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,