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

zer*_*dth 42 mouse xinput xte xbindkeys

周末我为此苦苦挣扎,需要重新映射我的鼠标按钮。

zer*_*dth 63

我有一个带有 9 个按钮的 Logitech 鼠标,按下“中间按钮”(#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)]
Run Code Online (Sandbox Code Playgroud)

我的鼠标自称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"
Run Code Online (Sandbox Code Playgroud)

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

鉴于 USB 的性质,每次重新启动时此 ID 都可能更改,因此仅编写一些静态键控到您一次发现的 ID 的脚本是不够的。您必须在启动时动态解析它并根据当前 ID 执行重新映射。

现在您知道了它的名称,您可以使用它xinput test deviceID来确定要重新映射的键。按下你想要映射的鼠标按钮,以获得它们的索引。(作为参考,1、2 和 3“总是”(即通常)指的是 3 键鼠标的左键、中键和右键。常见的重新映射将这些颠倒过来,使鼠标成为左手使用。 )

button press   2
button release 2
button press   9
button release 9
Run Code Online (Sandbox Code Playgroud)

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

既然您知道鼠标的名称以及要更改的按钮,您就可以编写一个~/.xsessionrc脚本,xinput在启动时调用以执行按钮重新映射。下面是我的完整脚本。

# Map button 9 (top side button) to button 2 (middle button)
my_mouse_id=$(xinput | grep "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
Run Code Online (Sandbox Code Playgroud)

此处的第一行设置了一个临时会话变量,该变量等于 报告的鼠标 ID xinput。这是通过grep从 中获取报告中鼠标的已知名称xinput,然后使用sedid=xxx报告中的该标记中提取 ID 号来完成的。然后在xinput set-button-map执行重新映射的指令中使用该值。在上面的示例中,唯一的变化是按钮 #9 被重新映射为模拟按钮 #2。所有其他人保持其默认设置。

更新:正如@Lokasenna 在下面指出的那样,如果您的设备将自己报告为鼠标和键盘,您可能需要限制grepusing的结果计数-m 1

将鼠标按钮映射到任意函数

另请参阅此答案

你需要xinputxbindkeysxautomation(包括xte)安装了这个任务。

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

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

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

"/usr/bin/xte 'mouseclick 1' 'mouseclick 1' &"
b:8 + Release
Run Code Online (Sandbox Code Playgroud)

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

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)]
Run Code Online (Sandbox Code Playgroud)

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

"/usr/bin/xte -i 9 'mouseclick 1' 'mouseclick 1' &"
b:8 + Release
Run Code Online (Sandbox Code Playgroud)

  • 谢谢提供信息。您的 awk 看起来需要根据设备中的字数进行更改。我使用了`sed 's/^.*id=\([0-9]*\)[ \t].*$/\1/'` (7认同)
  • 不需要在 set-button-map 中使用 id;例如:`xinput set-button-map "Logitech Trackball" 1 3 3` (2认同)

Rus*_*mov 8

简短的步骤是:

有一个实用程序叫做xinput. xinput list或者只是xinput将显示所有 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
Run Code Online (Sandbox Code Playgroud)

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

xinput --set-button-map 21 3 2 1
Run Code Online (Sandbox Code Playgroud)

到这里,重新映射就完成了。

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

echo "xinput --set-button-map 21 3 2 1" > leftmouseremap.sh
Run Code Online (Sandbox Code Playgroud)

给它可执行权限

chmod +x leftmouseremap.sh 
Run Code Online (Sandbox Code Playgroud)

最后,从 GUI 手动将其添加到 Statrtup 应用程序中,或者,如果您希望从 CLI 中添加,请将下面的文本(更改您的路径)放入您的文件中~/.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=
Run Code Online (Sandbox Code Playgroud)

请记住,使用 KDE 时,路径类似于~/.kde/Autosart,对于其他桌面管理员来说,这可能略有不同。或者,可以使用一般方法来完成启动运行/etc/rc.local


小智 6

使用zerobandwidth 的好答案时,某些设备(例如 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)]
Run Code Online (Sandbox Code Playgroud)

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

修复很简单 - 只需使用grep的最大计数参数,-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
Run Code Online (Sandbox Code Playgroud)