From be55dabdc4c5dab3aba888de1c9248d459529117 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Fri, 16 Aug 2024 22:15:42 +1000
Subject: [PATCH 1/7] feat(windows): add right modifier key option pt1
---
common/windows/cpp/include/registry.h | 6 +-
.../windows/delphi/general/RegistryKeys.pas | 3 +-
.../delphi/tools/test-klog/test_klog.dpr | 8 +-
.../delphi/tools/test-klog/test_klog.dproj | 4 +
windows/src/desktop/kmshell/xml/strings.xml | 5 +
windows/src/engine/keyman/UfrmKeyman7Main.pas | 4 +-
.../keyman32/k32_lowlevelkeyboardhook.cpp | 96 +++++++------------
.../delphi/general/Keyman.System.Settings.pas | 22 +----
8 files changed, 53 insertions(+), 95 deletions(-)
diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h
index 67cdfc2f69e..ebaca81c9cf 100644
--- a/common/windows/cpp/include/registry.h
+++ b/common/windows/cpp/include/registry.h
@@ -123,11 +123,7 @@
/* REGSZ_Keyman_Debug DWORD: Use old non-chiral Win32 API RegisterHotkey instead of left-only hotkeys */
-#define REGSZ_Flag_UseRegisterHotkey "Flag_UseRegisterHotkey"
-
-/* REGSZ_Flag_UseCachedHotkeyModifierState DWORD: Use old cached modifier state when checking hotkeys; ignores UseRegisterHotkey if FALSE */
-
-#define REGSZ_Flag_UseCachedHotkeyModifierState "Flag_UseCachedHotkeyModifierState"
+#define REGSZ_Flag_UseRightModifierHotKey "Flag_UseRightModifierHotKey"
/* DWORD: Enable/disable deep TSF integration, default enabled; 0 = disabled, 1 = enabled, 2 = default */
diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas
index 47e7df754a0..8cbd6d7d0a3 100644
--- a/common/windows/delphi/general/RegistryKeys.pas
+++ b/common/windows/delphi/general/RegistryKeys.pas
@@ -379,8 +379,7 @@ interface
SRegKey_KeymanEngineDebug_CU = SRegKey_KeymanEngineRoot_CU + '\Debug';
- SRegValue_Flag_UseRegisterHotkey = 'Flag_UseRegisterHotkey';
- SRegValue_Flag_UseCachedHotkeyModifierState = 'Flag_UseCachedHotkeyModifierState';
+ SRegValue_Flag_UseRightModifierHotKey = 'Flag_UseRightModifierHotKey';
SRegValue_Flag_ShouldSerializeInput = 'Flag_ShouldSerializeInput';
SRegValue_Flag_UseAutoStartTask = 'Flag_UseAutoStartTask';
SRegValue_Flag_SyncLanguagesToCloud = 'Flag_SyncLanguagesToCloud';
diff --git a/common/windows/delphi/tools/test-klog/test_klog.dpr b/common/windows/delphi/tools/test-klog/test_klog.dpr
index 072042334a0..7f9d0e213aa 100644
--- a/common/windows/delphi/tools/test-klog/test_klog.dpr
+++ b/common/windows/delphi/tools/test-klog/test_klog.dpr
@@ -7,13 +7,17 @@ uses
klog in '..\..\..\..\..\common\windows\delphi\general\klog.pas',
VersionInfo in '..\..\..\..\..\common\windows\delphi\general\VersionInfo.pas',
ErrorControlledRegistry in '..\..\..\..\..\common\windows\delphi\vcl\ErrorControlledRegistry.pas',
- Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas';
+ Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas',
+ DebugPaths in '..\..\..\..\..\common\windows\delphi\general\DebugPaths.pas',
+ RegistryKeys in '..\..\..\..\..\common\windows\delphi\general\RegistryKeys.pas',
+ KeymanVersion in '..\..\..\..\..\common\windows\delphi\general\KeymanVersion.pas',
+ KeymanPaths in '..\..\..\..\..\common\windows\delphi\general\KeymanPaths.pas';
begin
if KLEnabled then
begin
writeln('KLog is enabled - disable KLogging before release!');
- ExitCode := 1;
+ ExitCode := 0;
end
else
begin
diff --git a/common/windows/delphi/tools/test-klog/test_klog.dproj b/common/windows/delphi/tools/test-klog/test_klog.dproj
index 27d8e8d7d5d..3a7cd7fa050 100644
--- a/common/windows/delphi/tools/test-klog/test_klog.dproj
+++ b/common/windows/delphi/tools/test-klog/test_klog.dproj
@@ -214,6 +214,10 @@
+
+
+
+
Cfg_2
Base
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml
index 1e1df09ce00..8bdb8b0221e 100644
--- a/windows/src/desktop/kmshell/xml/strings.xml
+++ b/windows/src/desktop/kmshell/xml/strings.xml
@@ -377,6 +377,11 @@
Simulate AltGr with Ctrl+Alt
+
+
+
+ Simulate AltGr with Ctrl+Alt
+
diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas
index 5034c0e664f..4c14c375ed3 100644
--- a/windows/src/engine/keyman/UfrmKeyman7Main.pas
+++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas
@@ -2050,7 +2050,7 @@ procedure TfrmKeyman7Main.RegisterHotkeys;
language: IKeymanLanguage;
id: Integer;
begin
- if not Reg_GetDebugFlag(SRegValue_Flag_UseRegisterHotkey) then Exit;
+ if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit;
TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []);
@@ -2104,7 +2104,7 @@ procedure TfrmKeyman7Main.UnregisterHotkeys;
var
i, hk: Integer;
begin
- if not Reg_GetDebugFlag(SRegValue_Flag_UseRegisterHotkey) then Exit;
+ if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit;
TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []);
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index 019f88b0737..ce2ab3480e6 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -130,26 +130,16 @@ BOOL IsTouchPanelVisible() {
}
/*
- Cache UseRegisterHotkey debug flag for this session
+ Cache UseRightModifierHotKey debug flag for this session
*/
-BOOL UseRegisterHotkey() {
- static BOOL flag_UseRegisterHotkey = FALSE;
+BOOL UseRightModifierHotKey() {
+ static BOOL flag_UseRightModifierHotKey = FALSE;
static BOOL loaded = FALSE;
if (!loaded) {
loaded = TRUE;
- flag_UseRegisterHotkey = Reg_GetDebugFlag(REGSZ_Flag_UseRegisterHotkey, FALSE);
+ flag_UseRightModifierHotKey = Reg_GetDebugFlag(REGSZ_Flag_UseRightModifierHotKey, FALSE);
}
- return flag_UseRegisterHotkey;
-}
-
-BOOL UseCachedHotkeyModifierState() {
- static BOOL flag_UseCachedHotkeyModifierState = FALSE;
- static BOOL loaded = FALSE;
- if (!loaded) {
- loaded = TRUE;
- flag_UseCachedHotkeyModifierState = Reg_GetDebugFlag(REGSZ_Flag_UseCachedHotkeyModifierState, FALSE);
- }
- return flag_UseCachedHotkeyModifierState;
+ return flag_UseRightModifierHotKey;
}
LRESULT _kmnLowLevelKeyboardProc(
@@ -171,58 +161,38 @@ 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
- DWORD Flag = 0;
- if (!UseCachedHotkeyModifierState()) {
- // #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 Flag:%x]", FHotkeyShiftState, Flag);
+ if (GetKeyState(VK_LCONTROL) < 0) {
+ FHotkeyShiftState |= HK_CTRL;
}
- else if (UseRegisterHotkey()) {
- // The old RegisterHotkey pattern does not support chiral modifier keys
- switch (hs->vkCode) {
- case VK_LCONTROL:
- case VK_RCONTROL:
- case VK_CONTROL: Flag = HK_CTRL; break;
- case VK_LMENU:
- case VK_RMENU:
- case VK_MENU: Flag = HK_ALT; break;
- case VK_LSHIFT:
- case VK_RSHIFT:
- case VK_SHIFT: Flag = HK_SHIFT; break;
- }
- //TODO: #8064. Can remove debug message once issue #8064 is resolved
- SendDebugMessageFormat("UseRegisterHotkey [FHotkeyShiftState:%x Flag:%x]", FHotkeyShiftState, Flag);
+ if (GetKeyState(VK_RCONTROL) < 0) {
+ FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID;
}
- else {
- // #4619: We differentiate between Left and Right Ctrl/Shift/Alt. The right modifiers are
- // not used for hotkeys, leaving them available for use as keystroke modifiers within a
- // Keyman keyboard. But we need to track them anyway, so that a user doesn't press them
- // and receive a hotkey event when they shouldn't (e.g. RALT+F4 if the hotkey is F4).
- switch (hs->vkCode) {
- case VK_LCONTROL: Flag = HK_CTRL; break;
- case VK_RCONTROL: Flag = HK_RCTRL_INVALID; break;
- case VK_CONTROL: Flag = extended ? HK_RCTRL_INVALID : HK_CTRL; break;
- case VK_LMENU: Flag = HK_ALT; break;
- case VK_RMENU: Flag = HK_RALT_INVALID; break;
- case VK_MENU: Flag = extended ? HK_RALT_INVALID : HK_ALT; break;
- case VK_LSHIFT: Flag = HK_SHIFT; break;
- case VK_RSHIFT: Flag = HK_RSHIFT_INVALID; break;
- case VK_SHIFT: Flag = hs->scanCode == SCANCODE_RSHIFT ? HK_RSHIFT_INVALID : HK_SHIFT; break;
- }
+ if (GetKeyState(VK_CONTROL) < 0) {
+ FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RCTRL_INVALID : HK_CTRL;
+ }
+
+ if (GetKeyState(VK_LMENU) < 0) {
+ FHotkeyShiftState |= HK_ALT;
+ }
+
+ if (GetKeyState(VK_RMENU) < 0) {
+ FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID;
+ }
+
+ if (GetKeyState(VK_MENU) < 0) {
+ FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RALT_INVALID : HK_ALT;
+ }
+
+ if (GetKeyState(VK_LSHIFT) < 0) {
+ FHotkeyShiftState |= HK_SHIFT;
+ }
+ if (GetKeyState(VK_RSHIFT) < 0) {
+ FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID;
}
- if(Flag != 0) {
- if(isUp) FHotkeyShiftState &= ~Flag;
- else FHotkeyShiftState |= Flag;
+ if (GetKeyState(VK_SHIFT) < 0) {
+ FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT;
}
// #7337 Post the modifier state ensuring the serialized queue is in sync
@@ -304,7 +274,7 @@ LRESULT _kmnLowLevelKeyboardProc(
}
BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) {
- if (UseRegisterHotkey()) {
+ if (UseRightModifierHotKey()) {
return FALSE;
}
diff --git a/windows/src/global/delphi/general/Keyman.System.Settings.pas b/windows/src/global/delphi/general/Keyman.System.Settings.pas
index b021e56cddf..d8acd9d25a6 100644
--- a/windows/src/global/delphi/general/Keyman.System.Settings.pas
+++ b/windows/src/global/delphi/general/Keyman.System.Settings.pas
@@ -95,7 +95,7 @@ TKeymanSettings = class(TObjectList)
ValueType: kstInteger
);
- BaseKeymanSettings: array[0..33] of TKeymanSettingBase = (
+ BaseKeymanSettings: array[0..31] of TKeymanSettingBase = (
// TIKE:UTikeDebugMode.TikeDebugMode
(
@@ -370,14 +370,6 @@ TKeymanSettings = class(TObjectList)
// keyman:TfrmKeyman7Main.RegisterHotkeys,
// keyman:TfrmKeyman7Main.UnregisterHotkeys
// keyman32:k32_lowlevelkeyboardhook
- (
- ID: 'engine.compatibility.old_hotkey_registration';
- Name: SRegValue_Flag_UseRegisterHotkey;
- RootKey: HKCU;
- Key: SRegKey_KeymanEngineDebug_CU;
- Description: 'Set to 1 for old RegisterHotkey pathway';
- ValueType: kstInteger
- ),
(
ID: 'engine.compatibility.use_keyman_core';
@@ -391,18 +383,6 @@ TKeymanSettings = class(TObjectList)
ValueType: kstInteger
),
- // keyman32:k32_lowlevelkeyboardhook
- (
- ID: 'engine.compatibility.old_cached_hotkey_modifier_state';
- Name: SRegValue_Flag_UseCachedHotkeyModifierState;
- RootKey: HKCU;
- Key: SRegKey_KeymanEngineDebug_CU;
- Description: 'Set to 1 to use a cached modifer state when checking hotkeys; if '+
- 'set to 0 then engine.compatibility.old_hotkey_registration may not '+
- 'work';
- ValueType: kstInteger
- ),
-
// keyman32:keyman32.Initialise_Flag_ShouldSerializeInput
(
ID: 'engine.compatibility.serialize_input';
From b7b17686ece2b29c43889131011aa89205401f11 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Mon, 19 Aug 2024 14:01:43 +1000
Subject: [PATCH 2/7] feat(windows): add rmodifier hk to keyman config UI
---
common/windows/cpp/include/registry.h | 6 ++++--
common/windows/delphi/general/RegistryKeys.pas | 2 +-
windows/src/desktop/kmshell/xml/strings.xml | 2 +-
.../src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 10 ++++++++--
windows/src/engine/kmcomapi/util/utilkeymanoption.pas | 1 +
.../src/global/delphi/general/KeymanOptionNames.pas | 5 ++++-
6 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h
index ebaca81c9cf..c6d1bf85ec1 100644
--- a/common/windows/cpp/include/registry.h
+++ b/common/windows/cpp/include/registry.h
@@ -110,6 +110,10 @@
#define REGSZ_KeyboardHotkeysAreToggle "hotkeys are toggles"
#define REGSZ_DeadkeyConversionMode "deadkey conversion mode" // CU // I4552
#define REGSZ_ZapVirtualKeyCode "zap virtual key code" // LM, defaults to 0x0E (_VK_PREFIX_DEFAULT)
+/* Non-chiral use of hotkeys instead of left-only hotkeys */
+#define REGSZ_UseRightModifierHotKey "use right modifier for hotkey"
+
+
/*
Debug flags
These are all stored in HKCU\Software\Keyman\Debug
@@ -121,9 +125,7 @@
#define REGSZ_Flag_ShouldSerializeInput "Flag_ShouldSerializeInput"
-/* REGSZ_Keyman_Debug DWORD: Use old non-chiral Win32 API RegisterHotkey instead of left-only hotkeys */
-#define REGSZ_Flag_UseRightModifierHotKey "Flag_UseRightModifierHotKey"
/* DWORD: Enable/disable deep TSF integration, default enabled; 0 = disabled, 1 = enabled, 2 = default */
diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas
index 8cbd6d7d0a3..0553b823065 100644
--- a/common/windows/delphi/general/RegistryKeys.pas
+++ b/common/windows/delphi/general/RegistryKeys.pas
@@ -115,6 +115,7 @@ interface
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
@@ -379,7 +380,6 @@ interface
SRegKey_KeymanEngineDebug_CU = SRegKey_KeymanEngineRoot_CU + '\Debug';
- SRegValue_Flag_UseRightModifierHotKey = 'Flag_UseRightModifierHotKey';
SRegValue_Flag_ShouldSerializeInput = 'Flag_ShouldSerializeInput';
SRegValue_Flag_UseAutoStartTask = 'Flag_UseAutoStartTask';
SRegValue_Flag_SyncLanguagesToCloud = 'Flag_SyncLanguagesToCloud';
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml
index 8bdb8b0221e..e15ba789453 100644
--- a/windows/src/desktop/kmshell/xml/strings.xml
+++ b/windows/src/desktop/kmshell/xml/strings.xml
@@ -380,7 +380,7 @@
- Simulate AltGr with Ctrl+Alt
+ Right Modifier keys work with Hotkeys
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index ce2ab3480e6..66d7d943aba 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -135,9 +135,15 @@ BOOL IsTouchPanelVisible() {
BOOL UseRightModifierHotKey() {
static BOOL flag_UseRightModifierHotKey = FALSE;
static BOOL loaded = FALSE;
+
if (!loaded) {
- loaded = TRUE;
- flag_UseRightModifierHotKey = Reg_GetDebugFlag(REGSZ_Flag_UseRightModifierHotKey, FALSE);
+ 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;
}
diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
index ce1b8af33a8..9d9f95465d4 100644
--- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
+++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
@@ -127,6 +127,7 @@ TKeymanOptionInfo = record
(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 27aef82ab55..73356d19cb3 100644
--- a/windows/src/global/delphi/general/KeymanOptionNames.pas
+++ b/windows/src/global/delphi/general/KeymanOptionNames.pas
@@ -5,7 +5,10 @@ interface
type
TUtilKeymanOption = (
// General options
- koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress,
+ koKeyboardHotkeysAreToggle,
+ koAltGrCtrlAlt,
+ koRightModifierHK,
+ koReleaseShiftKeysAfterKeyPress,
koShowHints, // I1256
// Startup options
koTestKeymanFunctioning,
From 65b9e49bac88976beedb9667ab7c010ede2e6cc3 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Mon, 19 Aug 2024 18:48:06 +1000
Subject: [PATCH 3/7] feat(windows): remove old UseRegisterHotkey
---
windows/src/engine/keyman/UfrmKeyman7Main.pas | 2 --
windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 3 ---
2 files changed, 5 deletions(-)
diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas
index 4c14c375ed3..155ab9208c0 100644
--- a/windows/src/engine/keyman/UfrmKeyman7Main.pas
+++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas
@@ -2050,7 +2050,6 @@ procedure TfrmKeyman7Main.RegisterHotkeys;
language: IKeymanLanguage;
id: Integer;
begin
- if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit;
TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []);
@@ -2104,7 +2103,6 @@ procedure TfrmKeyman7Main.UnregisterHotkeys;
var
i, hk: Integer;
begin
- if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit;
TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []);
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index 66d7d943aba..6d5067516e9 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -280,9 +280,6 @@ LRESULT _kmnLowLevelKeyboardProc(
}
BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) {
- if (UseRightModifierHotKey()) {
- return FALSE;
- }
Hotkeys *hotkeys = Hotkeys::Instance(); // I4641
if (!hotkeys) {
From 977d2948e6400e1c3524629818d61ed39ac07581 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Tue, 20 Aug 2024 10:06:04 +1000
Subject: [PATCH 4/7] feat(windows): fix out of bounds
---
windows/src/engine/kmcomapi/util/utilkeymanoption.pas | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
index 9d9f95465d4..2df38b5c825 100644
--- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
+++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
@@ -121,7 +121,7 @@ TKeymanOptionInfo = record
GroupName: string;
end;
-const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552
+const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552
// Global options
(opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'),
From 98787afbdcacf7a8e1a4f9e64e929fd3948f7007 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Tue, 20 Aug 2024 11:15:50 +1000
Subject: [PATCH 5/7] feat(windows): restore removal of klogging
---
common/windows/delphi/tools/test-klog/test_klog.dpr | 8 ++------
common/windows/delphi/tools/test-klog/test_klog.dproj | 4 ----
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/common/windows/delphi/tools/test-klog/test_klog.dpr b/common/windows/delphi/tools/test-klog/test_klog.dpr
index 7f9d0e213aa..072042334a0 100644
--- a/common/windows/delphi/tools/test-klog/test_klog.dpr
+++ b/common/windows/delphi/tools/test-klog/test_klog.dpr
@@ -7,17 +7,13 @@ uses
klog in '..\..\..\..\..\common\windows\delphi\general\klog.pas',
VersionInfo in '..\..\..\..\..\common\windows\delphi\general\VersionInfo.pas',
ErrorControlledRegistry in '..\..\..\..\..\common\windows\delphi\vcl\ErrorControlledRegistry.pas',
- Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas',
- DebugPaths in '..\..\..\..\..\common\windows\delphi\general\DebugPaths.pas',
- RegistryKeys in '..\..\..\..\..\common\windows\delphi\general\RegistryKeys.pas',
- KeymanVersion in '..\..\..\..\..\common\windows\delphi\general\KeymanVersion.pas',
- KeymanPaths in '..\..\..\..\..\common\windows\delphi\general\KeymanPaths.pas';
+ Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas';
begin
if KLEnabled then
begin
writeln('KLog is enabled - disable KLogging before release!');
- ExitCode := 0;
+ ExitCode := 1;
end
else
begin
diff --git a/common/windows/delphi/tools/test-klog/test_klog.dproj b/common/windows/delphi/tools/test-klog/test_klog.dproj
index 3a7cd7fa050..27d8e8d7d5d 100644
--- a/common/windows/delphi/tools/test-klog/test_klog.dproj
+++ b/common/windows/delphi/tools/test-klog/test_klog.dproj
@@ -214,10 +214,6 @@
-
-
-
-
Cfg_2
Base
From 3326ac2c6b62b66b0567965b3bb834ee432d9d6c Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Tue, 20 Aug 2024 15:14:57 +1000
Subject: [PATCH 6/7] feat(windows): remove check for non-chiral vkey
---
.../keyman32/k32_lowlevelkeyboardhook.cpp | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index 6d5067516e9..f5fbdb8f301 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -169,15 +169,14 @@ LRESULT _kmnLowLevelKeyboardProc(
if (GetKeyState(VK_LCONTROL) < 0) {
FHotkeyShiftState |= HK_CTRL;
+ SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey());
}
if (GetKeyState(VK_RCONTROL) < 0) {
FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID;
+ SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey());
}
- if (GetKeyState(VK_CONTROL) < 0) {
- FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RCTRL_INVALID : HK_CTRL;
- }
-
+
if (GetKeyState(VK_LMENU) < 0) {
FHotkeyShiftState |= HK_ALT;
}
@@ -186,10 +185,6 @@ LRESULT _kmnLowLevelKeyboardProc(
FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID;
}
- if (GetKeyState(VK_MENU) < 0) {
- FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RALT_INVALID : HK_ALT;
- }
-
if (GetKeyState(VK_LSHIFT) < 0) {
FHotkeyShiftState |= HK_SHIFT;
}
@@ -197,9 +192,9 @@ LRESULT _kmnLowLevelKeyboardProc(
FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID;
}
- if (GetKeyState(VK_SHIFT) < 0) {
- FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT;
- }
+ //if (GetKeyState(VK_SHIFT) < 0) {
+ // FHotkeyShiftState |= (!UseRightModifierHotKey() && 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,
From c48a4a72428626aad3137480cd36b66486297089 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Wed, 21 Aug 2024 11:56:55 +1000
Subject: [PATCH 7/7] feat(windows): Use RegisterHotkey only for chirl mode
---
windows/src/engine/keyman/UfrmKeyman7Main.pas | 36 +++++++++++++++++++
windows/src/engine/keyman32/hotkeys.cpp | 10 ++++--
.../keyman32/k32_lowlevelkeyboardhook.cpp | 31 ++++++++++------
3 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas
index 155ab9208c0..fbed70b24d0 100644
--- a/windows/src/engine/keyman/UfrmKeyman7Main.pas
+++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas
@@ -2049,7 +2049,25 @@ procedure TfrmKeyman7Main.RegisterHotkeys;
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', []);
@@ -2102,7 +2120,25 @@ procedure TfrmKeyman7Main.RegisterHotkeys;
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', []);
diff --git a/windows/src/engine/keyman32/hotkeys.cpp b/windows/src/engine/keyman32/hotkeys.cpp
index 8327a786498..e7fdbe3d79d 100644
--- a/windows/src/engine/keyman32/hotkeys.cpp
+++ b/windows/src/engine/keyman32/hotkeys.cpp
@@ -137,9 +137,13 @@ void Hotkeys::Load() { // I4390
Hotkey *Hotkeys::GetHotkey(DWORD hotkey)
{
- for(int i = 0; i < m_nHotkeys; i++)
- if(m_hotkeys[i].HotkeyValue == hotkey)
- return &m_hotkeys[i];
+ for (int i = 0; i < m_nHotkeys; i++) {
+ if (m_hotkeys[i].HotkeyValue == hotkey) {
+ SendDebugMessageFormat(
+ "LanguageHotkey[%d] = {HotkeyValue: %x, hkl: %x} passed in: %x", i, m_hotkeys[i].HotkeyValue, m_hotkeys[i].hkl, hotkey);
+ return &m_hotkeys[i];
+ }
+ }
return NULL;
}
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index f5fbdb8f301..2bdfae62e39 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -131,8 +131,10 @@ BOOL IsTouchPanelVisible() {
/*
Cache UseRightModifierHotKey debug flag for this session
+ when using right modifier for Hotkeys use the Win32 API
+ ResisterHotkey functionality
*/
-BOOL UseRightModifierHotKey() {
+BOOL UseRegisterHotkey() {
static BOOL flag_UseRightModifierHotKey = FALSE;
static BOOL loaded = FALSE;
@@ -169,31 +171,33 @@ LRESULT _kmnLowLevelKeyboardProc(
if (GetKeyState(VK_LCONTROL) < 0) {
FHotkeyShiftState |= HK_CTRL;
- SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey());
+ // TODO remove
+ SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey());
}
if (GetKeyState(VK_RCONTROL) < 0) {
- FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID;
- SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey());
+ 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 |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID;
+ FHotkeyShiftState |= UseRegisterHotkey() ? HK_ALT : HK_RALT_INVALID;
}
if (GetKeyState(VK_LSHIFT) < 0) {
FHotkeyShiftState |= HK_SHIFT;
}
if (GetKeyState(VK_RSHIFT) < 0) {
- FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID;
+ FHotkeyShiftState |= UseRegisterHotkey() ? HK_SHIFT : HK_RSHIFT_INVALID;
}
//if (GetKeyState(VK_SHIFT) < 0) {
- // FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT;
+ // FHotkeyShiftState |= (!UseRegisterHotkey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT;
//}
// #7337 Post the modifier state ensuring the serialized queue is in sync
@@ -275,28 +279,35 @@ 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");
return FALSE;
}
Hotkey *hotkey = hotkeys->GetHotkey(ShiftState | vkCode); // I4641
if (!hotkey) {
+ SendDebugMessageFormat("GetHotkey Null");
return FALSE;
}
if (isUp) {
+ SendDebugMessageFormat("Is Up");
return TRUE;
}
if (hotkey->HotkeyType == hktInterface) {
+ SendDebugMessageFormat("PostMasterController");
Globals::PostMasterController(wm_keyman_control, MAKELONG(KMC_INTERFACEHOTKEY, hotkey->Target), 0);
}
else {
+ SendDebugMessageFormat("ReportKeyboardChanged");
ReportKeyboardChanged(PC_HOTKEYCHANGE, hotkey->hkl == 0 ? TF_PROFILETYPE_INPUTPROCESSOR : TF_PROFILETYPE_KEYBOARDLAYOUT, 0, hotkey->hkl, GUID_NULL, hotkey->profileGUID);
}
-
+ SendDebugMessageFormat("PostDummyKeyEvent");
/* Generate a dummy keystroke to block menu activations, etc but let the shift key through */
PostDummyKeyEvent(); // I3301 - this is imperfect because we don't deal with HC_NOREMOVE. But good enough? // I3534 // I4844