如何使用xbindkeys将修改器(例如CTRL)映射到鼠标滑块按钮

这个问题已被提出,但从未得到适当回答。 在与@Seth通关后,我现在再次询问它。 这将允许我回答并可能更容易地修改问题。 原始问题可以在这里找到:

将Ctrl和Alt映射到鼠标滑块按钮


问题:

虽然使用xbindkeysxdotoolxdotool将任何键击映射到鼠标按钮非常简单,但是将修改键(例如ALTCTRLSHIFT等)映射到它时似乎更有问题。

最终的解决方案应该只允许用CTRL + 点击 (例如,用于选择列表的多个条目)。

可以在Stack Exchange以及其他Linux相关论坛中找到解决此问题的几种可能方法。 但这些都没有像预期的那样起作用,因为它们会导致其他问题和副作用。

笔记:

下面的一些示例涉及Guile with Scheme语法并依赖于.xbindkeysrc.scm文件,而其他.xbindkeysrc依赖于.xbindkeysrc文件及其各自的语法。 我知道他们不会一起工作。

此外,下面的片段仅依赖于xdotool但我对涉及xdotool等其他应用程序的方法xdotool开放态度 – 虽然它似乎导致相同的结果,因此我在这里只使用xdotool操作。

方法A:

使用以下命令更新.xbindkeysrc文件:

 "xdotool keydown ctrl" b:8 "xdotool keyup ctrl" release + b:8 

这就是我最初尝试过的,但它有副作用,即修饰符被保留并且无法释放。

方法B:

使用以下命令更新.xbindkeysrc.scm文件:

 (xbindkey '("b:8") "xdotool keydown ctrl") (xbindkey '(release "b:8") "xdotool keyup ctrl") (xbindkey '("m:0x14" "b:8") "xdotool keydown ctrl") (xbindkey '(release "m:0x14" "b:8") "xdotool keyup ctrl") 

发现于http://www.linuxforums.org/forum/hardware-peripherals/169773-solved-map-mouse-button-modifier-key.html并尝试解决修改器所处的问题(如方法所述)一个)。

虽然它修复了它只能部分工作,因为在按下拇指按钮时无法执行其他鼠标点击。

方法C:

使用以下命令更新.xbindkeysrc文件:

 "xdotool keydown ctrl" b:8 "xdotool keyup ctrl" release + control + b:8 

在OP中尝试了关于askubuntu的链接问题。 更简单,更稳固,因为它不涉及修饰符状态。 然而问题仍然存在,即无法进行CTRL + 点击

似乎xbindkeys本身就是问题,因为它识别了点击但不会执行它。 这可以使用xev | grep button进行测试 xev | grep buttonxbindkeys -v

xev记录的正常鼠标点击应如下所示:

 state 0x10, button 1, same_screen YES state 0x110, button 1, same_screen YES 

以及拇指按钮:

 state 0x10, button 8, same_screen YES state 0x10, button 8, same_screen YES 

但是当启用上面的xbindkeys配置时,它不会记录任何内容。 虽然拇指按钮映射到CTRL是有意义的,因此不再是鼠标按钮,但是按钮1也不会被记录,这很奇怪。 这可能是因为xbindkeys没有执行它,但它本身正在识别它:

 Button press ! e.xbutton.button=8 e.xbutton.state=16 "xdotool keydown ctrl" m:0x0 + b:8 (mouse) got screen 0 for window 16d Start program with fork+exec call Button press ! e.xbutton.button=1 e.xbutton.state=20 Button release ! e.xbutton.button=1 e.xbutton.state=276 Button release ! e.xbutton.button=8 e.xbutton.state=20 "xdotool keyup ctrl" Release + m:0x4 + b:8 (mouse) got screen 0 for window 16d Start program with fork+exec call 

方法D:

使用以下命令更新.xbindkeysrc文件:

 "xdotool keydown ctrl" b:8 "xdotool keyup ctrl" release + control + b:8 "xdotool click 1" b:1 

太简单……但会导致无限循环的点击。


更新:

与此同时,我购买了一台罗技G502,并注意到一旦通过Windows上的驱动程序进行配置,不仅配置文件本身存储在设备内存中,而且实际的按键操作由鼠标完成。 这实际上解决了我在Linux上的问题!

我记得能够做到的唯一另一只老鼠是Razer Copperhead。 但我想今天还有其他鼠标可以做到这一点。

我花了很多时间试图做出有约束力的工作。 我最终找到了一个解决方案,这个解决方案虽然复杂但效果很好,并不代表第三方软件。 我在这里分享,希望它能帮助人们。 此外,我知道这在安全性方面并不完美,因此任何建设性的反馈都非常受欢迎。

有一些非常好的解决方案, 就像这里提出的解决方案一样 ,但它总是受到xbindkeys的限制,他们抓住整个鼠标,使得修改器+鼠标点击映射不确定。 另外,来自上述链接的基于guile的解决方案使用ctrl + plus / ctrl + minus,例如Gimp无法识别。

我发现我们想要的是一个充当键盘的鼠标按钮,所以我使用了uinput,可以通过python访问,写了一个脚本监视/ 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 

对于输入:

 /etc/udev/rules.d/94-mxkey.rules ---------------------------------------------------- KERNEL=="uinput", GROUP="mxgrabber", MODE="660" 

不需要符号链接,uinput将始终位于$/dev/uinput$/dev/input/uinput具体取决于您所使用的系统。 当然,只要给他这个小组以及阅读和写作的权利。

您需要拔下插头 – 插上鼠标,新链接应出现在/ dev中。 您可以使用$udevadm trigger强制udev触发规则

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库 (显然)和python-evdev库 。 使用pip或您的分发包。

该脚本非常简单,您只需要识别您按钮的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文件可执行,并要求您的桌面管理器在启动时加载该文件。 也许还有一杯葡萄酒来庆祝这项好工作!

6.额外免费

我使用xbindkeys进行其他行为。 例如,如果您有一个带有侧轮点击的鼠标,则以下配置可能会很好:

 ~/.xbindkeysrc --------------------------------------------- # Navigate between tabs with side wheel buttons "xdotool key ctrl+Tab" b:7 "xdotool key ctrl+shift+Tab" b:6 # Close tab with ctrl + right click # --clearmodifiers ensure that ctrl state will be # restored if button is still pressed "xdotool key --clearmodifiers ctrl+F4" control+b:3 

要使最后一个组合工作, 您必须禁用为python脚本配置的按钮 ,否则它仍然会被xbindkeys抓取。 只有Ctrl键必须保留:

 ~/.Xmodmap ------------------------------------------- ! Disable button 13 ! Is mapped to ctrl with uinput and python script pointer = 1 2 3 4 5 6 7 8 9 10 11 12 0 14 15 

使用$ xmodmap ~/.Xmodmap重新加载

7.结论

正如我在开始时所说的那样,即使它被认为是“mxgrabber”组,我也不得不给自己写信给/ dev / uinput。 我确信有一种更安全的方式,但我不知道如何做到这一点。

从好的方面来看,它确实很有效。 键盘或鼠标键的任何组合如何使用键盘的Ctrl按钮现在可以与鼠标一起使用!!

我找到了一个PyUserInput的解决方案。 这最终非常简单,不需要管理权限。 安装了python 2和PyUserInput后,我使用了以下脚本:

 #!/usr/bin/python from pymouse import PyMouseEvent from pykeyboard import PyKeyboard k = PyKeyboard() class MouseToButton(PyMouseEvent): def click(self, x, y, button, press): if button == 8: if press: # press k.press_key(k.control_l_key) else: # release k.release_key(k.control_l_key) C = MouseToButton() C.run() 

在给脚本执行权限之后,我用~/.xsessionrc的一行来调用它

〜/ path / to / script.py&

注意 。 这不会阻止鼠标按钮事件触发。 在我的例子中,我使用xinput set-button-map来更改xinput按钮映射,并将我感兴趣的按钮的编号分配给未使用的按钮。

例如,如果要在鼠标上使用按钮8但按钮8已经有一个function(例如, page-next ),则可以使用以下.xsessionrc

 logitech_mouse_id=$(xinput | grep "Logitech M705" | sed 's/^.*id=\([0-9]*\)[ \t].*$/\1/') xinput set-button-map $logitech_mouse_id 1 2 3 4 5 6 7 12 9 10 11 12 13 14 15 16 17 18 19 20 ./.xbuttonmodifier.py & 

提供的按钮12对OS没有任何意义,并且在.xbuttonmodifier.py (上面描述的脚本)中为按钮12分配自定义function。

我有部分解决方案。 我还没有想出如何取消映射现有按钮,因此您最终只需单击按钮和所需的修改器。 因此,如果该鼠标按钮有一些现有的用途,它仍然会触发。 例如,将鼠标右键重新映射到控制键将导致发送控件+单击。

无论如何,我找到了一个类似于你的问题的论坛post,答案是安装btnx并通过它配置你的修饰符。 似乎通过回购不再提供btnx。 有一个ppa,但它不适用于最新的ubuntu。

论坛post:post: http : //ubuntuforums.org/showthread.php?t = 1245930

但是来源可用:

您可以从源代码编译它,但这会将您的文件放在包管理器无法维护的系统上。

即,以下文件:

 /usr/local/sbin/btnx /etc/init.d/btnx /usr/share/pixmaps/btnx.png /usr/share/btnx-config (directory, multiple files) /usr/share/applications/btnx-config.desktop /usr/share/omf/btnx-config/btnx-manual-C.omf /usr/share/locale/de/LC_MESSAGES/btnx-config.mo /usr/share/locale/fr/LC_MESSAGES/btnx-config.mo /usr/share/locale/nl/LC_MESSAGES/btnx-config.mo /usr/share/locale/ru/LC_MESSAGES/btnx-config.mo 

以下符号链接:

 /etc/rc0.d/K49btnx -> ../init.d/btnx /etc/rc1.d/K49btnx -> ../init.d/btnx /etc/rc6.d/K49btnx -> ../init.d/btnx /etc/rc2.d/S49btnx -> ../init.d/btnx /etc/rc3.d/S49btnx -> ../init.d/btnx /etc/rc4.d/S49btnx -> ../init.d/btnx /etc/rc5.d/S49btnx -> ../init.d/btnx 

那么……如果你不介意从源头构建……

获取btnx的依赖项:

 sudo apt-get install libdaemon-dev git 

如果你从未在源代码中构建任何东西,那么你可能也需要build-essential:

 sudo apt-get install build-essential 

然后获取并编译btnx:

 git clone https://github.com/cdobrich/btnx cd btnx ./configure make sudo make install cd - 

它有一个单独的GUI配置工具。 获取它的依赖项:

 sudo apt-get install libgtk2.0-dev libglade2-dev 

现在获取并编译gui配置工具:

 git clone https://github.com/cdobrich/btnx-config ./configure make sudo make install 

现在运行该工具:

 sudo btnx-config 

单击“检测鼠标按钮”如果您希望在使用该工具时能够读取方向,请调整弹出的窗口的大小,如果不这样,对话框文本会被剪切,如果您在检测期间尝试resize,它将取消检测。 只需将窗口放大一点。

单击按下开始鼠标检测,然后尝试不移动鼠标直到文本更改…大约需要5-10秒。 文字会改变。 如果是,请忽略它所说的内容并单击“前进”。

单击“按下以开始按钮检测”按钮

在这里,您将多次单击鼠标的一个按钮(直到状态栏填满)。 然后将按钮的名称设置为稍后将识别的内容(例如:LeftButton)单击“添加”按钮。

对每个鼠标按钮重复此操作(不要忘记滚轮,滚动点击等)。 您可以跳过任何不想重新映射的按钮。

添加完所有按钮后,单击“确定”。

在主GUI中,单击按钮,在左侧窗格中选择要重新映射的按钮。 它将使用您在前面的步骤中输入的名称。 出于您的目的,您只需在右侧的“键组合”下选择“键”修改器。

不要在此屏幕上单击“删除”,它将删除该按钮。 如果你这样做,你将不得不再回过头来检测按钮。

返回Conrigurations屏幕,然后单击restart btnx。

试试新按钮。

如果要卸载应用程序,请停止btnx程序,然后进入相应的git签出目录并进行卸载:

 sudo /etc/init.d/btnx stop cd btnx sudo make uninstall cd - cd btnx-config sudo make uninstall cd -