feat(windows): remove registerhotkey and cache modifier

Remove the feature flags that allows the use of cached modifier for
hotkeys. Remove the feature flag that uses the Win 32 API
RegisterHotkeys.
This commit is contained in:
rc-swag 2024-08-22 15:45:23 +10:00
parent c48a4a7242
commit 05d52463f9
6 changed files with 22 additions and 221 deletions

View file

@ -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

View file

@ -377,11 +377,6 @@
<!-- Introduced: 7.0.230.0 -->
<string name="koAltGrCtrlAlt" comment="General options - Ctrl+Alt simulates AltGr on computers without AltGr">Simulate AltGr with Ctrl+Alt</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 18.0.91 -->
<string name="koRightModifierHK" comment="General options - Right Ctrl Alt and Shift Work for HotKey">Right Modifier keys work with Hotkeys</string>
<!-- Context: Configuration Dialog - Options tab -->
<!-- String Type: FormatString -->
<!-- Introduced: 9.0.480.0 -->
@ -797,13 +792,18 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to
<!-- Context: Splash Dialog -->
<!-- String Type: PlainText -->
<!-- Introduced: 8.0.288.0 -->
<string name="S_Splash_Name" comment="Splash major title">Keyman</string>
<string name="S_Splash_Name" translatable="false" comment="Splash major title">Keyman</string>
<!-- Context: Splash Dialog -->
<!-- String Type: PlainText -->
<!-- Introduced: 8.0.294.0 -->
<string name="S_Splash_Start" comment="Start Keyman button">Start Keyman</string>
<!-- Context: Splash Dialog -->
<!-- String Type: PlainText -->
<!-- Introduced: 18.0 -->
<string name="S_Splash_Start_2" comment="Start {Keyman} button">Start %1$s</string>
<!-- Context: Splash Dialog -->
<!-- String Type: PlainText -->
<!-- Introduced: 8.0.294.0 -->
@ -860,7 +860,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to
<!-- Context: Formatted Messages -->
<!-- String Type: FormatString -->
<!-- Introduced: 7.0.230.0 -->
<string name="SKShortApplicationTitle" comment="Product name">Keyman</string>
<string name="SKShortApplicationTitle" translatable="false" comment="Product name">Keyman</string>
@ -1026,7 +1026,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to
<!-- Context: Formatted Messages -->
<!-- String Type: FormatString -->
<!-- Introduced: 7.0.230.0 -->
<string name="SKApplicationTitle" comment="Product name used for the title of message boxes and message dialogs">Keyman</string>
<string name="SKApplicationTitle" translatable="false" comment="Product name used for the title of message boxes and message dialogs">Keyman</string>
<!-- Parameters: %1$s = Version number string -->
<!-- Context: Formatted Messages -->

View file

@ -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);

View file

@ -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");

View file

@ -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'),

View file

@ -5,10 +5,7 @@ interface
type
TUtilKeymanOption = (
// General options
koKeyboardHotkeysAreToggle,
koAltGrCtrlAlt,
koRightModifierHK,
koReleaseShiftKeysAfterKeyPress,
koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress,
koShowHints, // I1256
// Startup options
koTestKeymanFunctioning,