mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1239744 - no longer automatically show an on-screen keyboard for programmatic focus changes, tidy up osk logic in IMEHandler, r=masayuki
--HG-- extra : rebase_source : 013c2759f4faca65ed3de79ca1d7f0b97e6375cb
This commit is contained in:
parent
8532605cf4
commit
b499a37faf
@ -393,6 +393,18 @@ struct InputContextAction final
|
||||
(mCause == CAUSE_MOUSE || mCause == CAUSE_TOUCH));
|
||||
}
|
||||
|
||||
static bool IsUserAction(Cause aCause)
|
||||
{
|
||||
switch (aCause) {
|
||||
case CAUSE_KEY:
|
||||
case CAUSE_MOUSE:
|
||||
case CAUSE_TOUCH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
InputContextAction()
|
||||
: mCause(CAUSE_UNKNOWN)
|
||||
, mFocusChange(FOCUS_NOT_CHANGED)
|
||||
|
@ -606,7 +606,7 @@ IMEHandler::MaybeShowOnScreenKeyboard()
|
||||
!IsWin8OrLater() ||
|
||||
!Preferences::GetBool(kOskEnabled, true) ||
|
||||
GetOnScreenKeyboardWindow() ||
|
||||
IMEHandler::IsKeyboardPresentOnSlate()) {
|
||||
!IMEHandler::NeedOnScreenKeyboard()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -653,24 +653,31 @@ IMEHandler::WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
|
||||
lowerCaseNeedle.c_str()) == lowerCaseHaystack.c_str();
|
||||
}
|
||||
|
||||
// Returns true if a physical keyboard is detected on Windows 8 and up.
|
||||
// Uses the Setup APIs to enumerate the attached keyboards and returns true
|
||||
// if the keyboard count is 1 or more. While this will work in most cases
|
||||
// it won't work if there are devices which expose keyboard interfaces which
|
||||
// are attached to the machine.
|
||||
// Based on IsKeyboardPresentOnSlate() in Chromium's base/win/win_util.cc.
|
||||
// Returns false if a physical keyboard is detected on Windows 8 and up,
|
||||
// or there is some other reason why an onscreen keyboard is not necessary.
|
||||
// Returns true if no keyboard is found and this device looks like it needs
|
||||
// an on-screen keyboard for text input.
|
||||
// static
|
||||
bool
|
||||
IMEHandler::IsKeyboardPresentOnSlate()
|
||||
IMEHandler::NeedOnScreenKeyboard()
|
||||
{
|
||||
// This function is only supported for Windows 8 and up.
|
||||
if (!IsWin8OrLater()) {
|
||||
Preferences::SetString(kOskDebugReason, L"IKPOS: Requires Win8+.");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Preferences::GetBool(kOskDetectPhysicalKeyboard, true)) {
|
||||
Preferences::SetString(kOskDebugReason, L"IKPOS: Detection disabled.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the last focus cause was not user-initiated (ie a result of code
|
||||
// setting focus to an element) then don't auto-show a keyboard. This
|
||||
// avoids cases where the keyboard would pop up "just" because e.g. a
|
||||
// web page chooses to focus a search field on the page, even when that
|
||||
// really isn't what the user is trying to do at that moment.
|
||||
if (!InputContextAction::IsUserAction(sLastContextActionCause)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -679,13 +686,13 @@ IMEHandler::IsKeyboardPresentOnSlate()
|
||||
!= NID_INTEGRATED_TOUCH) {
|
||||
Preferences::SetString(kOskDebugReason,
|
||||
L"IKPOS: Touch screen not found.");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the device is docked, the user is treating the device as a PC.
|
||||
if (::GetSystemMetrics(SM_SYSTEMDOCKED) != 0) {
|
||||
Preferences::SetString(kOskDebugReason, L"IKPOS: System docked.");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// To determine whether a keyboard is present on the device, we do the
|
||||
@ -697,11 +704,15 @@ IMEHandler::IsKeyboardPresentOnSlate()
|
||||
|
||||
// 2. If the device supports auto rotation, then we get its platform role
|
||||
// and check the system metric SM_CONVERTIBLESLATEMODE to see if it is
|
||||
// being used in slate mode. If yes then we return false here to ensure
|
||||
// that the OSK is displayed.
|
||||
// being used in slate mode. If not then we return false here to ensure
|
||||
// that the OSK is not displayed.
|
||||
|
||||
// 3. If step 1 and 2 fail then we check attached keyboards and return true
|
||||
// if we find ACPI\*, HID\VID* or bluetooth keyboards.
|
||||
// 3. If step 1 and 2 both confirm this *could* be a device with no usable
|
||||
// keyboard, we check whether the last input was touch-based. If so,
|
||||
// we return true immediately to get an on-screen keyboard.
|
||||
|
||||
// 4. If this was a mouse or (on-screen) keyboard event, we check if
|
||||
// this device has keyboards attached to it.
|
||||
|
||||
typedef BOOL (WINAPI* GetAutoRotationState)(PAR_STATE state);
|
||||
GetAutoRotationState get_rotation_state =
|
||||
@ -717,11 +728,11 @@ IMEHandler::IsKeyboardPresentOnSlate()
|
||||
if (auto_rotation_state & AR_NOSENSOR) {
|
||||
Preferences::SetString(kOskDebugReason,
|
||||
L"IKPOS: Rotation sensor not found.");
|
||||
return true;
|
||||
return false;
|
||||
} else if (auto_rotation_state & AR_NOT_SUPPORTED) {
|
||||
Preferences::SetString(kOskDebugReason,
|
||||
L"IKPOS: Auto-rotation not supported.");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,13 +758,13 @@ IMEHandler::IsKeyboardPresentOnSlate()
|
||||
if (sPowerPlatformRole != PlatformRoleMobile &&
|
||||
sPowerPlatformRole != PlatformRoleSlate) {
|
||||
Preferences::SetString(kOskDebugReason, L"IKPOS: PlatformRole is neither Mobile nor Slate.");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before we check for a keyboard, we should check if the last input was touch,
|
||||
@ -761,9 +772,20 @@ IMEHandler::IsKeyboardPresentOnSlate()
|
||||
if (sLastContextActionCause == InputContextAction::CAUSE_TOUCH) {
|
||||
Preferences::SetString(kOskDebugReason,
|
||||
L"IKPOS: Used touch to focus control, ignoring keyboard presence");
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return !IMEHandler::IsKeyboardPresentOnSlate();
|
||||
}
|
||||
|
||||
// Uses the Setup APIs to enumerate the attached keyboards and returns true
|
||||
// if the keyboard count is 1 or more. While this will work in most cases
|
||||
// it won't work if there are devices which expose keyboard interfaces which
|
||||
// are attached to the machine.
|
||||
// Based on IsKeyboardPresentOnSlate() in Chromium's base/win/win_util.cc.
|
||||
// static
|
||||
bool
|
||||
IMEHandler::IsKeyboardPresentOnSlate()
|
||||
{
|
||||
const GUID KEYBOARD_CLASS_GUID =
|
||||
{ 0x4D36E96B, 0xE325, 0x11CE,
|
||||
{ 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
|
||||
|
@ -145,6 +145,7 @@ private:
|
||||
static void MaybeDismissOnScreenKeyboard(nsWindow* aWindow);
|
||||
static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack,
|
||||
const std::wstring& aNeedle);
|
||||
static bool NeedOnScreenKeyboard();
|
||||
static bool IsKeyboardPresentOnSlate();
|
||||
static bool IsInTabletMode();
|
||||
static bool AutoInvokeOnScreenKeyboardInDesktopMode();
|
||||
|
Loading…
Reference in New Issue
Block a user