Pages - Menu

Friday, November 21, 2008

mapping middle-click to a keyboard key

Update 2012: Some of these components have been deprecated and removed from newer distributions. Check this newer post for a different method.

One of the biggest things I miss when using my laptop is the ability to select text in one window, then middle-click paste it into another. Sure, I can push both buttons together, but that requires a degree of accuracy, and it's supposed to be a quick, one-finger action, not a move-two-hands affair. I can imagine this would be infinitely useful using Linux on a Macbook too, as they don't even have right-click. I started looking round for a solution to this problem, and eventually found it.

First, we need install an old accessibility extension to X which is called xkbset. In Ubuntu or Debian, just sudo apt-get install xkbset. The original idea of this software is to provide support for people who might not be able to use a mouse or keyboard so well, so it enables things like MouseKeys (control the cursor with the numpad) and StickyKeys (hit shift, lift off, type a letter, get a capital), and SlowKeys (only register a keypress after a certain amount of time). But we're going to use it to map a keyboard key to a mouse button with MouseKeys.

First, we'll get rid of all the cursor-control stuff, so you can still use your numpad. As root, edit the file /usr/share/X11/xkb/compat/mousekeys and remove everything between interpret.repeat= False; and // New Keysym Actions. Notice this maps some new "keysym" actions below, specifically the one called Pointer_Button2.

Next, we'll make a script to configure xkbset, to turn MouseKeys on, to not turn it off after a period of inactivity, and to map a key of your choice to middle-click. Here's my ~/.middle-click.sh:
#!/bin/bash
# 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 135 = Pointer_Button2"
This maps the Menu key (it's between Right Alt and Right Ctrl on my keyboard, looks like a menu with a mouse cursor) to mouse button 2, which is middle click. Notice I can also use any other key on the keyboard, by commenting out the keysym line, and using the keycode line. Keycodes are different from keyboard to keyboard, so to get the keycode of the key you wish to use, run xev in a terminal, push the key you desire, and watch the terminal output.

For the Mac users, left-click is button 1, and right-click is button 3. If I was using a Mac, I imagine I'd map Right Command to Button2, and Right Option to Button3. I hope the right side of these buttons has a different keycode to the left side. If not, I've read of people using F11 and/or F12. man xmodmap will tell you how to use a modifier like Cmd+F12 if you so desire.

Under Gnome, I use System -> Preferences -> Sessions to start this script as I log in, so I don't have to worry about it again. Don't forget to make your script executable with chmod +x ~/.middle-click.sh

15 comments:

Gleber said...

Jamie, you are my lifesaver! Great post!

gauda said...

thanks for sharing dude! nice tip!

Anonymous said...

Great hint! Thanks a lot! I just bought one of these netbooks and there is no real mmb at all, so your post saved my day :)

Anonymous said...

I take it using Shift + INS was out of the question initially? Tut tut.

sledge said...

>Anonymous said...
>
> I take it using Shift + INS was out >of the question initially? Tut tut.

Make Shift+INS work in GTK applications, and you'll be the God, tut tut

Matthew said...

could you post a modified version of mouse for me i messed mine up

Anonymous said...

This is an old post, but awesome!

I've been wanting to do this on my netbook for a while now.

Oh -- just a note, though, I had to comment out between interpret.repeat= True; and
//New Keysym Actions

(there was another interpret.repeat = False; in there right above the New Keysym line...)

Thanks! now I just need to train myself to use that menu key...

Anonymous said...

There is "xdotool", which allows to script middle click (and much more!).
E.g.

xdotool click 2

for middle click

Unknown said...

Great solution. I had to change the script for a UK keyboard.

Just comment out lines relating to the us keyboard and use the key id

# setxkbmap -layout us
# xmodmap -e "keysym Menu = Pointer_Button2"
# and uncomment the key code
xmodmap -e "keycode 135 = Pointer_Button2"

Anonymous said...

Is there a way to do the opposite? For instance, make middle-click type "k". My real plan is to use this to make my keyboard "one-handed" by mapping middle-click to Mode_switch.

Linux Aleph said...

I've never done it myself, but the Arch Linux wiki has some good tips. See "Binding keyboard to mouse buttons" here: https://wiki.archlinux.org/index.php/All_Mouse_Buttons_Working

Anonymous said...

Worked perfectly. What a save. Thanks.

Running Mint 13 on Toshiba S70-A. Dodgy Elantech clickpad - very awkward to click. I've mapped left-click to Super_L.

Paul Lockwood said...

Very helpful, thanks.

This is a list of all key mappings: http://wiki.linuxquestions.org/wiki/List_of_Keysyms_Recognised_by_Xmodmap


I map a numeric keypad to single and double click. What I personally ended up with is:

xmodmap -e "keysym Menu = Pointer_DblClick_Dflt"
xmodmap -e "keysym KP_Add = Pointer_Button1"
xmodmap -e "keysym KP_Subtract = Pointer_DblClick_Dflt"

Unknown said...

THANK YOUUUUUU !!!!!!

Unknown said...

Thank you, worked perfect!