On windows I have an autohotkey script which:

  • Only works when caps lock is on
  • Generates left, middle and right mouse button events when left control, menu and alt keys are pressed
  • Allows holding the keys down (for dragging objects)

Is there an easy way of duplicating this functionality in linux?


X has a built-in mechanism for controlling the mouse cursor with the keyboard. Press the Pointer_EnableKeys key to activate this mode (mouse keys mode); it's usually bound to Shift+NumLock.

In mouse keys mode, the keypad arrows move the pointer around, and the other keypad keys emulate buttons (/*- are left, middle, right respectively; + is left double-click, and 0 and . are left press and release).

See mouse keys for more information. By the way, this mode can be enabled on Windows too.

| improve this answer | |
  • Thanks, but I'm afraid mousekeys won't work because I still use the mouse in my right hand to move the cursor. And even if I could reassign the keys used by the mousekeys program, I would have to explicitly change between left, middle or right. With my ahk script I can rest my fingers on the three keys and press any or a combination of them instantly. – typist Jul 22 '11 at 21:47

Keymapping - mouse click - middle click How to Map Mouse buttons to Keyboard keys

Firstly, disable keypad controlling mouse so xev can capture the keycode Then type the command:

$ xev

Then move your mouse into the little new window that pops up. Press a mouse button to find out the name of that button: See below, I found one of my mouse buttons is called "button 1"

ButtonPress event, serial 37, synthetic NO, window 0x6200001,
    root 0x29d, subw 0x6200002, time 2427401, (31,41), root:(652,407),
    state 0x0, button 1, same_screen YES

Then find out which keyboard key you want to map that mouse button to: Press a keyboard key and find the keycode.

When pressing the space key on my keyboard, the terminal shows:

KeyPress event, serial 37, synthetic NO, window 0x6200001,
    root 0x29d, subw 0x0, time 2152399, (398,60), root:(1019,426),
    state 0x0, keycode 65 (keysym 0x20, space), same_screen YES,
    XLookupString gives 1 bytes: (20) " "
    XmbLookupString gives 1 bytes: (20) " "
    XFilterEvent returns: False

from above, we have found that the keycode for the Space key is 65 So you need to find the keycodes of the keys you want to map mouse buttons to...

Then the next step:

$ sudo apt-get install xkbset

Then copy the script below and save it into a file called keymap_mouse2kb.sh

of course change the keyboard keycodes to the ones you want

# set XKB layout
setxkbmap -layout us
# turn on mousekeys
xkbset m
# stop mousekeys expiring after a timeout
xkbset exp =m
# map keysym to other keysym
#xmodmap -e "keysym Menu = Pointer_Button2"
# this also works
 xmodmap -e "keycode 66 = Pointer_Button2"
 xmodmap -e "keycode 133 = Pointer_Button1"
 xmodmap -e "keycode 88 = Pointer_Button3"

Then make this file executable by

$ sudo chmod u+x keymap_mouse2kb.sh

Then run it when you need it... e.g. at booting up

$ ./keymap_mouse2kb.sh
| improve this answer | |
  • "setxkbmap -layout us" - does this imply that this might only work with 1 layout? – Display Name Oct 27 '18 at 11:31
  • I did not use "setxkbmap -layout us" line. I mapped Menu key on my keyboard to be used as mouse middle button and it worked with all keyboard layouts. – Lissanro Rayen Mar 2 at 1:29

I had a similar need. I couldn't find any existing solution that met all my needs, so I wrote a little utility to do it and put it on GitHub.


| improve this answer | |

You could probably do the same things with Tcl ('tickle').

| improve this answer | |

Using "xkbset m" has unfortunate consequence of disabling numpad, so I was forced to look for different solution. This is the solution I ended up with:

Create /usr/local/bin/click with following content:


# This script can be used to simulate mouse click and drag'n'drop with keyboard key.
# click 1 - left mouse button (the default if no arguments provided)
# click 2 - middle mouse button
# click 3 - right mouse button
# click 2 Shift_L - Press Shift key with middle mouse button (you can use any other
# modifier key instead)
# IMPORTANT: Do not forget to find your keyboard device name with "xinput list" command
# and change XINPUT_DEVICE below. Use "xinput test 'your keyboard name'" to be sure
# that you found correct device name.

  XINPUT_DEVICE="TypeMatrix.com USB Keyboard"
  if [[ -z "$1" ]]; then set -- "1"; fi
  if [[ -n "$2" ]]; then xdotool keydown --clearmodifiers "$2"; fi
  xdotool mousedown $1
  while read event; do
    if [[ $event == *release* ]]; then
      xdotool mouseup $1
      if [[ -n "$2" ]]; then xdotool keyup "$2"; fi
      break; fi; done < <(xinput test "$XINPUT_DEVICE")

Make it executable:

chmod +x /usr/local/bin/click

Then it can be used as a command launched by keyboard shortcut. For example, in KDE I created Custom Shortcut for middle mouse button, used Menu key as Trigger, and as Action used click 2. If you are using different desktop environment or xbindkeys, procedure is pretty much the same, just use any key you want as shortcut and make it run click command.

To make Shift+Middle Mouse Button work, I had to create separate shortcut for Shift+Menu key, and assign command click 2 Shift_L as Action.

If you are wondering why use this complicated script instead of xdotool click, the reason is that with xdotool click it is not possible to drag'n'drop by holding a key (this is important even for middle mouse button, many applications use it to rotate or pan view). The script above makes this possible.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.