From f1d9f5304863fee2afa012ba57fc977632b9bc20 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:32:39 +1000 Subject: [PATCH 1/5] feat(windows): add right modifier included in HotKey --- windows/src/desktop/kmshell/xml/strings.xml | 16 +++--- .../keyman32/k32_lowlevelkeyboardhook.cpp | 52 +++++++++++++++++++ .../engine/kmcomapi/util/utilkeymanoption.pas | 3 +- .../delphi/general/KeymanOptionNames.pas | 5 +- 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 774a4d5e425..e15ba789453 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 + + + + Right Modifier keys work with Hotkeys + @@ -792,18 +797,13 @@ 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/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 8e3fe92a3ce..4d842401dd8 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -129,6 +129,27 @@ BOOL IsTouchPanelVisible() { return touchPanelVisible; } +/* + Cache UseRightModifierHotKey debug flag for this session +*/ +BOOL UseRightModifierHotKey() { + 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, @@ -157,6 +178,37 @@ LRESULT _kmnLowLevelKeyboardProc( 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; + + 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, UseRightModifierHotKey()); + } + + if (GetKeyState(VK_RCONTROL) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; + // TODO remove + SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); + } + + if (GetKeyState(VK_LMENU) < 0) { + FHotkeyShiftState |= HK_ALT; + } + + if (GetKeyState(VK_RMENU) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? 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; + } + + + + //TODO: #8064. Can remove debug message once issue #8064 is resolved SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index ce1b8af33a8..2df38b5c825 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -121,12 +121,13 @@ 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'), (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 2927f57c04fc779d917149ea9fda2ebcddfa9d3c Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:41:31 +1000 Subject: [PATCH 2/5] feat(windows): missed checked in file --- common/windows/delphi/general/RegistryKeys.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 1557de58657..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 From 558636886c7a776fcd6eeb3791efae29d432c6d6 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:39:47 +1000 Subject: [PATCH 3/5] feat(windows): remove left modifier only bit flag --- windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 4d842401dd8..e33a610e61b 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -172,12 +172,6 @@ LRESULT _kmnLowLevelKeyboardProc( // #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; if (GetKeyState(VK_LCONTROL) < 0) { FHotkeyShiftState |= HK_CTRL; @@ -207,8 +201,6 @@ LRESULT _kmnLowLevelKeyboardProc( } - - //TODO: #8064. Can remove debug message once issue #8064 is resolved SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); From 500c800bb495ab44db66e3b4558cd40224230f1e Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:01:50 +1000 Subject: [PATCH 4/5] feat(windows): remove developer debug logging --- common/windows/cpp/include/registry.h | 2 +- windows/src/desktop/kmshell/xml/strings.xml | 4 ++-- windows/src/engine/keyman32/hotkeys.cpp | 2 -- .../keyman32/k32_lowlevelkeyboardhook.cpp | 24 ++++--------------- 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h index c6d1bf85ec1..842176e9edc 100644 --- a/common/windows/cpp/include/registry.h +++ b/common/windows/cpp/include/registry.h @@ -110,7 +110,7 @@ #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 */ +/* Default is to only use left modifier in hotkeys trigger */ #define REGSZ_UseRightModifierHotKey "use right modifier for hotkey" diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index ea09ca5b744..9409d6d8c12 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -379,8 +379,8 @@ - - Right Modifier keys work with Hotkeys + + Right-side modifier keys trigger hotkeys diff --git a/windows/src/engine/keyman32/hotkeys.cpp b/windows/src/engine/keyman32/hotkeys.cpp index e7fdbe3d79d..1652397d77b 100644 --- a/windows/src/engine/keyman32/hotkeys.cpp +++ b/windows/src/engine/keyman32/hotkeys.cpp @@ -139,8 +139,6 @@ Hotkey *Hotkeys::GetHotkey(DWORD hotkey) { 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]; } } diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index e33a610e61b..8e16d536f2a 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -130,7 +130,7 @@ BOOL IsTouchPanelVisible() { } /* - Cache UseRightModifierHotKey debug flag for this session + Cache UseRightModifierHotKey for this session */ BOOL UseRightModifierHotKey() { static BOOL flag_UseRightModifierHotKey = FALSE; @@ -148,8 +148,6 @@ BOOL UseRightModifierHotKey() { return flag_UseRightModifierHotKey; } - - LRESULT _kmnLowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, @@ -169,20 +167,14 @@ 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 - // #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) { + 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, UseRightModifierHotKey()); } if (GetKeyState(VK_RCONTROL) < 0) { FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); } if (GetKeyState(VK_LMENU) < 0) { @@ -200,10 +192,8 @@ LRESULT _kmnLowLevelKeyboardProc( FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; } - - //TODO: #8064. Can remove debug message once issue #8064 is resolved - SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); - + //TODO: #8064. Can remove debug message once issue #8064 is resolved + SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); // #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, @@ -287,30 +277,24 @@ BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { 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 From 10c343fc432641b1df11fa73e0e852fde2c6c7cf Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 2 Sep 2024 13:31:21 +1000 Subject: [PATCH 5/5] feat(windows): change verb use to allow for clarity --- common/windows/delphi/general/RegistryKeys.pas | 8 ++++---- windows/src/desktop/kmshell/xml/strings.xml | 2 +- .../keyman32/k32_lowlevelkeyboardhook.cpp | 18 +++++++++--------- .../engine/kmcomapi/util/utilkeymanoption.pas | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 0553b823065..e351b3860ff 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -113,11 +113,11 @@ interface SRegValue_ShowWelcome = 'show welcome'; // CU SRegValue_UseAdvancedInstall = 'use advanced install'; // CU - SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU - SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU - SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU + SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU + SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU + SRegValue_AllowRightModifierHotKey = 'allow right modifier for hotkey'; // CU SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU - SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true + SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true SRegValue_CreateStartMenuAsSubfolders = 'create start menu as subfolders'; // CU SRegValue_CreateUninstallEntries = 'create uninstall entries'; // CU diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 9409d6d8c12..8b6c37c55c8 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -380,7 +380,7 @@ - Right-side modifier keys trigger hotkeys + Allow right modifier for hotkeys diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index efd5d158bb9..a6a84faf44c 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -130,22 +130,22 @@ BOOL IsTouchPanelVisible() { } /* - Cache UseRightModifierHotKey for this session + Cache AllowRightModifierHotKey for this session */ -BOOL UseRightModifierHotKey() { - static BOOL flag_UseRightModifierHotKey = FALSE; +BOOL AllowRightModifierHotKey() { + static BOOL flag_AllowRightModifierHotKey = FALSE; static BOOL loaded = FALSE; if (!loaded) { RegistryReadOnly reg(HKEY_CURRENT_USER); if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) { if (reg.ValueExists(REGSZ_AllowRightModifierHotKey)) { - flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_AllowRightModifierHotKey); + flag_AllowRightModifierHotKey = !!reg.ReadInteger(REGSZ_AllowRightModifierHotKey); } } loaded = TRUE; // Set loaded to TRUE whether or not the key exists } - return flag_UseRightModifierHotKey; + return flag_AllowRightModifierHotKey; } LRESULT _kmnLowLevelKeyboardProc( @@ -176,7 +176,7 @@ LRESULT _kmnLowLevelKeyboardProc( } if (GetKeyState(VK_RCONTROL) < 0) { - FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; + FHotkeyShiftState |= AllowRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; } if (GetKeyState(VK_LMENU) < 0) { @@ -184,18 +184,18 @@ LRESULT _kmnLowLevelKeyboardProc( } if (GetKeyState(VK_RMENU) < 0) { - FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID; + FHotkeyShiftState |= AllowRightModifierHotKey() ? 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 |= AllowRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; } //TODO: #8064. Can remove debug message once issue #8064 is resolved - SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); + SendDebugMessageFormat("[FHotkeyShiftState:%x]", FHotkeyShiftState); // #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, diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index 2df38b5c825..906e121f077 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -127,7 +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: koRightModifierHK; RegistryName: SRegValue_AllowRightModifierHotKey; 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'),