3

I want to set my keyboard layout to 'de' variant 'us'. On my ubuntu 15.10 with unity this works fine using the command setxkbmap de us.

The problem is, I have to run this command after every boot/after every wakeup from sleep. How can I configure my system to permanently use the mentioned layout? I know I can use some form of autostart (unity's or .xinitrc), however this won't work after suspend. I also read about setting the layout in org.gnome.desktop.input-sources here, but this won't give the desired results using the string 'de+us'.

Any ideas?

2
  • Out of curiosity: how does that layout look like? (Umlauts?,qwertz? but / directly accessible ?) – guntbert Jan 18 '16 at 20:35
  • 1
    It basically is a us qwerty keyboard layout with the german umlauts on AltGr+o/u/a/s and on AltGr+*where they would be on a german layout*. For me this layout combines easy access to the braces, /, .. and the german umlauts. It just feels more natural than using e.g. the compose functionality or switching between layouts. If only I could get ubuntu/X to use it by default :[. – dassmann Jan 19 '16 at 10:28
3
+50

Note for other searchers landing on this page: this is apparently peculiar to the de-us layout in the Unity environment, because for some reason it lacks an entry in a particular configuration file.


How keyboard data is stored in Ubuntu

In Ubuntu, there is a folder called /usr/share/X11/xkb/symbols which contains a few subfolders as well as a number of text files, each representing a different layout. Most, if not all, of these layouts, have a number of variants. The one we're interested in is the us variant of the de keyboard, so we open the file de and scroll down to the following entry (it was at line 686 for me, but I'm not on 15.10).

partial alphanumeric_keys
xkb_symbols "us" {
    include "us"

    name[Group1]="German (US keyboard with German letters)";

    key <AC01> { [           a,          A, adiaeresis, Adiaeresis ] };
    key <AC02> { [           s,          S,     ssharp,     ssharp ] };
    key <AC10> { [   semicolon,      colon, odiaeresis, Odiaeresis ] };
    key <AC11> { [  apostrophe,   quotedbl, adiaeresis, Adiaeresis ] };
    key <AD03> { [           e,          E,   EuroSign,   EuroSign ] };
    key <AD07> { [           u,          U, udiaeresis, Udiaeresis ] };
    key <AD09> { [           o,          O, odiaeresis, Odiaeresis ] };
    key <AD11> { [ bracketleft,  braceleft, udiaeresis, Udiaeresis ] };
    key <AE03> { [           3, numbersign,    section,    section ] };
    key <AE11> { [       minus, underscore,     ssharp,   question ] };

    include "level3(ralt_switch)"
};

This defines the keyboard to be identical to the standard QWERTY variety us, with changes to

  • keys 1 (A), 2 (S), 10 (;), and 11 (') on the home row
  • keys 3 (E), 7 (U), 9 (O), and 11 ([) on the top row
  • keys 3 (3) and 11 (-) on the numbers row
  • the ALT key used to access the special characters

We check that it's properly formatted, not missing any brackets or anything, and it is. This is why setxkbmap de us succeeds, if only temporarily. We'll copy the description from this entry later on.

How Ubuntu accesses that data

Ubuntu has a registry setting where it saves the name of the keyboard or keyboards the user wants. However, we have to fix an entry in another configuration file before Ubuntu will accept our preferred keyboard. The file that needs to be modified is /usr/share/X11/xkb/rules/evdev.xml.

This file has three major sections:

  • a list of known keyboard models (describing the physical arrangement of buttons)
  • a list of known keyboard layouts (describing the logical assignment of characters to keys)
  • a list of options (describing possible modifications to the layout)

We need to open this as root so we can save it later. Since we want to use the us variant of the de layout, the relevant portion of the file is going to be the second section- specifically, we modify the German layout (in my copy, this begins on line 3176).

<layout>
  <configItem>
    <name>de</name>

    <shortDescription>de</shortDescription>
    <description>German</description>
    <languageList>
      <iso639Id>ger</iso639Id>
    </languageList>
  </configItem>
  <variantList>
    <variant>
      <configItem>
        <name>us</name>
        <description>German (US keyboard with German letters)</description>
      </configItem>
    </variant>

Notice the structure of this section. Each layout contains a configuration and multiple variants. I've added a new variant entry (the last six lines), immediately after the tag opening variantList, the content of which matches what I found in the keyboard data file above.

After saving, change the registry setting to select our newly added entry:

gsettings set org.gnome.desktop.input-sources sources [('xkb', 'de+us')]

I found it necessary to log out and back in for this change to take effect, but after that, the layout worked as one would hope, including surviving suspend/resume cycles.

2
  • 1
    Awesome, thanks for the background info! This is exactly what I was looking for. I will open a bug report and try get this fixed in future unity versions. Btw is there any sort of documentation where stuff like this is described? – dassmann Jan 22 '16 at 10:32
  • The documentation is not comprehensive; I synthesised my answer from a number of different sources and some experimentation on a LiveUSB. My take is, if you're offering a bounty you deserve a thorough response. – Aoeuid Jan 27 '16 at 4:16
1

Add new script into /etc/pm/sleep.d, name it 20_my-layout

case "${1}" in
    resume|thaw)
        DISPLAY=:0.0 ; export DISPLAY
        setxkbmap de us
;;
esac

Source: How to execute a command after resume from suspend?

1
  • 1
    This is a clever answers aswell. Thanks, I was not aware of the sleep.d folder! – dassmann Jan 22 '16 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.