diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 0553b82306..1557de5865 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -115,7 +115,6 @@ const SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU - SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index e15ba78945..774a4d5e42 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -377,11 +377,6 @@ Simulate AltGr with Ctrl+Alt - - - - Right Modifier keys work with Hotkeys - @@ -797,13 +792,18 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman Start Keyman + + + + Start %1$s + @@ -860,7 +860,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman @@ -1026,7 +1026,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index fbed70b24d..d8cb3e30e7 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -228,9 +228,6 @@ type FActiveHKL: Integer; FTrayIcon: TIcon; // I4359 - FHotkeyWindow: HWND; - FHotkeys: TIntegerList; - FInputPane: TFrameworkInputPane; FIsInputPaneVisible: Boolean; @@ -295,12 +292,6 @@ type procedure UnregisterControllerWindows; // I4731 function IsSysTrayWindow(AHandle: THandle): Boolean; procedure GetTrayIconHandle; // I4731 - - procedure RegisterHotkeys; - procedure UnregisterHotkeys; - procedure HotkeyWndProc(var Message: TMessage); - - procedure DoLanguageHotkey(Index: Integer); protected procedure DoInterfaceHotkey(Target: Integer); @@ -550,8 +541,6 @@ begin FreeAndNil(FInputPane); - UnregisterHotkeys; - with TRegistryErrorControlled.Create do // I2890 try if OpenKey(SRegKey_KeymanOSK_CU, True) then @@ -833,7 +822,6 @@ begin end; FOSKManuallyClosedThisSession := False; FRunningProduct.FLangSwitchConfiguration.Refresh; - RegisterHotkeys; end; KMC_NOTIFYWELCOME: // I1248 - Redesigned welcome begin @@ -869,23 +857,6 @@ begin end; end; -procedure TfrmKeyman7Main.DoLanguageHotkey(Index: Integer); -var - FKeyboard: TLangSwitchKeyboard; -begin - if (Index >= 0) and (Index < kmcom.Languages.Count) then - begin - FKeyboard := FLangSwitchManager.FindKeyboard(kmcom.Languages[Index].HKL, kmcom.Languages[Index].ProfileGUID); - if not Assigned(FKeyboard) then Exit; - - // Handle toggle hotkey - if (FKeyboard = FLangSwitchManager.ActiveKeyboard) and (kmcom.Options['koKeyboardHotkeysAreToggle'].Value) then - FKeyboard := FLangSwitchManager.Languages[0].Keyboards[0]; - - ActivateKeyboard(FKeyboard); - end; -end; - procedure TfrmKeyman7Main.DoInterfaceHotkey(Target: Integer); begin if not Assigned(FRunningProduct) then @@ -1356,7 +1327,6 @@ begin StartKeymanX64; - RegisterHotkeys; end; procedure TfrmKeyman7Main.RequestCurrentActiveKeyboard(Command: WORD); // I3961 @@ -2023,18 +1993,6 @@ begin end; end; -procedure TfrmKeyman7Main.HotkeyWndProc(var Message: TMessage); -begin - if Message.Msg = WM_HOTKEY then - begin - KL.Log('Hotkey %d', [Message.WParam]); - if Message.WParam > kh__High - then DoLanguageHotkey(Message.WParam - kh__High - 1) - else DoInterfaceHotkey(Message.WParam); - end; - Message.Result := DefWindowProc(FHotkeyWindow, Message.Msg, Message.WParam, Message.LParam); -end; - function KeymanHotkeyModifiersToWindowsHotkeyModifiers(v: KeymanHotkeyModifiers): Integer; begin Result := 0; @@ -2043,117 +2001,6 @@ begin if (v and HK_ALT) = HK_ALT then Result := Result or MOD_ALT; end; -procedure TfrmKeyman7Main.RegisterHotkeys; -var - hk: IKeymanHotkey; - i: Integer; - language: IKeymanLanguage; - id: Integer; - RegistryErrorControlled: TRegistryErrorControlled;// I2890 - UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey -begin - RegistryErrorControlled := TRegistryErrorControlled.Create; - try - if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and - RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then - begin - UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); - end - else - begin - UseRegisterHotKey := False; - end; - finally - RegistryErrorControlled.Free; - end; - - if not UseRegisterHotKey then Exit; - - TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []); - - if FHotkeyWindow = 0 then - FHotkeyWindow := AllocateHWnd(HotkeyWndProc); - - if not Assigned(FHotkeys) then - FHotkeys := TIntegerList.Create; - - UnregisterHotkeys; - - for i := 0 to kmcom.Hotkeys.Count - 1 do - begin - hk := kmcom.Hotkeys[i]; - if not hk.IsEmpty and (hk.VirtualKey <> 0) then - begin - // Note, if hk.VirtualKey is 0, this indicates a modifier-only hotkey such - // as Alt+Left Shift. These are handled in keyman32 k32_lowlevelkeyboardhook - // because RegisterHotkey cannot handle modifier-only hotkeys. - if RegisterHotkey(FHotkeyWindow, hk.Target, KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey) then - begin - TDebugLogClient.Instance.WriteMessage('Added hotkey %d -> %x %x', [hk.Target, - KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey]); - FHotkeys.Add(hk.Target) - end - else - TDebugLogClient.Instance.WriteLastError('RegisterHotkeys', 'RegisterHotkey', 'Failed to register hotkey '+IntToStr(hk.Target)); - end; - end; - - for i := 0 to kmcom.Languages.Count - 1 do - begin - language := kmcom.Languages[i]; - hk := language.Hotkey; - if Assigned(hk) and not hk.IsEmpty and (hk.VirtualKey <> 0) then - begin - id := kh__High + 1 + i; - if RegisterHotkey(FHotkeyWindow, id, KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey) then - begin - TDebugLogClient.Instance.WriteMessage('Added hotkey for language %s [%d] -> %x %x', [language.LocaleName, id, - KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey]); - FHotkeys.Add(id); - end - else - TDebugLogClient.Instance.WriteLastError('RegisterHotkeys', 'RegisterHotkey', 'Failed to register hotkey '+IntToStr(id)); - end; - end; -end; - -procedure TfrmKeyman7Main.UnregisterHotkeys; -var - i, hk: Integer; - RegistryErrorControlled: TRegistryErrorControlled;// I2890 - UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey -begin - RegistryErrorControlled := TRegistryErrorControlled.Create; - try - if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and - RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then - begin - UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); - end - else - begin - UseRegisterHotKey := False; - end; - finally - RegistryErrorControlled.Free; - end; - - if not UseRegisterHotKey then Exit; - - TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []); - - if not Assigned(FHotkeys) then - Exit; - - for i := 0 to FHotkeys.Count - 1 do - begin - hk := FHotkeys[i]; - if not UnregisterHotKey(FHotkeyWindow, hk) then - TDebugLogClient.Instance.WriteLastError('UnregisterHotkeys', 'UnregisterHotkey', 'Failed to unregister hotkey '+IntToStr(hk)); - end; - FHotkeys.Clear; -end; - { TLangSwitchRefreshWatcher } constructor TLangSwitchRefreshWatcher.Create(AOwnerHandle: THandle); diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 2bdfae62e3..8e3fe92a3c 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -129,27 +129,6 @@ BOOL IsTouchPanelVisible() { return touchPanelVisible; } -/* - Cache UseRightModifierHotKey debug flag for this session - when using right modifier for Hotkeys use the Win32 API - ResisterHotkey functionality -*/ -BOOL UseRegisterHotkey() { - static BOOL flag_UseRightModifierHotKey = FALSE; - static BOOL loaded = FALSE; - - if (!loaded) { - RegistryReadOnly reg(HKEY_CURRENT_USER); - if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) { - if (reg.ValueExists(REGSZ_UseRightModifierHotKey)) { - flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_UseRightModifierHotKey); - } - } - loaded = TRUE; // Set loaded to TRUE whether or not the key exists - } - return flag_UseRightModifierHotKey; -} - LRESULT _kmnLowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, @@ -169,36 +148,18 @@ LRESULT _kmnLowLevelKeyboardProc( SendDebugMessageFormat("wparam: %x lparam: %x [vk:%s scan:%x flags:%x extra:%x]", wParam, lParam, Debug_VirtualKey((WORD) hs->vkCode), hs->scanCode, hs->flags, hs->dwExtraInfo); // I4674 - if (GetKeyState(VK_LCONTROL) < 0) { - FHotkeyShiftState |= HK_CTRL; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); - } + // #5190: Don't cache modifier state because sometimes we won't receive + // modifier change events (e.g. on lock screen) + FHotkeyShiftState = 0; + if (GetKeyState(VK_LCONTROL) < 0) FHotkeyShiftState |= HK_CTRL; + if (GetKeyState(VK_RCONTROL) < 0) FHotkeyShiftState |= HK_RCTRL_INVALID; + if (GetKeyState(VK_LMENU) < 0) FHotkeyShiftState |= HK_ALT; + if (GetKeyState(VK_RMENU) < 0) FHotkeyShiftState |= HK_RALT_INVALID; + if (GetKeyState(VK_LSHIFT) < 0) FHotkeyShiftState |= HK_SHIFT; + if (GetKeyState(VK_RSHIFT) < 0) FHotkeyShiftState |= HK_RSHIFT_INVALID; + //TODO: #8064. Can remove debug message once issue #8064 is resolved + SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); - if (GetKeyState(VK_RCONTROL) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_CTRL : HK_RCTRL_INVALID; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); - } - - if (GetKeyState(VK_LMENU) < 0) { - FHotkeyShiftState |= HK_ALT; - } - - if (GetKeyState(VK_RMENU) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_ALT : HK_RALT_INVALID; - } - - if (GetKeyState(VK_LSHIFT) < 0) { - FHotkeyShiftState |= HK_SHIFT; - } - if (GetKeyState(VK_RSHIFT) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_SHIFT : HK_RSHIFT_INVALID; - } - - //if (GetKeyState(VK_SHIFT) < 0) { - // FHotkeyShiftState |= (!UseRegisterHotkey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; - //} // #7337 Post the modifier state ensuring the serialized queue is in sync // Note that the modifier key may be posted again with WM_KEYMAN_KEY_EVENT, @@ -279,9 +240,7 @@ LRESULT _kmnLowLevelKeyboardProc( } BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { - if (UseRegisterHotkey()){ - return FALSE; - } + Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if (!hotkeys) { SendDebugMessageFormat("Failed to get Instance"); diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index 2df38b5c82..ce1b8af33a 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -121,13 +121,12 @@ type GroupName: string; end; -const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 +const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 // Global options (opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koSwitchLanguageForAllApplications; RegistryName: SRegValue_SwitchLanguageForAllApplications; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I2277 // I4393 (opt: koAltGrCtrlAlt; RegistryName: SRegValue_AltGrCtrlAlt; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), - (opt: koRightModifierHK; RegistryName: SRegValue_UseRightModifierHotKey; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koShowHints; RegistryName: SRegValue_EnableHints; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), (opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'), diff --git a/windows/src/global/delphi/general/KeymanOptionNames.pas b/windows/src/global/delphi/general/KeymanOptionNames.pas index 73356d19cb..27aef82ab5 100644 --- a/windows/src/global/delphi/general/KeymanOptionNames.pas +++ b/windows/src/global/delphi/general/KeymanOptionNames.pas @@ -5,10 +5,7 @@ interface type TUtilKeymanOption = ( // General options - koKeyboardHotkeysAreToggle, - koAltGrCtrlAlt, - koRightModifierHK, - koReleaseShiftKeysAfterKeyPress, + koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress, koShowHints, // I1256 // Startup options koTestKeymanFunctioning,