The Journalist's Cage

And this gray spirit yearning in desire to follow knowledge like a sinking star...

HomeBlogTagsArticles

Calendar

January 2007
SuMoTuWeThFrSa
 123456
78910111213
14151617181920
21222324252627
28293031

Recent Bookmarks

Tags

Archives


RSS

Global key bindings with Python and GTK

I recently purchased a Logitech G15 gaming keyboard, which features a nifty integrated LCD and an assortment of macro keys. Unfortunately, Beryl only allows users to bind arbitrary commands to 11 keys. Since the G15 has 18 separate macro keys in addition to multimedia buttons, I had to find an alternate solution. I finally decided to implement my own binding manager so that I can associate keys with commands and Python expressions.

Logitech G15

Obviously, the first step was to figure out how to set up global key bindings with Python. I started by poking around the GTK/GDK documentation in search of relevant functionality, but I didn't really find anything there. I asked in the #linux channel on the Ars Technica IRC server and got some useful suggestions, but nothing that seemed to do exactly what I wanted. It finally occurred to me to investigate the source code of a Python application that has global key bindings.

Deskbar, a really useful panel applet that I use on a daily basis, uses a global key binding for activation. The deskbar/Keybinder.py file in the Python site-packages directory reveals that Deskbar is actually using a file called _keybinder.so, which appears to have been created for the Tomboy note-taking program. The tomboy_keybinder_bind function in _keybinder.so makes it possible to associate a binding with a Python function. The binding is described as strings consisting of modifiers and single letters. The following is a simple example that shows how to associate a key binding with a function:

#!/usr/bin/env python

# Import the GTK library
import gtk

# Import the key binding function from the module
from _keybinder import tomboy_keybinder_bind as bindkey

# Define a function to execute when the binding is activated
def onBindingPress(arg):
  print "Binding initiated and parameter received: %s" % arg

# Bind to the onBindingPress function and pass "Test" as an argument
bindkey("<Ctrl><Alt>b", onBindingPress, "Test")

# Establish a binding to quit the program
bindkey("<Ctrl><Alt>q", gtk.main_quit)

# Start a GTK main loop that will run until the quit binding is used
gtk.main()

I find it a bit odd that this functionality had to be borrowed from Tomboy, and it makes me wonder how it is implemented in _keybinder.so. I'm not entirely sure why global key binding support isn't provided by the Python and Ruby GTK bindings, but I'm pleased that I found a way to do it with minimal hassle.


Posted on 2007-01-100 comments



Comments

Add a Comment

Name:

E-mail: (Optional, Not shown)

Subject: (Optional)

Text in image:

Comment: