xkbbell & xkbevd

X11 Logo ⓒ MIT

So I started working with Eclipse on Linux. I was hoping to redefine the keyboard shortcuts to use the meta key, as I’m connecting remotely with a Mac OS X laptop and X11. I though it would be an easy task. I was wrong. In KDE applications, this just requires you to select the action, type in the new shortcut and it is done. With gtk2 this does not work. I checked with xev, the key events are the expected one: left-meta. I searched online, no useful information, just other lost users and the nagging feeling that Gnome does not honor the xmod file. Changing the keyboard settings in the gnome-control-center has no effect, this might be related to the fact I’m running a KDE desktop, but I have hardly the choice, on my virtual machine Gnome just crashes. I tried reproducing the issue on my laptop but installing gnome-terminal and launching result in the program dying horribly on launch, probably because there is no gnome desktop running, and plain X11 is way too scary. I have not solved the issue (getting rid of all things gtk would probably be the sanest solution), but digging around I stumbled on a interesting X11 extension: X Keyboard.

I have written a small binary program called xbkgrowl that does the same thing than the script presented here. It does not require any configuration file and does a few other things, link priority translation. Please check it out.

In short, this extension can be used to control the lights and modifiers on the keyboard, it also gives a way of sending notifications to the X11 server. This would be something useful when I’m working on a remote Linux box, streaming back sounds is wasteful and far from stable. On my Mac, I have Growl installed so it would be really convenient to be able to trigger growl notifications. There are versions of Growl, or Growl-like project under linux, and Growl has network support, but this requires a fixed IP adresses, an open port on my Mac, and installing software or at least writing some script. But actually by using the X keyboard dæmon and an old command line you can do this using the X11 connection and without installing anything on the Linux side.

  • Install growlnotify on Mac OS X.
  • Create a configuration file xkbevd.cf with the following content:
    Bell()  shell "/usr/local/bin/growlnotify --message \"$(name)\" --appIcon X11; true "
    
  • Start the X11 server (you can just start xlogo)
  • Start the X keyboard dæmon with the following command xkbevd -cfg xkbevd.cf -bg. This will start the program in background using the configuration defined in xkbevd.cf.
  • You can now trigger a notification using the command xkbbell message, for instance xkbbell "lasers offline". This should work both locally and on remote machines.
    This only works if the X11 display on your Unix box point back to the X11 server on your Mac. You can test this by launching xlogo on the Unix box, it should display the logo on the Mac’s screen. If you have connected using ssh, make sure you selected the -Y option.

Some notes:

  • This is an old protocol (1995) which has never been seriously supported. Use at your own risk.
  • The xkbevd program, is buggy. In particular, there seems to be some issue with the memory buffer used for command substitution, no end marker is inserted, so when a long message is followed by a short one, the short command will have the last characters from the long one at its end. This is why the second command is true, which ignores all its arguments.
  • While the xkbbell command recognises many options, only the volume flag seems to be carried to the server. The volume is in the $(volume) variable, with the value of 50 added.
  • The notifications are carried over NX, but the text message is discarded.
  • There are some standard bell names defined in the header files, but any arbitrary ASCII string seems to work.
  • Instead of growl, you can also use the Mac OS X command say. In that case, the configuration file would be:
    Bell()  shell "/usr/bin/say \"$(name)\" ; true "
    
  • It is possible to define different actions for different messages, so for instance.
    Bell()  shell "/usr/local/bin/growlnotify --message \"$(name)\" --appIcon X11; true "
    Bell(Warning) shell "/usr/bin/say Warning
    

I more or less fixed the gtk issue with xmodmap, but this is really a kludge.

7 thoughts on “xkbbell & xkbevd”

  1. I followed your instructions but I was expecting to see a message appear on my Mac when I sent it from my Linux box. That didn’t happen. I got a “can’t open display” error. If I run the xkbell command on my Mac, Growl shows the message. What am I missing?

  2. You need to make sure that the DISPLAY variable on your Unix box point to the X11 server on your Mac. If you used ssh to connect to the Unix box, make sure you used the -Y option.

  3. I had a look at mumbles, but using it has basically the same drawback as calling a script to trigger growl notification:
    – I need to figure out the ip address of the Mac to send it growl notifications
    – I need to open up a network port for growl notifications on the mac.
    The first item can be solved with a little bit of script-fu, the second item represents a security risk. Using xkbbell requires neither. Now if mumbles would support sending notifications over X11 bell events, that would be cool.

  4. Very nice! Have confirmed this works on Cygwin+GrowlforWindows as well, as long as you have the X11, xkbutils, and xkbevd packages installed.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.