8

Using Linux Mint 18.1, I've remapped some mouse and keyboard keys using 'xinput' (command below). When I disconnect the mouse and reconnect it, the xinput command must be re-run manually.

I had read that adding them to ~/.xsessionrc is the right thing to do. As you can see I've done that. I've also tried ~/.xinputrc. It'll run once on bootup, but if I disconnect and reconnect the mouse, or sleep the computer, I need to re run the xinput command manually.

Anyone know the right way to keep these commands always active? E.g. how can I make them persist across a device disconnect/reconnect?

davidparks21@ghostmint ~ $ cat .xsessionrc
# Map mouse button 8 (top right) to button 2 (top left) and vice versa
xinput --set-button-map 10 1 8 3 4 5 6 7 2 9 10 11 12

# Fix numeric keypad for shift-home and shift-end
setxkbmap -option numpad:microsoft
4
  • .xsessionrc runs each time you log in in graphic mode. Do you log in and back out, or do the settings change during a session? Did you disconnect or connect an input peripheral? Commented Dec 25, 2016 at 0:05
  • 1
    Besides running the commands in .xsessionrc (check your display manager (gdm/kdm/xdm/lightdm/... if it's configured to run this), you can also add a configuration in xorg.conf for the same effects.
    – dirkt
    Commented Dec 25, 2016 at 8:55
  • I'm quite perplexed by this now. I've been through many reboots, suspends, etc. For many days it seemed to work perfectly, I even deleted this post thinking I was crazy. But then it occurred again. I had to run the commands manually because the mouse buttons weren't remapped. The cases of this happening appear random to my eyes, at least so far. The only interesting action happening in the last occurrence was basic screen locking and unlocking. Though this happens often without issue. So as of now this is a transient issue. I'll post here if/when I figure it out. Commented Dec 27, 2016 at 18:01
  • 2
    may be a duplicate of unix.stackexchange.com/questions/65891/…
    – netmonk
    Commented Jan 26, 2017 at 15:18

4 Answers 4

1
+50

You can run this script, after plugging, or unplugging usb device, code will execute:

while true; do state=$(lsusb) && sleep 2 && [[ $state != $(lsusb) ]] && echo "Change detected, replace echo with your command"; done
4
  • I didn't know about lsusb, this is the best hack I've seen for the problem. Commented Jan 27, 2017 at 16:36
  • This is still problematic if you are trying to use your mouse intensively (e.g. in a game) and it changes for two seconds before this script fixes it. It would be nice to hook into the USB detection for when it gets disconnected. Commented Apr 22, 2019 at 18:54
  • I think udev is the application that needs to be interacted with to do it right. Commented Apr 22, 2019 at 19:14
  • I hacked together a udev monitoring program and made it an answer. Commented Apr 22, 2019 at 22:23
1

Here's my final solution, I corrected an extremely unlikely and non critical race condition in Nir's answer. Also I handle the fact that I can't remap the keys when the mouse is unplugged (no error messages while it's unplugged).

I added to ~/.xinitrc:

# Map mouse button 8 (top right) to button 2 (top left) and vice versa, run when changes to the mouse occur
while true; do
  NEW_MOUSEID=$(xinput | grep "Expert Mouse" | grep -o -E '[0-9]+' | head -n 1)
    if [ "$MOUSEID" != "$NEW_MOUSEID" ]; then
      MOUSEID=$NEW_MOUSEID
      if [ "$MOUSEID" != "" ]; then
        xinput --set-button-map $MOUSEID 1 8 3 4 5 6 7 2 9 10 11 12
      fi
  fi
  sleep 2
done &

I used the mouse ID parsed from xinput as the trigger instead of lsusb, but it's has the same effect.

Note that the pipes after the xinput command just parses the ID of the mouse, which can change. The extra NEW/OLD mouse ID's were an anal avoidance of any possibility of a race condition.

Thanks @Nir for the suggestion.

2
  • 1
    I used this same approach because like you I couldn't find anything better. Seems like there should be a "right way", but what?
    – user207863
    Commented Jan 1, 2018 at 19:04
  • Line with reading id of device should be changed to this (When you have device with a number in it's name: NEW_MOUSEID=$(xinput | grep "Expert Mouse" | grep -o -E 'id=[0-9]+' | grep -o -E '[0-9]+' | head -n 1)
    – Morph21
    Commented Oct 8, 2020 at 7:01
0

For what is worth:
You can use ~/.xsession file, rather than ~/.xsessionrc.

~/.xsessionrc is Debian-specific, while ~/.xsession is UNIX-like and have a similar behaviour across all the distros.

1
  • 1
    I appreciate the note, though maybe better as a comment as it doesn't address the crux of the question, how to make the xinput command I placed in those file persist across USB disconnect/reconnect. Commented Jan 25, 2017 at 18:16
-2

Loading configuration files on startup all depends on what desktop environment is being used. If you were start your xserver by typing startx that will normally indicate that it will use .xinitrc (stored in $HOME).

Within .xinitrc you will have to load the config that has the different mappings, i.e .xsessionrc

Then line you will need is this (in .xinitrc)

xrdb -merge ~/.xsessionrc 

However, if you are using a login manager such as LightDM or GNOME you will have to find the same equivalent

2
  • 1
    Does this address when the USB mouse is disconnected and reconnected? Commented Jan 25, 2017 at 16:38
  • @DavidParks This does not no, only starting your config files on boot. Easy way to hack it would be to make a bash alias to reconnect it Commented Jan 26, 2017 at 16:51

You must log in to answer this question.

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