Ubuntu 24.04下终端失焦时Pynput模拟按键失效问题求助
解决Ubuntu 24.04下模拟按键失焦无效的问题
你的核心问题是Ubuntu 24.04默认使用Wayland显示服务器,它对跨窗口输入模拟有严格的安全限制,导致pynput、pyautogui这类库在终端失焦后无法生效。以下是两种可行的解决方式:
方式一:切换到Xorg显示服务器
这是最直接的解决方案,Xorg对输入模拟的限制更少:
- 在系统登录界面,点击用户名右侧的齿轮图标,选择「Ubuntu on Xorg」
- 登录后重新运行你的WebSocket服务器,测试按键模拟是否正常工作
方式二:使用ydotool在Wayland下模拟按键
如果不想切换到Xorg,可以用ydotool(基于uinput的工具,Wayland原生支持)替代现有库:
- 安装ydotool:
sudo apt update && sudo apt install ydotool - 给当前用户添加uinput权限(避免每次用sudo):
执行后需要重新登录系统生效。sudo usermod -aG input $USER - 修改你的代码,替换
play_pause函数:import asyncio import websockets import subprocess def play_pause(): print("Sending Play...") # 模拟Ctrl+Alt+Shift+Space的按下与释放 subprocess.run([ "ydotool", "key", "ctrl:1", "alt:1", "shift:1", "space:1", "space:0", "shift:0", "alt:0", "ctrl:0" ]) async def handle_connection(websocket, path): async for message in websocket: command = message if command == "play/pause": play_pause() print("play/pause") else: print(f"Unknown command: {command}") await websocket.send(f"Command '{command}' received") async def main(): async with websockets.serve(handle_connection, "localhost", 9999): print("WebSocket server started at ws://localhost:9999") await asyncio.Future() # Run forever if __name__ == "__main__": asyncio.run(main())
补充说明
- pyautogui和keyboard库在Wayland下普遍存在兼容性问题,因为它们依赖X11的输入模拟接口,而Wayland不兼容这些接口。
- 如果你的服务器是通过Flatpak等沙箱方式运行,还需要额外配置沙箱的输入权限。
内容的提问来源于stack exchange,提问作者Matheus Lima
相关产品推荐
相关产品推荐

