当前位置: 首页>>技术教程>>正文


如何在启动时自动重新映射鼠标上的按钮?

, , ,

问题描述

我周末一直在努力解决这个问题,需要重新映射我的鼠标按钮。

最佳方法

我有一个带有 9 个按钮的 Logitech 鼠标,按下 “middle button” (#2) 需要点击滚轮。我不喜欢这样,因为我很笨拙,当我尝试点击滚轮时,通常会滚动我所在的窗口。所以我想自动将顶部按钮(本例中为 #9)重新映射到中间按钮(#2)。我还想映射底部按钮(#8),以便它执行双击左键(#1)。

虽然我的目的很具体,但下面的解决方案可以推广到您想要在启动时自动重新映射鼠标按钮的任何情况。

将鼠标按钮映射到其他鼠标按钮

您需要安装 xinput 才能完成此任务。这可以完全在 .xsessionrc 文件中完成。首先,使用 xinput 来发现分配给鼠标的名称,然后将其与输入设备 ID 关联。以下是我的笔记本电脑的一些示例输出:

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer            id=4    [slave  pointer  (2)]
⎜   ↳ Logitech USB Laser Mouse              id=11   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard           id=5    [slave  keyboard (3)]

我的鼠标自称 Logitech USB Laser Mouse ,显示为 id=11 。您的鼠标将具有不同的名称;弄清楚这一点留给读者作为练习。

当您仍然知道此会话中设备的 ID 时,请使用 xinput list deviceID 找出输入处理程序认为您的鼠标有多少个按钮。这可能与设备上显示的按钮数量不同。

Logitech USB Laser Mouse                    id=11   [slave  pointer  (2)]
    Reporting 7 classes:
        Class originated from: 11. Type: XIButtonClass
        Buttons supported: 16
        Button labels: "Button Left" "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right" "Button Side" "Button Extra" "Button Forward" "Button Back" "Button Task" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown"

我的鼠标只有 9 个明显的物理按钮,但 xinput 报告有 16 个。

鉴于 USB 的特性,此 ID 每次重新启动时都会发生变化,因此仅编写静态键入您一次发现的 ID 的脚本是不够的。您必须在启动时动态解析它并根据当前 ID 执行您的 re-map。

现在您知道了它的名称,您可以使用 xinput test deviceID 来确定要重新映射哪个键。按下要从其映射的鼠标按钮,以获取它们的索引。(作为参考,1、2 和 3 “always”(即通常)指的是 3 键鼠标的左键、中键和右键。常见的 re-map 将这些按钮反转,使鼠标成为 left-handed。)

button press   2
button release 2
button press   9
button release 9

在这种情况下,我发现我想将按钮#9(侧面,顶部)映射到按钮#2(中间)。

现在您知道了鼠标的名称以及要更改哪些按钮,您可以编写一个 ~/.xsessionrc 脚本,该脚本调用 xinput 在启动时执行按钮 re-mapping。以下是我的完整脚本。

# Map button 9 (top side button) to button 2 (middle button)
my_mouse_id=$(xinput | grep -m 1 "Logitech USB Laser Mouse" | sed 's/^.*id=\([0-9]*\)[ \t].*$/\1/')
echo $my_mouse_id > ~/temp/my_mouse_id
xinput set-button-map $my_mouse_id 1 2 3 4 5 6 7 8 2 10 11 12 13 14 15 16

此处的第一行设置了一个临时会话变量,该变量等于 xinput 报告的鼠标 ID。这是通过 grep 查找来自 xinput 的报告中鼠标的已知名称,然后使用 sed 从报告中的 id=xxx 标记中提取 ID 号来实现的。然后,此值用于 xinput set-button-map 指令,该指令执行 re-mapping。在上面的示例中,唯一的变化是按钮 #9 被 re-mapped 模仿按钮 #2。所有其他按钮均保持其默认设置。

更新:正如@Lokasenna 指出的 below ,如果您的设备将自己报告为鼠标和键盘,则可能需要使用 -m 1 来限制 grep 的结果计数。如果鼠标没有将自己报告为两者,这不会造成问题,因此它已包含在脚本中。

将鼠标按钮映射到任意功能

另请参阅 this answer

为此任务,您需要安装 xinputxbindkeysxautomation(包括 xte)。

使用 xinput listxinput test 来查找鼠标的设备 ID 和要分配的按钮编号。就我而言,我想将底部按钮 (#8) 映射到双击左键 (#1)。

创建或编辑 ~/.xbindkeysrc 。此文件的格式是一系列成对的行。第一行是针对事件执行的命令;第二行是事件描述。我们将使用 xautomationxte 组件将事件直接发送到输入处理程序。

为了在释放按钮时创建双击事件,我添加了以下内容:

"/usr/bin/xte 'mouseclick 1' 'mouseclick 1' &"
b:8 + Release

此配置将鼠标单击按钮 #1 两次的序列映射到释放按钮 #8。(理论上,我猜你可以将任何命令映射到鼠标按钮,但这是最常见的情况。有关其他实际示例,请参阅 this answer。)

针对 16.04 Ubuntu 的更新

对于系统上连接了多个鼠标的用户,您还需要传入设备的 ID。这可能不适用于所有用户,并且是在使用 Unity 的 Ubuntu 16.04 上发现的。

xinput list

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Kensington      Kensington Expert Mouse   id=9    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=13   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     id=14   [slave  pointer  (2)]

然后通过引用命令输出中的 id= 值来修改 .xbindkeysrc 文件(此示例中为 id=9):

"/usr/bin/xte -i 9 'mouseclick 1' 'mouseclick 1' &"
b:8 + Release

次佳方法

简要步骤如下:

有一个名为 xinput 的实用程序。xinput listxinput 将显示所有 X 输入设备及其 ID。在这里您可以找到要重新映射的鼠标的 ID。

我将使用我的 ID 作为示例,从我的设置来看,它是 21,然后 xinput --get-button-map 21 将输出

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

现在,如果你想交换左右按钮,只需运行

xinput --set-button-map 21 3 2 1

到这里,重新映射已经完成。

要在启动时运行它,只需将其放入文件中:

echo "xinput --set-button-map 21 3 2 1" > leftmouseremap.sh

赋予它可执行权限

chmod +x leftmouseremap.sh 

最后,从 GUI 手动将其添加到 Statrtup Application,或者,如果您希望从 CLI 添加到 Statrtup Application,请将下面的文本(将路径更改为您的路径)放入 ~/.config/autostart 中的文件中,这是我的(less .config/autostart/leftmouseremap.sh.desktop):

[Desktop Entry]
Type=Application
Exec=/home/ruslan/leftmouseremap.sh
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_US]=/home/ruslan/leftmouseremap.sh
Name=/home/ruslan/leftmouseremap.sh
Comment[en_US]=
Comment=

请记住,对于 KDE,路径应该类似于 ~/.kde/Autosart ,对于其他桌面管理器,路径可能略有不同。或者,可以使用 /etc/rc.local 以常规方法进行启动运行。

第三种方法

使用 zerobandwidth’s great answer 时,某些设备(例如 Logitech 的 MX Ergo)会同时显示为指针和键盘设备:

⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech MX Ergo                          id=10   [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=14   [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ...
    ↳ Logitech MX Ergo                          id=15   [slave  keyboard (3)]

因此,grep "Logitech MX Ergo" 最终返回两个值。后者最终被包含在映射字符串中作为第一项,并搞砸了所有鼠标按钮。

修复很简单 – 只需使用 grep 的 maximum-count 参数 -m 1

my_mouse_id=$(xinput | grep -m 1 "Logitech MX Ergo" | sed 's/^.*id=\([0-9]*\)[ \t].*$/\1/')
echo $my_mouse_id > ~/temp/my_mouse_id
xinput --set-button-map $my_mouse_id 1 2 3 4 5 6 7 8 2 10 11 12 13 14 15 16

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/14561.html,未经允许,请勿转载。