Bug 1226148 - reduce flickering and closing when using the OSK tab key, r=masayuki, a=sylvestre
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 18 Jan 2016 12:14:43 +0000
changeset 316727 4b9d05addfe595c87c1b0ae98113467dca16eeb2
parent 316726 e66b2afa9628ec9a00474f0dfcfe74888d1823e2
child 316728 4cec5d9097c46ead7c106732c9725b3911ad23a4
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, sylvestre
bugs1226148
milestone46.0a2
Bug 1226148 - reduce flickering and closing when using the OSK tab key, r=masayuki, a=sylvestre
widget/windows/WinIMEHandler.cpp
widget/windows/WinIMEHandler.h
widget/windows/nsWindowDefs.h
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -147,16 +147,23 @@ IMEHandler::ProcessRawKeyMessage(const M
 }
 
 // static
 bool
 IMEHandler::ProcessMessage(nsWindow* aWindow, UINT aMessage,
                            WPARAM& aWParam, LPARAM& aLParam,
                            MSGResult& aResult)
 {
+  if (aMessage == MOZ_WM_DISMISS_ONSCREEN_KEYBOARD) {
+    if (!sFocusedWindow) {
+      DismissOnScreenKeyboard();
+    }
+    return true;
+  }
+
 #ifdef NS_ENABLE_TSF
   if (IsTSFAvailable()) {
     TSFTextStore::ProcessMessage(aWindow, aMessage, aWParam, aLParam, aResult);
     if (aResult.mConsumed) {
       return true;
     }
     // If we don't support IMM in TSF mode, we don't use IMMHandler.
     if (!sIsIMMEnabled) {
@@ -248,17 +255,17 @@ IMEHandler::NotifyIME(nsWindow* aWindow,
         nsresult rv =
           TSFTextStore::OnFocusChange(true, aWindow,
                                       aWindow->GetInputContext());
         IMEHandler::MaybeShowOnScreenKeyboard();
         return rv;
       }
       case NOTIFY_IME_OF_BLUR:
         sFocusedWindow = nullptr;
-        IMEHandler::MaybeDismissOnScreenKeyboard();
+        IMEHandler::MaybeDismissOnScreenKeyboard(aWindow);
         IMMHandler::OnFocusChange(false, aWindow);
         return TSFTextStore::OnFocusChange(false, aWindow,
                                            aWindow->GetInputContext());
       case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
         // If IMM IME is active, we should send a mouse button event via IMM.
         if (IsIMMActive()) {
           return IMMHandler::OnMouseButtonEvent(aWindow, aIMENotification);
         }
@@ -297,21 +304,23 @@ IMEHandler::NotifyIME(nsWindow* aWindow,
       IMMHandler::OnUpdateComposition(aWindow);
       return NS_OK;
     case NOTIFY_IME_OF_SELECTION_CHANGE:
       IMMHandler::OnSelectionChange(aWindow, aIMENotification, true);
       return NS_OK;
     case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
       return IMMHandler::OnMouseButtonEvent(aWindow, aIMENotification);
     case NOTIFY_IME_OF_FOCUS:
+      sFocusedWindow = aWindow;
       IMMHandler::OnFocusChange(true, aWindow);
       IMEHandler::MaybeShowOnScreenKeyboard();
       return NS_OK;
     case NOTIFY_IME_OF_BLUR:
-      IMEHandler::MaybeDismissOnScreenKeyboard();
+      sFocusedWindow = nullptr;
+      IMEHandler::MaybeDismissOnScreenKeyboard(aWindow);
       IMMHandler::OnFocusChange(false, aWindow);
 #ifdef NS_ENABLE_TSF
       // If a plugin gets focus while TSF has focus, we need to notify TSF of
       // the blur.
       if (TSFTextStore::ThinksHavingFocus()) {
         return TSFTextStore::OnFocusChange(false, aWindow,
                                            aWindow->GetInputContext());
       }
@@ -592,24 +601,25 @@ IMEHandler::MaybeShowOnScreenKeyboard()
     return;
   }
 
   IMEHandler::ShowOnScreenKeyboard();
 }
 
 // static
 void
-IMEHandler::MaybeDismissOnScreenKeyboard()
+IMEHandler::MaybeDismissOnScreenKeyboard(nsWindow* aWindow)
 {
   if (sPluginHasFocus ||
       !IsWin8OrLater()) {
     return;
   }
 
-  IMEHandler::DismissOnScreenKeyboard();
+  ::PostMessage(aWindow->GetWindowHandle(), MOZ_WM_DISMISS_ONSCREEN_KEYBOARD,
+                0, 0);
 }
 
 // static
 bool
 IMEHandler::WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
                                              const std::wstring& aNeedle)
 {
   std::wstring lowerCaseHaystack(aHaystack);
--- a/widget/windows/WinIMEHandler.h
+++ b/widget/windows/WinIMEHandler.h
@@ -136,17 +136,17 @@ private:
   // 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;
 
   static bool IsTSFAvailable() { return (sIsInTSFMode && !sPluginHasFocus); }
   static bool IsIMMActive();
 
   static void MaybeShowOnScreenKeyboard();
-  static void MaybeDismissOnScreenKeyboard();
+  static void MaybeDismissOnScreenKeyboard(nsWindow* aWindow);
   static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
                                                const std::wstring& aNeedle);
   static bool IsKeyboardPresentOnSlate();
   static bool IsInTabletMode();
   static bool AutoInvokeOnScreenKeyboardInDesktopMode();
 
   /**
    * Show the Windows on-screen keyboard. Only allowed for
--- a/widget/windows/nsWindowDefs.h
+++ b/widget/windows/nsWindowDefs.h
@@ -36,16 +36,18 @@
 // If a popup window is being activated, we try to reactivate the previous
 // window with this message.
 #define MOZ_WM_REACTIVATE                 (WM_APP+0x0314)
 // If TSFTextStore needs to notify TSF/TIP of layout change later, this
 // message is posted.
 #define MOZ_WM_NOTIY_TSF_OF_LAYOUT_CHANGE (WM_APP+0x0315)
 // Internal message used in correcting backwards clock skew
 #define MOZ_WM_SKEWFIX                    (WM_APP+0x0316)
+// Internal message used for hiding the on-screen keyboard
+#define MOZ_WM_DISMISS_ONSCREEN_KEYBOARD  (WM_APP+0x0317)
 
 // Internal message for ensuring the file picker is visible on multi monitor
 // systems, and when the screen resolution changes.
 #define MOZ_WM_ENSUREVISIBLE              (WM_APP+0x374F)
 
 #ifndef SM_CXPADDEDBORDER
 #define SM_CXPADDEDBORDER                 92
 #endif