Bug 1226145 - actually check whether the on-screen keyboard is up rather than relying on internal state, r?masayuki draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 16 Dec 2015 12:48:12 +0000
changeset 315785 aed92d3b3415c9a1c5b652cb78877583c21bb0ff
parent 315778 a1393f2f306ef87ddaf36b8a91d8ac5aa1370134
child 512084 09cb22a1e74e90cd60216d58429602f7420345b7
push id8461
push usergijskruitbosch@gmail.com
push dateWed, 16 Dec 2015 16:12:35 +0000
reviewersmasayuki
bugs1226145
milestone46.0a1
Bug 1226145 - actually check whether the on-screen keyboard is up rather than relying on internal state, r?masayuki
widget/windows/WinIMEHandler.cpp
widget/windows/WinIMEHandler.h
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -41,17 +41,16 @@ namespace widget {
 nsWindow* IMEHandler::sFocusedWindow = nullptr;
 InputContextAction::Cause IMEHandler::sLastContextActionCause =
   InputContextAction::CAUSE_UNKNOWN;
 bool IMEHandler::sPluginHasFocus = false;
 
 #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;
 static bool sDeterminedPowerPlatformRole = false;
 
 // static
 void
@@ -562,17 +561,17 @@ IMEHandler::SetInputScopeForIMM32(nsWind
 
 // static
 void
 IMEHandler::MaybeShowOnScreenKeyboard()
 {
   if (sPluginHasFocus ||
       !IsWin8OrLater() ||
       !Preferences::GetBool(kOskEnabled, true) ||
-      sShowingOnScreenKeyboard ||
+      GetOnScreenKeyboardWindow() ||
       IMEHandler::IsKeyboardPresentOnSlate()) {
     return;
   }
 
   // On Windows 10 we require tablet mode, unless the user has set the relevant
   // Windows setting to enable the on-screen keyboard in desktop mode.
   // We might be disabled specifically on Win8(.1), so we check that afterwards.
   if (IsWin10OrLater()) {
@@ -587,18 +586,17 @@ IMEHandler::MaybeShowOnScreenKeyboard()
   IMEHandler::ShowOnScreenKeyboard();
 }
 
 // static
 void
 IMEHandler::MaybeDismissOnScreenKeyboard()
 {
   if (sPluginHasFocus ||
-      !IsWin8OrLater() ||
-      !sShowingOnScreenKeyboard) {
+      !IsWin8OrLater()) {
     return;
   }
 
   IMEHandler::DismissOnScreenKeyboard();
 }
 
 // static
 bool
@@ -910,29 +908,36 @@ IMEHandler::ShowOnScreenKeyboard()
   const char16_t *cachedPathPtr;
   cachedPath.GetData(&cachedPathPtr);
   ShellExecuteW(nullptr,
                 L"",
                 char16ptr_t(cachedPathPtr),
                 nullptr,
                 nullptr,
                 SW_SHOW);
-  sShowingOnScreenKeyboard = true;
 }
 
 // Based on DismissVirtualKeyboard() in Chromium's base/win/win_util.cc.
 // static
 void
 IMEHandler::DismissOnScreenKeyboard()
 {
-  sShowingOnScreenKeyboard = false;
-
-  // Dismiss the virtual keyboard by generating the ESC keystroke
-  // programmatically.
-  const wchar_t kOSKClassName[] = L"IPTip_Main_Window";
-  HWND osk = ::FindWindowW(kOSKClassName, nullptr);
-  if (::IsWindow(osk) && ::IsWindowEnabled(osk)) {
+  // Dismiss the virtual keyboard if it's open
+  HWND osk = GetOnScreenKeyboardWindow();
+  if (osk) {
     ::PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0);
   }
 }
 
+// static
+HWND
+IMEHandler::GetOnScreenKeyboardWindow()
+{
+  const wchar_t kOSKClassName[] = L"IPTip_Main_Window";
+  HWND osk = ::FindWindowW(kOSKClassName, nullptr);
+  if (::IsWindow(osk) && ::IsWindowEnabled(osk)) {
+    return osk;
+  }
+  return nullptr;
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/windows/WinIMEHandler.h
+++ b/widget/windows/WinIMEHandler.h
@@ -119,17 +119,16 @@ private:
 #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;
-  static bool sShowingOnScreenKeyboard;
 
   static bool IsTSFAvailable() { return (sIsInTSFMode && !sPluginHasFocus); }
   static bool IsIMMActive();
 
   static void MaybeShowOnScreenKeyboard();
   static void MaybeDismissOnScreenKeyboard();
   static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
                                                const std::wstring& aNeedle);
@@ -143,15 +142,21 @@ private:
    */
   static void ShowOnScreenKeyboard();
 
   /**
    * Dismiss the Windows on-screen keyboard. Only allowed for
    * Windows 8 and higher.
    */
   static void DismissOnScreenKeyboard();
+
+  /**
+   * Get the HWND for the on-screen keyboard, if it's up. Only
+   * allowed for Windows 8 and higher.
+   */
+  static HWND GetOnScreenKeyboardWindow();
 #endif // #ifdef NS_ENABLE_TSF
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif // #ifndef WinIMEHandler_h_