Bug 1226145 - actually check whether the on-screen keyboard is up rather than relying on internal state, r?masayuki
--- 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_