如何使用libX11拦截Windows/Super键事件传递到Ubuntu 21.10系统
实现方案
你之前的XGrabKey调用无法拦截Windows键是两个原因导致的:一是没有针对性捕获Windows键对应的Mod4修饰符相关事件,二是同步捕获模式和全局参数配置冲突。以下是可直接使用的实现方案,仅拦截Windows键及相关组合键,不会影响其他键盘输入:
核心原理
Ubuntu 21.10默认将左右Windows键映射为Super_L和Super_R按键,同时绑定到X11的Mod4修饰符,所有Windows相关的快捷键都会带上Mod4Mask标记,只需要针对性捕获这部分事件即可。
修正后的代码示例
from Xlib import X, display from Xlib.keysymdef import XK_Super_L, XK_Super_R d = display.Display() lock_window = # 你的全屏锁定窗口对象 # 1. 预获取左右Windows键对应的键码 left_win_code = d.keysym_to_keycode(XK_Super_L) right_win_code = d.keysym_to_keycode(XK_Super_R) # 2. 捕获单独按下Windows键的事件,兼容NumLock、CapsLock等锁键的修饰位 extra_mods = [0, X.LockMask, X.Mod2Mask, X.LockMask | X.Mod2Mask] for mod in extra_mods: # 捕获左Win键 XGrabKey(d, left_win_code, mod, lock_window, False, X.GrabModeAsync, X.GrabModeAsync) # 捕获右Win键 XGrabKey(d, right_win_code, mod, lock_window, False, X.GrabModeAsync, X.GrabModeAsync) # 3. 捕获所有带Win键的组合快捷键,避免触发系统全局操作 for keycode in range(0, 256): for mod in extra_mods: XGrabKey(d, keycode, X.Mod4Mask | mod, lock_window, False, X.GrabModeAsync, X.GrabModeAsync) # 4. 主动抢占输入焦点,保证捕获生效 XSetInputFocus(d, lock_window, X.RevertToNone, X.CurrentTime) d.flush()
解锁时的清理逻辑
程序解锁时必须主动释放捕获的按键,否则会导致系统Win键永久失效:
# 释放所有捕获的按键 XUngrabKey(d, X.AnyKey, X.AnyModifier, lock_window) d.flush()
注意事项
- 不要使用
ANY_KEY + ANY_MODIFIER的全局捕获组合,会和窗口管理器的高优先级全局快捷键冲突,导致捕获失效 - 将原来的
GRAB_MODE_SYNC改为GRAB_MODE_ASYNC,捕获到的Win键事件会被直接吞掉,不需要额外调用XAllowEvents处理
内容的提问来源于stack exchange,提问作者TheLizzard
相关产品推荐
相关产品推荐

