27

I use a 10-button mouse (Logitech M705). Under X11, I was able to configure one of the extra buttons to behave as a second middle-click by modifying files in etc/X11/xorg.conf.d.

Under Wayland, this no longer works. My research shows that I need to do something with libinput. I thought this would be a common problem but can't find an answer anywhere.

Can someone explain how to remap mouse buttons or explain why it can't be done?

3
  • I'm using Wayland for a while and I couldn't find how to remap buttons so far. May 24, 2017 at 14:21
  • If you want to remap your keyboard keys or mouse buttons to certain keys, use "Input Remapper" by sezanzeb. It's VERY simple, it has a GUI, and it just WORKS. I just have set a certain shortcut to simulate a keyboard key, works well.
    – Allexj
    Jan 7 at 12:56
  • I agree, which is why Input Remapper (formerly Key Mapper) is the accepted answer below.
    – Kyle
    Jan 13 at 19:27

5 Answers 5

15

I've spent 2 days googling, testing tens of methods I've found and struggling with remapping mouse buttons under Wayland...

So sharing what I've learned:

Logitech M570 trackball has 2 extra buttons. They produce BTN_SIDE a BTN_EXTRA in libinput:

[root@centos8 ~]# libinput debug-events --device /dev/input/event21
-event21  DEVICE_ADDED     Logitech M570                     
      seat0 default group1  cap:p left scroll-nat scroll-button
 event21  POINTER_BUTTON   +16.93s      BTN_EXTRA (276) pressed, seat count: 1
 event21  POINTER_BUTTON   +17.09s      BTN_EXTRA (276) released, seat count: 0
 event21  POINTER_BUTTON   +17.89s      BTN_SIDE (275) pressed, seat count: 1
 event21  POINTER_BUTTON   +17.99s      BTN_SIDE (275) released, seat count: 0

You can check it using evtest which will also show button scancodes:

[root@centos8 ~]# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
...
/dev/input/event21: Logitech M570
Select the device event number [0-21]: 21
Event: time 1589974995.415405, -------------- SYN_REPORT ------------
Event: time 1589974996.969613, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90004
Event: time 1589974996.969613, type 1 (EV_KEY), code 275 (BTN_SIDE), value 1
Event: time 1589975000.165574, -------------- SYN_REPORT ------------
Event: time 1589975000.611570, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90005
Event: time 1589975000.611570, type 1 (EV_KEY), code 276 (BTN_EXTRA), value 1
Event: time 1589975002.369616, -------------- SYN_REPORT ------------

Now create a rule file for udev hwdb to remap scancodes to desired buttons, e.g. /etc/udev/hwdb.d/70-mouse-remap.hwdb:

# remap buttons on Logitech M570 trackball
evdev:name:Logitech M570:*
 ID_INPUT_KEY=1
 KEYBOARD_KEY_90004=btn_middle
 KEYBOARD_KEY_90005=btn_middle

Yes, the buttons are really mapped as keyboard key scancodes back to mouse middle button. Do not use too general device identifier like evdev:input:* because it may interfere with you other devices, e.g. on my Thinkpad T490 it breaks mic mute button (Fn+F4).

Save the file and rescan hwdb

[root@centos8 ~]# systemd-hwdb update

I had also to physically unplug the mouse (wireless receiver in this case) from USB to see the changes. Plug it back and check that rules are applied:

[root@centos8 ~]# udevadm info /dev/input/event21
P: /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4/1-4.4:1.2/0003:046D:C52B.0097/0003:046D:1028.0098/input/input84/event21
...
E: KEYBOARD_KEY_90004=btn_middle
E: KEYBOARD_KEY_90005=btn_middle

Now you can test libinput again and you should see both buttons generate BTN_MIDDLE event:

[root@centos8 ~]#  libinput debug-events --device /dev/input/event21
-event21  DEVICE_ADDED     Logitech M570                     seat0 default group1  cap:kp left scroll-nat scroll-button
 event21  POINTER_BUTTON    +1.45s  BTN_MIDDLE (274) pressed, seat count: 1
 event21  POINTER_BUTTON    +1.59s  BTN_MIDDLE (274) released, seat count: 0
 event21  POINTER_BUTTON    +2.20s  BTN_MIDDLE (274) pressed, seat count: 1    
 event21  POINTER_BUTTON    +2.28s  BTN_MIDDLE (274) released, seat count: 0

If everything is ok, you should be able to paste with both extra buttons in Wayland native application like gnome-terminal.

Enjoy.

4
  • 1
    Thank you, there is a lot of helpful information in this answer. I want to point out, since it wasn't immediately obvious to me, that this answer explains how to remap a mouse button so that Wayland sees different input events, whereas the wayland-mouse-mapper answer observes Wayland input events and uses evemu to emit additional, different events.
    – sjy
    Sep 13, 2020 at 3:30
  • 1
    I don't get why it is KEYBOARD_KEY_90004 instead of BTN_SIDE, and what is ID_INPUT_KEY=1 here. Could you please explain it?
    – fikr4n
    Sep 22, 2022 at 5:28
  • Thank you very much for this, worked perfectly.
    – David Rios
    Dec 13, 2022 at 18:14
  • If you want to remap your keyboard keys or mouse buttons to certain keys, use "Input Remapper" by sezanzeb. It's VERY simple, it has a GUI, and it just WORKS. I just have set a certain shortcut to simulate a keyboard key, works well.
    – Allexj
    Jan 7 at 12:57
11

There is a graphical way to do this now. All of the command-line solutions hurt. The GUI program I found is called Key Mapper and it works for X11 and Wayland. It uses root privileges and solves all of the problems:

  • Install the program such as the deb package from the releases page on GitHub (or as mentioned in the article below, there is also an AUR package for arch-based distros or you can use pip).
  • Open Key Mapper
  • Choose the mouse you want.
  • Click "click here"
  • Click the button you want to change (If it gets stuck on "press key", first follow the instructions in the bottom popup to "Restore Defaults"--apply your changes from any previous mappings and the Restore Defaults button won't remove them).
  • After it accepts your button, the name of the button will appear in the left column. Then you can click the right column and start typing the what you want the button to do. For example, I wanted the Logitech Marble Mouse side button I clicked in the previous step to become middle click, so I started typing "middle" then chose "BTN_MIDDLE".
  • It worked instantly after clicking "Apply"!

I found this by searching for: mouse button mapping gui ubuntu

The article I found says some more about it: Remap Keyboard And Mouse Buttons On Linux With The New Key Mapper GUI (Supports X11 And Wayland) February 23, 2021 on Linux Uprising

2
  • It doesn't seem to stay mapped after a reboot on Xubuntu 20.04 (Focal) using Key Mapper 1.0.0. The Key Mapper team knows about this and the issue is tracked here (The issue notes possible workarounds): github.com/sezanzeb/key-mapper/issues/154
    – Poikilos
    Aug 11, 2021 at 13:40
  • 2
    Now it is called input remapper, and it's available in Ubuntu's 22.04 software sources.
    – Didi Kohen
    Dec 12, 2022 at 15:59
8

Remapping buttons if you're running Wayland could be done like this:

  1. Run xev | grep button to log mouse click events and get the number of the event by f.e clicking in the window. In my case, middle button is:

    state 0x10, button 2, same_screen YES
    

    and I want to map it on:

    state 0x10, button 13, same_screen YES
    
  2. Then run xinput --list and find your pointer device, mine is:

    Logitech Performance MX  id=9  [slave pointer  (2)]
    
  3. xinput get-button-map 9 returns:

    1 2 3 4 ... 20
    
  4. xinput set-button-map:

    $ xinput set-button-map 9  1 13 3 4 .. 12 2 14 .. 20
    

NOTE: replace the number 9 for the number returned by id=

And if that key's behavior is defined, your event is mapped. If it is not, that's a little bit different issue. Under Wayland TBH I haven't found a way for executing a command on an event (which is pretty easy with Xorg's xbindkeys) and therefore fully customizing behavior of key and mouse event.. I believe Wayland is trying to be more secure and disables this behavior.

In any case, you still have the opportunity to switch to Xorg pretty easily and enjoy the functionality.

5
  • Worked for me, but how do you make the change permanent? Seems I have to run xinput set-button-map for each new Wayland session...
    – mgalgs
    Nov 30, 2017 at 5:21
  • 1
    Yes, you need to run it every time. To automate this, you can put this in a script and create a service file, or put this in an init folder that is ran at startup corresponding to your distro (on systemd-based OS that would be /etc/rc.d/init.d/)
    – CermakM
    Dec 1, 2017 at 6:58
  • You can put an option in xconf files: Option "ButtonMapping" "1 2 3 ..." Jul 9, 2018 at 11:29
  • 3
    This only changes the xorg input driver, not any applications that natively use wayland composition, like Gnome Shell or Nautilus
    – Ray Foss
    Apr 26, 2019 at 19:55
  • This should not be the accepted answer. It does not change the configuration of the Wayland environment.
    – sjy
    Sep 11, 2020 at 7:24
5

I made a small shell script + systemd unit file I call wayland-mouse-mapper.

excerpt mathportillo/wayland-mouse-mapper

A small script for mapping mouse buttons to keystrokes on Wayland.

I made for myself to use my mouse extra buttons for useful stuff. It's tested and works with Logitech MX Master 2S on Fedora 27 using Gnome, and works it on my old Logitech Performance MX too. It probably works on any Wayland and Any Logitech mouse (or any mouse if you edit mappings) because no other method (xdotools, xbindkeys, etc.) seemed to work.

It works by reading from libinput debug-events and triggering key events using evemu depending on the recognized button from the recognized device.

Buttons

These are just the default settings, you can customize them at the start of the mousemapper.sh script.

  • Forward: Move to workspace above (Super+Page up)
  • Back: Move to workspace below (Super+Page down)
4
  • Thank you for sharing this script! I see that it works by parsing the output of libinput debug-events. Has this been reliable in your experience? I am wondering if this could be used to handle high frequency scroll events or if a more efficient solution is needed.
    – sjy
    Sep 11, 2020 at 7:29
  • 1
    @sjy I reckon that extremely high frequency events probably wont skip but can stack, resulting in lag. It is specially likely to happen if you map it to a button that triggers something that does not handle repeated events. However, this problem happens in the layer outside mapping. There is for sure more efficient solutions of mapping, as reading SO binary input buffer, but if you do so you are still subject to the same thing. The point is that although there is more efficient ways, this is not the bottleneck (at least for common interface mapping). Sep 15, 2020 at 0:01
  • Thanks, I think I will give this a try! I notice that it is also available via the wayland-mouse-mapper-git AUR package.
    – sjy
    Sep 15, 2020 at 0:04
  • @sjy another way to answer is that there is already a absolutely ridiculous amount of libinput events being filtered out and scrolling as fast as you can probably wont be more than 10% of those, so if there was a performance issue, it would be in "trigger" part of mapping, not in the reading, and a better way of reading events wouldn't solve this. And the trigger part (cli command with evemu) is not the bottleneck when talking about any commom GUI event, so a better way to trigger wouldnt solve it too. Sep 15, 2020 at 0:11
3

Try modifying the hwdb udev rules. This registers the mouse buttons as a keyboard key such as Launch8/F16 and disables their functionality in all programs, wayland or otherwise.

# /usr/lib/udev/hwdb.d/71-mouse-local.hwdb

evdev:input:*
 KEYBOARD_KEY_90004=key_f16
 KEYBOARD_KEY_90005=key_f17

then as root systemd-hwdb update; udevadm trigger and unplug the mouse then plug it back in.

Additional sanity check: sudo udevadm info /dev/input/by-path/*-usb-*-mouse | grep -A3 -P3 KEYBOARD_KEY, or query it as such systemd-hwdb query "evdev:input:v046dp406a* see source for details on pulling the id.

Source: https://yulistic.gitlab.io/2017/12/linux-keymapping-with-udev-hwdb/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .