Skip to Content

Linux Global Hotkeys

(background)
I've been playing around with Mozilla Songbird, and am frustrated by the lack of global hotkeys, which are essential to any good media player. As a result, I did a lot of googling, etc. ;), and figure I might as well save the next guy a bit of trouble.

Anyway, here's a little tutorial on playing with global hotkeys in linux. The library I'm using is XLib, as most window managers are built on X, so this will be compatible. The code is in C, but can probably be ported....

// Derived from a tutorial by Ch. Tronche (http://tronche.com/gui/x/xlib-tutorial/2nd-program-anatomy.html)

#include <X11/Xlib.h>
#include <stdio.h>
main()
{
    Window root;
    XEvent e;
    int F2,F3,F4,F5,F6;
    
    // Open the display
    Display *dpy = XOpenDisplay(0);
    if (!dpy)return;
    // Get the root window -- so keys will be global
    root = DefaultRootWindow(dpy);
    
    F2 = XKeysymToKeycode(dpy, XStringToKeysym("F2"));
    F3 = XKeysymToKeycode(dpy, XStringToKeysym("F3"));
    F4 = XKeysymToKeycode(dpy, XStringToKeysym("F4"));
    F5 = XKeysymToKeycode(dpy, XStringToKeysym("F5"));
    F6 = XKeysymToKeycode(dpy, XStringToKeysym("F6"));
    
    // register the keys
    XGrabKey(dpy, F2, 0, root, True, GrabModeAsync, GrabModeAsync);
    XGrabKey(dpy, F3, 0, root, True, GrabModeAsync, GrabModeAsync);
    XGrabKey(dpy, F4, 0, root, True, GrabModeAsync, GrabModeAsync);
    XGrabKey(dpy, F5, 0, root, True, GrabModeAsync, GrabModeAsync);
    XGrabKey(dpy, F6, 0, root, True, GrabModeAsync, GrabModeAsync);
    
    // wait for events
    for(;;) {
        XNextEvent(dpy, &e);
        if (e.type == KeyPress){
            if (e.xkey.keycode == F4)
                break;
            else{
                if (e.xkey.keycode == F2)printf("F2!!!\n");
                else if (e.xkey.keycode == F3)printf("F3!!!\n");
                else if (e.xkey.keycode == F5)printf("F5!!!\n");
                else if (e.xkey.keycode == F6)printf("F6!!!\n");
            }
        }
    }
    // clean up
    XUngrabKey(dpy, F2, 0, root);
    XUngrabKey(dpy, F3, 0, root);
    XUngrabKey(dpy, F4, 0, root);
    XUngrabKey(dpy, F5, 0, root);
    XUngrabKey(dpy, F6, 0, root);
}

 

So What's happening here??

Well, after initializing X, we've got a bunch of

F2 = XKeysymToKeycode(dpy, XStringToKeysym("F2"));

This is translates a human-freindly string "F2" into a machine-readable keycode, for later use.

Then, to register our keys, we use the XGrabKey function:

XGrabKey(Display *display, int keycode, uint modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode);

the "modifiers" int can be any of ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask. Alternatively, AnyModifier can be used as a catch-all.

The next bit is for handling the events -- pretty basic stuff.

At the end, its good practice to release your grabbed keys.

modifiers

@Frenzie that's where the "modifiers" come in -- have TAB be the key, and use ShiftMask or AltMask

Hiya, I don't really

Hiya,

I don't really understand how to utilize this concept for combinations of keys. I'm trying to implement an Alt + Tab window switcher (to work while Alt + Tab is disabled in Metacity), but while it's working with just, say, super left or alt left, I can't figure out how to get it to show up with alt (left) + tab, remain while alt is pressed (ok, it's already doing that now), etc. The documentation for all of this stuff also seems really hard to find, btw.

Would you have any idea?

RSS

Syndicate content