| « Installing Funambol and integrating with SOGo | SOGo » |
Getting all Fn keys to work on the Sony Vaio VPCZ2
When I got my Vaio Z2, I installed Kubuntu 11.10 on it, and found out that not all Fn keys are mapped correctly out of the box. This is not specific to KDE, since it's mostly a kernel driver level thing.
Kernel driver
Note that I'm not talking about the fancy Assist, Web and Vaio buttons (I will get to these in another post), just the Fn-key mappings.
The normal troubleshooting procedures at https://wiki.ubuntu.com/Hotkeys/Troubleshooting didn't work (that somehow always happens to me :)), due to the peculiar way the sony-laptop driver works for handling input events. (See http://lkml.indiana.edu/hypermail/linux/kernel/1110.2/00048.html for the nitty gritty).
Out of the box, the mute, volume up & down, brightness up & down, and the suspend key worked. The touchpad toggle, display switch, and zoom in & out didn't.
...
Taking the peculiarities of the sony driver into account, I extended the contents of /lib/udev/keymaps/module-sony to :0x05 touchpad_toggle # Fn+F1
0x06 mute # Fn+F2
0x07 volumedown # Fn+F3
0x08 volumeup # Fn+F4
0x09 brightnessdown # Fn+F5
0x0A brightnessup # Fn+F6
0x0B switchvideomode # Fn+F7
0x0D zoomout # Fn+F9
0x0E zoomin # Fn+F10
0x10 suspend # Fn+F12
Now the keycodes are mapped to the right key symbols. Nice. The switchvideomode key seems to work now, and it arrives in X as the XF86Display event, but when trying to use the other newly defined keys in the KDE shortcuts control panel, they don't work. As if no key is pressed at all.
Sigh.
XKB
The next layer on top of the kernel is XKB. The keyboard you choose in KDE maps to one of the XKB definitions in /usr/share/X11/xkb. You can see what XKB config is active by entering in a terminal :
setxkbmap -print
Digging through the various xkb files I found that the XF86TouchpadToggle is actually mapped to the FK21 key code, in the symbols/inet file. The Zoom In and Zoom Out buttons are not defined in my currently active XKB map, so to be able to use those I will need to include them to my map somehow. Being too lazy to dive into the (quite complex) XKB layer, I tested the Touchpad Toggle key, which is defined in my XKB map.
So to test I map the 0x05 keycode to the key symbol F21 (as root)
/lib/udev/keymap input/event4 0x05 F21
..and test if the key arrives in X with xev. Yay, I get a nice XF86TouchpadToggle event!
Then, I go back to the KDE shortcuts control panel, and try to attach the key to some event. Now it detects a key is pressed, but I get the message that 'The key you just pressed is unsupported by Qt'. Argh!
Following the trail, I end up at KDE bug #182672, which basically explains that the problem is known, a fix has been made, but it's apparently not a priority for the Qt people to get it in. Will I be holding my breath? No. So let's go for the workaround.
Workaround
Instead of the proper solution
- mapping the keyboard scan codes to the right key symbols
- getting the key symbols to map to X events via XKB
- including them in the right keyboard definitions
- and pushing Qt to merge a patch that enables support for these events
.. I change the /lib/udev/keymaps/module-sony file to use prog1, prog2 and prog3 key symbols :
0x05 prog1 # Fn+F1
0x06 mute # Fn+F2
0x07 volumedown # Fn+F3
0x08 volumeup # Fn+F4
0x09 brightnessdown # Fn+F5
0x0A brightnessup # Fn+F6
0x0B switchvideomode # Fn+F7
0x0D prog2 # Fn+F9
0x0E prog3 # Fn+F10
0x10 suspend # Fn+F12
These key symbols are supported through the various input layers, they pass through the kernel and X and Qt. It's proper nor pretty, but it's the quickest way to bind those damn keys in the KDE shortcut system.
Touchpad Toggle
Now, the reason to get into all this was basically to make use of the touchpad-toggle Fn-key. Zooming in and out is nice-to-have, and I currently have those bound to the Zoom Desktop effect, but being able to disable the touchpad when typing is an essential need. KDE has no support for this out of the box, most likely because the XF86TouchpadToggle doesn't get passed through Qt anyway, but at least we can now bind the key to a script.
Put the code below in a file somewhere. The Vaio Z2 has a 'SynPS/2 Synaptics TouchPad'. If you have a different model, use 'xinput list' to find the right name for your device. Don't forget to make the script executable.
#!/bin/shDEVNAME="SynPS/2 Synaptics TouchPad"PROP="Device Enabled"
ENABLED=$(( `xinput list-props "$DEVNAME" | grep "$PROP" | cut -d\: -f 2` ))
if [ $ENABLED == 1 ]; thenENABLE=0elseENABLE=1fi
xinput -set-prop "$DEVNAME" "$PROP" $ENABLE
Then, via KDE Control Panel, go to Shortcut and Gestures / Custom Shortcuts. Create a new group, and a new action. In the Trigger tab, let KDE sniff your Fn-F1 keycombo, and in the Action tab point to the location of the above script.
Enjoy
--
Sources:
http://code.google.com/p/vaio-f11-linux/wiki/ProgrammableKeys
http://madduck.net/docs/extending-xkb/
http://people.uleth.ca/~daniel.odonnell/Blog/custom-keyboard-in-linuxx11