是否可以只用一个键(如Control_L
或 )来打开特定键盘布局Shift_L
,而不会丢失其主要功能?例如,我尝试为命令创建自定义键绑定,setxkbmap -layout en
并通过dconf-editor
将其绑定到 来编辑它Control_L
。布局打开了,但常用的快捷键Control_L
停止工作。
答案1
这是一个可以执行此操作的 Python 脚本。您需要sudo apt install python3-xlib
。
#!/usr/bin/env python3
# Based off https://stackoverflow.com/a/22368676/10477326
from Xlib.display import Display
from Xlib import X
from Xlib.ext import record
from Xlib.protocol import rq
import subprocess
TARGET_KEY = 37 # CTRL
target_pressed = False
disp = None
def handler(reply):
global target_pressed
data = reply.data
# Listen for all keys
while len(data):
event, data = rq.EventField(None).parse_binary_value(data, disp.display, None, None)
typ = event.type
if typ not in (X.KeyPress, X.KeyRelease):
# Interrupt on mouse Ctrl+Zoom or Ctrl+Click. Thank you @terdon
target_pressed = False
continue
detail = event.detail
# If there was another key in the middle,
# stop because it's another key combination and not just
# the one key that we desire.
if detail != TARGET_KEY:
target_pressed = False
continue
# On KeyPress, set a flag to wait for a KeyRelease to make sure
# no other keys will be pressed.
if typ == X.KeyPress:
target_pressed = True
continue
# Previously another key in the middle was detected.
if not target_pressed:
continue
# Now we know only the TARGET_KEY was pressed and released without any other keys.
# Run your command
subprocess.run(["setxkbmap", "-layout", "en"])
target_pressed = False
disp = Display()
root = disp.screen().root
ctx = disp.record_create_context(
0,
[record.AllClients],
[{
'core_requests': (0, 0),
'core_replies': (0, 0),
'ext_requests': (0, 0, 0, 0),
'ext_replies': (0, 0, 0, 0),
'delivered_events': (0, 0),
'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask),
'errors': (0, 0),
'client_started': False,
'client_died': False,
}],
)
disp.record_enable_context(ctx, handler)
disp.record_free_context(ctx)
while True:
event = root.display.next_event()
然后,您可以将其标记为可执行文件,并在启动应用程序中添加指向它的链接。主要思想是全局监听所有窗口上的所有按键。然后,我会监听其间的任何其他按键,以了解您是否要切换布局或使用其他快捷方式。目标键仍会始终发送到原始窗口。