mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-22 07:37:40 +00:00
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:
parent
c48a4a7242
commit
05d52463f9
6 changed files with 22 additions and 221 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 -->
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ interface
|
|||
type
|
||||
TUtilKeymanOption = (
|
||||
// General options
|
||||
koKeyboardHotkeysAreToggle,
|
||||
koAltGrCtrlAlt,
|
||||
koRightModifierHK,
|
||||
koReleaseShiftKeysAfterKeyPress,
|
||||
koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress,
|
||||
koShowHints, // I1256
|
||||
// Startup options
|
||||
koTestKeymanFunctioning,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue