Bug 1221947 - part 2: add TOUCH cause to IME Handling and use it to avoid checking for a keyboard, r=masayuki a=ritu
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 12 Nov 2015 16:36:19 +0000
changeset 305537 54f8c04cc8d7c9b951b38c94ca787de688856ea9
parent 305536 8e13fe7ab3da6658e6dcb184950b412367fbaeba
child 305538 36ad43168b8da376ddbf1e7a682feeac95a7d274
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, ritu
bugs1221947
milestone44.0a2
Bug 1221947 - part 2: add TOUCH cause to IME Handling and use it to avoid checking for a keyboard, r=masayuki a=ritu
dom/base/nsFocusManager.cpp
widget/IMEData.h
widget/windows/WinIMEHandler.cpp
widget/windows/WinIMEHandler.h
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -347,17 +347,19 @@ nsFocusManager::GetRedirectedFocus(nsICo
 
   return nullptr;
 }
 
 // static
 InputContextAction::Cause
 nsFocusManager::GetFocusMoveActionCause(uint32_t aFlags)
 {
-  if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
+  if (aFlags & nsIFocusManager::FLAG_BYTOUCH) {
+    return InputContextAction::CAUSE_TOUCH;
+  } else if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
     return InputContextAction::CAUSE_MOUSE;
   } else if (aFlags & nsIFocusManager::FLAG_BYKEY) {
     return InputContextAction::CAUSE_KEY;
   }
   return InputContextAction::CAUSE_UNKNOWN;
 }
 
 NS_IMETHODIMP
--- a/widget/IMEData.h
+++ b/widget/IMEData.h
@@ -303,17 +303,19 @@ struct InputContextAction final
     // changed by content script.
     CAUSE_UNKNOWN,
     // The cause is unknown but originated from chrome. Focus might have been
     // changed by chrome script.
     CAUSE_UNKNOWN_CHROME,
     // The cause is user's keyboard operation.
     CAUSE_KEY,
     // The cause is user's mouse operation.
-    CAUSE_MOUSE
+    CAUSE_MOUSE,
+    // The cause is user's touch operation (implies mouse)
+    CAUSE_TOUCH
   };
   Cause mCause;
 
   /**
    * mFocusChange indicates what happened for focus.
    */
   enum FocusChange
   {
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -34,16 +34,19 @@ const char* kOskDebugReason = "ui.osk.de
 namespace mozilla {
 namespace widget {
 
 /******************************************************************************
  * IMEHandler
  ******************************************************************************/
 
 bool IMEHandler::sPluginHasFocus = false;
+InputContextAction::Cause IMEHandler::sLastContextActionCause =
+  InputContextAction::CAUSE_UNKNOWN;
+
 #ifdef NS_ENABLE_TSF
 bool IMEHandler::sIsInTSFMode = false;
 bool IMEHandler::sIsIMMEnabled = true;
 bool IMEHandler::sShowingOnScreenKeyboard = false;
 decltype(SetInputScopes)* IMEHandler::sSetInputScopes = nullptr;
 #endif // #ifdef NS_ENABLE_TSF
 
 static POWER_PLATFORM_ROLE sPowerPlatformRole = PlatformRoleUnspecified;
@@ -344,16 +347,17 @@ IMEHandler::OnDestroyWindow(nsWindow* aW
 }
 
 // static
 void
 IMEHandler::SetInputContext(nsWindow* aWindow,
                             InputContext& aInputContext,
                             const InputContextAction& aAction)
 {
+  sLastContextActionCause = aAction.mCause;
   // FYI: If there is no composition, this call will do nothing.
   NotifyIME(aWindow, IMENotification(REQUEST_TO_COMMIT_COMPOSITION));
 
   const InputContext& oldInputContext = aWindow->GetInputContext();
 
   // Assume that SetInputContext() is called only when aWindow has focus.
   sPluginHasFocus = (aInputContext.mIMEState.mEnabled == IMEState::PLUGIN);
 
@@ -687,16 +691,24 @@ IMEHandler::IsKeyboardPresentOnSlate()
   }
 
   // Likewise, if the tablet/mobile isn't in "slate" mode, we should bail:
   if (::GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0) {
     Preferences::SetString(kOskDebugReason, L"IKPOS: ConvertibleSlateMode is non-zero");
     return true;
   }
 
+  // Before we check for a keyboard, we should check if the last input was touch,
+  // in which case we ignore whether or not a keyboard is present:
+  if (sLastContextActionCause == InputContextAction::CAUSE_TOUCH) {
+    Preferences::SetString(kOskDebugReason,
+      L"IKPOS: Used touch to focus control, ignoring keyboard presence");
+    return false;
+  }
+
   const GUID KEYBOARD_CLASS_GUID =
     { 0x4D36E96B, 0xE325,  0x11CE,
       { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
 
   // Query for all the keyboard devices.
   HDEVINFO device_info =
     ::SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, nullptr,
                           nullptr, DIGCF_PRESENT);
--- a/widget/windows/WinIMEHandler.h
+++ b/widget/windows/WinIMEHandler.h
@@ -108,16 +108,18 @@ public:
    * Returns true when current keyboard layout has IME.  Otherwise, false.
    */
   static bool CurrentKeyboardLayoutHasIME();
 #endif // #ifdef DEBUG
 
 private:
   static bool sPluginHasFocus;
 
+  static InputContextAction::Cause sLastContextActionCause;
+
 #ifdef NS_ENABLE_TSF
   static decltype(SetInputScopes)* sSetInputScopes;
   static void SetInputScopeForIMM32(nsWindow* aWindow,
                                     const nsAString& aHTMLInputType);
   static bool sIsInTSFMode;
   // If sIMMEnabled is false, any IME messages are not handled in TSF mode.
   // Additionally, IME context is always disassociated from focused window.
   static bool sIsIMMEnabled;