-
-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a shortkey for the keyboard layout manual switching #3859
Changes from 6 commits
2b54b6d
96e33f0
5e6af3c
cc06065
c36965a
6381b59
cfbc84b
d7b15fa
8ca6717
cb13591
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
from ctypes.wintypes import DWORD | ||
|
||
from xpra.platform.win32.common import ( | ||
ActivateKeyboardLayout, | ||
GetKeyState, GetKeyboardLayoutList, GetKeyboardLayout, | ||
GetIntSystemParametersInfo, GetKeyboardLayoutName, | ||
GetWindowThreadProcessId, | ||
|
@@ -37,6 +38,39 @@ def _GetKeyboardLayoutList(): | |
return layouts | ||
|
||
|
||
def x11_layouts_to_win32_hkl(): | ||
KMASKS = { | ||
0xffffffff : (0, 16), | ||
0xffff : (0, ), | ||
0x3ff : (0, ), | ||
} | ||
layout_to_hkl = {} | ||
max_items = 32 | ||
try: | ||
handle_list = (HANDLE*max_items)() | ||
count = GetKeyboardLayoutList(max_items, ctypes.byref(handle_list)) | ||
for i in range(count): | ||
hkl = handle_list[i] | ||
hkli = int(hkl) | ||
for mask, bitshifts in KMASKS.items(): | ||
kbid = 0 | ||
for bitshift in bitshifts: | ||
kbid = (hkli & mask)>>bitshift | ||
if kbid in WIN32_LAYOUTS: | ||
break | ||
if kbid in WIN32_LAYOUTS: | ||
code, _, _, _, _layout, _variants = WIN32_LAYOUTS.get(kbid) | ||
log("found keyboard layout '%s' / %#x with variants=%s, code '%s' for kbid=%#x", | ||
_layout, kbid, _variants, code, hkli) | ||
if _layout not in layout_to_hkl: | ||
layout_to_hkl[_layout] = hkl | ||
break | ||
except Exception: | ||
log("x11_layouts_to_win32_hkl()", exc_info=True) | ||
return layout_to_hkl | ||
|
||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small nitpick: one CR too many! |
||
EMULATE_ALTGR = envbool("XPRA_EMULATE_ALTGR", True) | ||
EMULATE_ALTGR_CONTROL_KEY_DELAY = envint("XPRA_EMULATE_ALTGR_CONTROL_KEY_DELAY", 50) | ||
|
||
|
@@ -60,6 +94,16 @@ def init_vars(self): | |
#workaround for "fr" keyboards, which use a different key name under X11: | ||
KEY_TRANSLATIONS[("dead_tilde", 65107, 50)] = "asciitilde" | ||
KEY_TRANSLATIONS[("dead_grave", 65104, 55)] = "grave" | ||
self.__x11_layouts_to_win32_hkl = x11_layouts_to_win32_hkl() | ||
|
||
def set_platform_layout(self, layout): | ||
hkl = self.__x11_layouts_to_win32_hkl.get(layout) | ||
if hkl is None: | ||
return 0 | ||
# https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-activatekeyboardlayout | ||
# KLF_SETFORPROCESS|KLF_REORDER = 0x108 | ||
old_hkl_or_zero_on_failure = ActivateKeyboardLayout(hkl, 0x108) | ||
return old_hkl_or_zero_on_failure | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. None of the other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the return value and just logged the failures because in the "gnome dbus request" scenario, successful/failed response will be determined by a callback and it does not seem good to block the shortkey processing until the callback is invoked. |
||
|
||
def __repr__(self): | ||
return "win32.Keyboard" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
best to use
x.lower() in TRUE_OPTIONS
/x.lower() in FALSE_OPTIONS