KDE has a very handy feature to switch keyboard layouts on the fly. This is for instance useful if you use the German keyboard layout by default, and the US layout for programming. To enable keyboard layout switching, go into System Settings > Input Devices (category Hardware) > Keyboard item > Layouts tab:
Here, ‘[x] Configure layouts‘ is checked, enabling the list view. I added the German keyboard layout, and then the English (US) layout. Notice also, that the shortcut is set to ‘Ctrl+Alt+K‘. Clicking apply, a tiny little indicator appears in the panel:
Unchanged Keyboard Shortcuts
Switching the keyboard layout has one potential issue, though: The shortcuts remain unchanged. So if undo is mapped to Ctrl+z in the German layout, it is still mapped to Ctrl+z in the US layout. Note that by ‘z’ we refer to the hardware key on the keyboard. As a consequence, in the US layout, hitting the hardware key ‘y’ on the German keyboard inserts the character ‘z’, but the z in Ctrl+z is still on the hardware key ‘z’. This behavior may or may not be wanted.
Getting more into detail reveals that the order of the keyboard layouts in the first screen shot is of importance: If you first add the German ‘de‘ layout, and then the English ‘us‘ layout, then the shortcuts will always use the Germany keyboard layout, independent of what keyboard layout is chosen.
Reversely, if you first add the English ‘us’ layout, and then the German ‘de‘ layout, then the shortcuts will always use the English ‘us‘ keyboard layout.
So it seems that the order defines a priority, and the shortcuts always use the first entry in the list.
The correct solution to fix this would (in my humble opinion) be to add an option ‘[x] Shorcuts follow keyboard layout‘ or similar. But since this option does not exist, let’s do a quick hack to still get what we want here.
First we reset the shortcut in the settings of the keyboard layout options:
Click apply and close the dialog. Now, the shortcut ‘Ctrl+Alt+K‘ is unbound. Our idea is now to create a script that toggles the keyboard layout by calling setxkbmap with the appropriate parameters and bind this script via a global shortcut to ‘Ctrl+Alt+K‘.
To this end, we first have to create the script. So let’s first type `setxkbmap -query` in the console and check the output. For me, this results in:
$ setxkbmap -query rules: evdev model: pc101 layout: de,us variant: nodeadkeys,
From this, we can follow that the current xkb layout is achieved with:
setxkbmap -model pc101 -layout de,us -variant nodeadkeys
Now, let’s switch the de,us to us,de and try the following:
setxkbmap -model pc101 -layout us,de -variant nodeadkeys
Notice, that the keyboard layout indicator in the panel switched to ‘us‘. Calling the first variant with de,us again, we get back to the German layout.
This discovery leads us to the following script switch-keyboard-layout.sh:
#!/bin/sh # query xkb map: us,de -> us is primary; de,us -> de is primary dummy=`setxkbmap -query | grep us,de` # return value 0: us,de; return value != 0, de,us if [ $? -ne 0 ]; then # de is primary, now make us primary in list setxkbmap -model pc101 -layout us,de -variant nodeadkeys else # us is primary, now make de primary in list setxkbmap -model pc101 -layout de,us -variant nodeadkeys fi
Save this script somewhere to switch-keyboard-layout.sh and make it executable with
chmod 755 switch-keyboard-layout.sh
Each time we execute this script, the keyboard layout is toggled.
Next, we go into System Settings again and navigate to Shortcuts and Gestures (Common Appearance and Behavior), there in the Custom Shortcuts we add a new Command/URL item named ‘SwitchKeyboardLayout’ as follows:
As a comment for this new item, we write ‘Switch Keyboard Layout‘, in the ‘Trigger‘ tab, bind the global shortcut to ‘Ctrl+Alt+K‘, and in the ‘Action‘ tab, choose the switch-keyboard-layout.sh script. Finally click Apply, and close the dialog.
Now, hitting Ctrl+Alt+K calls our script and correctly toggles the keyboard layout including the shortcuts.
Unfortunately, this approach does not support e.g. switching the keyboard layout on application basis as the switching policy of the Keyboard settings (first screen shot) allows. Still it works.
A final remark, though: For GTK applications this works out of the box. So is there any real reason why this is not the case for KDE / Qt applications? A real fix would be very much appreciated, I’d be also fine with an option. But not providing this feature at all is very thin ice…
Update: This issue was reported as KDE bug #197552 in 2009, and resolved as an upstream issue. However, it never was reported to Qt upstream. If I may say so, this is not how resolving bugs in KDE usually works. Grrr…