如何使用xbindkeys将修饰符(例如CTRL)映射到鼠标拇指按钮


13

已经问过这个问题,但从未得到正确回答。与@Seth许可后,我现在再次询问。这将使我能够做出响应,并且可能更容易地修改问题。原始问题可以在这里找到:

将Ctrl和Alt映射到鼠标拇指按钮


问题:

虽然这是非常简单的任何按键动作映射到使用鼠标按钮xbindkeys会同xdotoolxte似乎多了很多问题映射一个修改键(如ALTCTRLSHIFT等)给它。

最后的解决方案应该允许仅用鼠标CTRL + 单击(例如,用于选择列表的多个条目)。

可以在Stack Exchange以及其他Linux相关论坛上找到解决此问题的两种可能方法。但是这些都不起作用,因为它们会导致其他问题和副作用。

笔记:

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

此外,下面的代码片段xdotool仅依靠,但是我也乐于使用涉及其他应用程序的方法,例如xte-尽管看起来两者都能导致相同的结果,所以我在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和测试xbindkeys -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

太简单了...但是会导致无限点击。


更新:

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

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


1
这是使用Easystroke的解决方案:askubuntu.com/a/1010647/27202
atti

Answers:


8

我花了很多时间试图使绑定生效。我最终找到了一个解决方案,该解决方案很复杂,但是效果很好,并不意味着第三方软件。我在这里分享它,希望对人们有所帮助。此外,我知道这在安全性方面不是完美的,因此任何建设性的反馈都值得欢迎。

有一些解决方案真的很不错,就像这里提出的解决方案一样,但是它总是受到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

对于uinput:

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

无需符号链接,uinput始终位于$/dev/uinput$/dev/input/uinput取决于您所使用的系统。只要给他这个小组和阅读和写作的权利即可。

您需要拔出电源-插入鼠标,新链接应显示在/ dev中。您可以通过以下方式强制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库(显然)和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按钮一起使用现在都可以与其中一只鼠标一起使用!


非常感谢您的努力,并与我们分享!+1 ...尽管我还没有测试过。顺便说一句,我几乎已经放弃了这一点-如果能按预期工作,那就太好了:)
conceptdeluxe

别客气 !对我来说,它完美无瑕。如果您有麻烦,请告诉我。我尝试使答案完整,但是由于我花了将近两天的时间使它起作用,所以我可能忘记了一些东西。乐于帮助/编辑我的帖子。
的Aurelien Cibrario

我只是意识到ctrl + click1是关闭标签的非常糟糕的选择,因为它会在新标签页中打开链接。我编辑了答案,删除了python脚本的最后一部分,并使用更清洁的解决方案xbindkeys进行了调整
的Aurelien Cibrario

只是想让您知道,我还没有时间对其进行测试-但如果可以按预期工作,我可以确定使其成为可接受的答案-抱歉,等待-我有点忙于atm
conceptdeluxe

我想知道我们是否可以使用上面的脚本来消除错误的鼠标开关。我有一只破旧的鼠标。我使用自动热键脚本在Windows中修复它,但是没有在Linux中修复它的工具。这是用于左键修复的Autohhotkey脚本 autohotkey.com/board/topic/63555-debounce-mouse-keys 我希望有人移植到Linux上使用python3 -了evdev
KENN

4

我找到了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已经具有功能(例如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,并分配一个自定义函数来按钮12.xbuttonmodifier.py,我上述脚本。


但这并不能阻止原始事件的触发。因此,如果我将按钮8映射到Shift,并在Firefox中按住按钮8,它也会尝试返回到上一页,这是不可取的。
user23013

1
真正。为了解决这个问题,我使用了将我感兴趣的按钮的id更改为中的一个已使用的按钮xinput。参见编辑后的问题。
Maxim

2

我有部分解决方案。我还没有弄清楚如何取消现有按钮的映射,因此最终需要单击按钮和所需的修饰符。因此,如果该鼠标按钮具有某些现有用途,它将仍然会触发。例如,将鼠标右键重新映射到控制键将导致发送Control +单击。

无论如何,我发现了一个与您的问题类似的论坛帖子,针对该帖子的答案是安装btnx并通过它配置修改器。看来btnx不再可以通过仓库使用。有ppa,但不适用于最新的ubuntu。

论坛帖子: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

如果您从未从源代码构建任何东西,那么您可能还需要构建必需的东西:

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 config工具:

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

现在运行该工具:

sudo btnx-config

单击“检测鼠标按钮”。如果您希望在使用该工具时能够阅读说明,请调整弹出窗口的大小,如果不这样做,对话框文本将在以后被裁剪,如果您在检测过程中尝试调整大小,它将被取消。检测。只是使窗口大一点。

单击“按下”以开始鼠标检测,然后尝试直到文本更改后才移动鼠标。大约需要5到10秒钟。文本将更改。如果出现这种情况,请忽略其内容,然后单击“前进”。

点击“按下开始按钮检测”按钮

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

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

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

在主GUI中,单击“按钮”,在左窗格中选择要重新映射的按钮。它将使用您在先前步骤中输入的名称。为了您的目的,您只想在右侧的“组合键”下选择一个“键”修饰符。

不要在此屏幕上单击删除,它将删除按钮。如果需要,您必须返回并再次检测该按钮。

返回到“配置”屏幕,然后单击重新启动btnx。

试用新按钮。

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

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

2
非常感谢您在pastebin发布的详细答案。但是我担心,如果不在我的设备上进行详细检查,则不允许使用不受信任的PPA或从未知来源构建应用程序。不过,我会为您付出的努力投赞成票。除此之外,我建议您在此处更新您的答案并复制您在此处写的内容,因为此信息可能对其他人有帮助,但可能会被忽略。最后,我读到该软件包甚至可能无法在Ubuntu或Debian下编译-您是否真的尝试过?
conceptdeluxe 2015年

顺便说一句:通过将您的askubuntu帐户与其他Stack Exchange帐户(例如Linux和Unix)进行链接,您可以轻松获得额外的100个声望。
conceptdeluxe 2015年

是的,我在Ubuntu 14.04下进行了测试。我使鼠标右键发送了一个控制键,并在发布前确认它可以正常工作。然后由于声誉要求几乎放弃了这个职位。
斯蒂芬
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.