Modifying your GNOME keymap programmatically

For some reason I’ve a notebook with a Swedish keyboard but when docked I use my ergonomic keyboard with a German layout. To automatically switch the layout when the external keyboard is connected, I cooked up this script and added a .desktop file to $HOME/.config/autostart:

#!/usr/bin/env python
from gi.repository import Gtk, GLib, Gkbd
import usb
import sys
# Holtek Semiconductor, Inc. PS/2 keyboard + mouse controller
c = Gkbd.Configuration.get();
    # find index for german
    de = c.get_short_group_names().index('de')
    for bus in usb.busses():
        for dev in bus.devices:
            if dev.idVendor == vendor and dev.idProduct == product:
                c.lock_group (de)
except Exception, e:
    print e

This is using pyusb 0.4, it gets a bit easier with 1.0.

8 thoughts on “Modifying your GNOME keymap programmatically

  1. Hello,
    Do you know that in the latest xorg you can have a separate layout for each keyboard? Gnome doesn’t allow to configure them separately, but you can easily in a script:
    setxkbmap -device $id $LAYOUT
    Where $id is the device id as returned by “xinput –list”, and $LAYOUT is the language layout name (eg, “de”). I have a dutch USB keyboard which I use with my laptop which has a US layout, and that works fine ūüôā

  2. > Is the xinput id stable between reboots?
    Absolutely not. But the device ID as well as the device name is passed to the script I mentioned earlier.

  3. Unfortunately the hotplug solution doesn’t work. I’ve just tried, the main problem is that it’s called only for a mouse or a touchpad event. (The keyboard plugin doesn’t know about anything about run_custom_command()).
    Moreover arguments sent are a bit messed up (eg: “-i 5” is just one argument containing a space, and not 2 as you’d expect), which makes them harder to parse.
    Looks a nice idea though… for once that gnome allows such high level of configuration! I’m going to report some bugs in bugzilla….

Leave a Reply

Your email address will not be published. Required fields are marked *