问题摘要:我希望我的鼠标按钮之一能够被 X11 注册为 Windows 左键Super_L。
在我的窗口管理器中,我可以通过按住“左 Windows 按钮”(左 Super)并用鼠标左键拖动窗口来移动窗口。我希望能够在不触摸键盘的情况下做到这一点,所以我想将左 Super 键映射到鼠标按钮 11,这样我就可以按住鼠标按钮 11 并单击并拖动窗口。
最明显的解决方案是使用 xbindkeys 和 xte,如下所示(.xbindkeysrc
):
"xte 'keydown Super_L'"
b:11
"xte 'keyup Super_L'"
b:11 + release
它的工作原理如下:
- 当我按下鼠标第 11 键时,Super_L也会按下
- 当我释放鼠标第 11 键时,Super_L也会释放
但是有一个问题:如果我还按住另一个鼠标按钮(如鼠标按钮 11),则无法使用Super_L+移动窗口。使用上述解决方案,鼠标按钮 11 仍被注册为按下和释放,因此所有窗口管理器操作都不起作用。Mouse1
我已经尝试使用 Cinnamon 和 Awesome WM 来实现这一点,绝对没有Super_L当鼠标按钮 10 或 11 被按住时,键盘组合键可以起作用。
低于标准的黑客攻击
我目前正在解决这个问题,方法是让鼠标 11 单击以按住Super_L按钮一段时间。这样我就可以点击鼠标按钮,然后短暂地拖动内容:
"xte 'keydown Super_L' 'usleep 250000' 'keyup Super_L'"
b:11
另一次尝试
按照 totti 的建议,我尝试了这种xbindkeys
配置:
"xte 'mouseup 10' 'keydown Super_L'"
b:10
"xte 'keyup Super_L'"
b:10 + Release
它不起作用。似乎Super_L按键被按住了,因为一旦我释放按钮 10,它就会一直保持按住状态(直到我Super_L再次按下键盘上的按键),但鼠标按钮仍然被注册,因为我无法单击和拖动窗口。我不认为我能使用xbindkeys
和来实现这一点xte
。
答案1
askubuntu 帖子包含一个答案下面我将进行总结。
问题是 xbindkeys 会抓取整个鼠标,导致修饰键 + 鼠标点击映射不确定。答案是使用 uinput 通过python-uinput脚本来监控/dev/my-mouse
拇指按钮的点击并将Ctrl按键发送到虚拟键盘。以下是详细步骤:
1.制定udev规则
对于鼠标,文件/etc/udev/rules.d/93-mxmouse.conf.rules
:
KERNEL=="event[0-9]*", SUBSYSTEM=="input", SUBSYSTEMS=="input",
ATTRS{name}=="Logitech Performance MX", SYMLINK+="my_mx_mouse",
GROUP="mxgrabber", MODE="640"
Udev 将查找名称类似 event5 的内核设备。SYMLINK 用于查找 中的鼠标/dev/my_mx_mouse
,可供 组读取mxgrabber
。
要查找硬件信息,请运行以下命令:
udevadm info -a -n /dev/input/eventX
对于 uinput,文件/etc/udev/rules.d/94-mxkey.rules
:
KERNEL=="uinput", GROUP="mxgrabber", MODE="660"
拔下并插入鼠标,或者强制 udev 触发规则udevadm trigger
。
2. 激活 UINPUT 模块
sudo modprobe uinput
并且/etc/modules-load.d/uinput.conf
:
uinput
3. 创建新组
sudo groupadd mxgrabber
sudo usermod -aG mxgrabber your_login
4.Python脚本
安装python-uinput library
和python-evdev library
。
下面的脚本需要识别按钮的event.code:
#!/usr/bin/python3.5
# -*- coding: utf-8 -*-
"""
Sort of mini driver.
Read a specific InputDevice (my_mx_mouse),
monitoring for special thumb button
Use uinput (virtual driver) to create a mini keyboard
Send ctrl keystroke on that keyboard
"""
from evdev import InputDevice, categorize, ecodes
import uinput
# Initialize keyboard, choosing used keys
ctrl_keyboard = uinput.Device([
uinput.KEY_KEYBOARD,
uinput.KEY_LEFTCTRL,
uinput.KEY_F4,
])
# Sort of initialization click (not sure if mandatory)
# ( "I'm-a-keyboard key" )
ctrl_keyboard.emit_click(uinput.KEY_KEYBOARD)
# Useful to list input devices
#for i in range(0,15):
# dev = InputDevice('/dev/input/event{}'.format(i))
# print(dev)
# Declare device patch.
# I made a udev rule to assure it's always the same name
dev = InputDevice('/dev/my_mx_mouse')
#print(dev)
ctrlkey_on = False
# Infinite monitoring loop
for event in dev.read_loop():
# My thumb button code (use "print(event)" to find)
if event.code == 280 :
# Button status, 1 is down, 0 is up
if event.value == 1:
ctrl_keyboard.emit(uinput.KEY_LEFTCTRL, 1)
ctrlkey_on = True
elif event.value == 0:
ctrl_keyboard.emit(uinput.KEY_LEFTCTRL, 0)
ctrlkey_on = False
5. 整理
使 python 文件可执行并确保它在启动时加载。
答案2
由于您可以通过鼠标单击来运行脚本,因此您可以使用以下技巧。
1. 按按钮 11到抓住这超级键。 (按钮 11触发脚本)
2.使用其他鼠标按钮移动窗口
3. 按鼠标按钮 11再次发布 超级键
脚本
使用xdotool
容纳超级键
第一次单击按钮时,创建一个临时文件并按住键。下次单击删除临时文件并释放键,
更新
根据 ubuntu 帮助页面(多键鼠标如何使用)imwheel
可以重新映射到一个键。
答案3
调试建议:我会尝试监视/dev/input/eventX
文件以查看按下和释放该按钮时会生成什么事件,尤其是与 的组合BTN_LEFT
。这里这是帮助您入门的示例代码。显然,您必须对其进行修改,才能记录所有事件,而不仅仅是按键事件。
xev
如果还没有,您可能还想检查一下输出。分析这两个日志应该能发现您遇到的确切问题。
您的鼠标在按下多个按钮时可能会生成额外的按钮释放事件。在这种情况下,您的选择是使用键绑定解决方法,或修改xf86-input-evdev
库以过滤不需要的事件(或模拟丢失的事件)。不久前,我为触摸屏做了类似的事情,它在尝试拖放时生成了“点击”事件。这个想法是过滤几乎同时(在很短的时间窗口内)发生的“释放”事件和“点击”事件。如果我的猜测是正确的,您基本上需要实现类似的东西。
答案4
今天早些时候,我使用其他修饰键解决了这个问题。问题是,您必须在按钮组合中包含修饰键才能释放。假设您的 Super 键映射到 Mod4(据我所知,这应该是默认设置):
"xte 'keydown Super_L'"
b:11
"xte 'keyup Super_L'"
Mod4 + b:11 + release
编辑:刚刚意识到这并不能完全回答你的问题,因为你仍然无法在按住 b:11 时使用 LMB