I have been using a slightly custom-modded version of the US Dvorak layout for years, and I like automating my computer setups.
It has always seemed like a hassle trying to automate the keyboard layout setup, so I haven't gotten myself to do it until now.
How to add a custom keyboard layout in Ubuntu?
You need:
- A functional xkb keyboard layout, placed under
/usr/share/X11/xkb/symbols/
- An entry in one of the *.lst files under
/usr/share/X11/xkb/rules/
- An entry in the corresponding *.xml file under the same rules directory
When all this is done, you need to run the sudo dpkg-reconfigure xkeyboard-data
command, to make your installation reload the configured keyboard layouts. This will enable your desktop environment or window manager (Gnome, KDE, i3, XMonad, etc.) to pick up on the changes and let you choose your custom keyboard layout so that it's available even at the login screen.
XKB Layout
My layout is basically that I modded the standard US Dvorak layout by adding some characters with umlauts and other stuff that's used in the Swedish language (å, ö, ä, é, and the very infrequently used ü). I access these by holding the altgr key and pressing a
, o
, e
, u
, and y
keys respectively (i.e., for the people who don't know the Dvorak layout, that's the keys that usually have the letters a
, s
, d
, f
, and t
on them).
It looks like this
// This is basically a US Dvorak with some (mostly) Swedish accented characters added
// å -> alt-gr a
// ä -> alt-gr e
// ö -> alt-gr o
// é -> alt-gr u
// ü -> alt-gr y
default partial alphanumeric_keys
xkb_symbols "dvorak" {
include "us(dvorak)"
include "level3(caps_switch)"
include "level3(ralt_switch)"
name[Group1] = "Swedish (Frost Dvorak)";
// Unmodified Shift AltGr Shift+AltGr
// // symbols row, left side
key <AD05> { [ y, Y, udiaeresis, Udiaeresis ] };
// home row, left side
key <AC01> { [ a, A, aring, Aring ] };
key <AC02> { [ o, O, odiaeresis, Odiaeresis ] };
key <AC03> { [ e, E, adiaeresis, Adiaeresis ] };
key <AC04> { [ u, U, eacute, Eacute ] };
};
*.lst entries
Normally, there should be an evdev.extras.lst
file, and it should be possible to add your entry there, but due to some bug, that doesn't work, and we have to add this to the evdev.lst
file.
You need to add two different lines in this file, one under the ! layouts
section, and one under the ! variants
section.
! layouts
frost Swedish (Frost Dvorak)
! variants
dvorak frost: Swedish (Frost Dvorak)
*.xml entry
The XML entry gives pretty much the same information as the lst entry, but in a different format.
It looks like this:
<layout>
<configItem>
<name>frost</name>
<shortDescription>frost dvorak</shortDescription>
<description>Swedish</description>
<languageList>
<iso639Id>swe</iso639Id>
</languageList>
</configItem>
<variantList>
<variant>
<configItem>
<name>dvorak</name>
<description>Swedish (Frost Dvorak)</description>
</configItem>
</variant>
</variantList>
</layout>
The same bug-related thing goes here, so this needs to be added to the evdev.xml
file.
Automating all of this using Ansible
I was going through my setup scripts the other day and realized that I could probably be able to automate this entire thing as well, to remove a few more of the manual steps in setting up my computer. I've had some bad luck with work computers the past year and a half and so I've had to do this multiple times.
After a little digging around and testing things, I found out that we can use the lineinfile
module for the *.lst
entries, and the xml
module for the XML entry.
Not only that, but we can also tell Ansible to automatically run the dpkg-reconfigure
command, AND tell it to configure my keyboard layouts for me, so I don't have to poke around in the menus at all!
Here's the Playbook definition I use for this, task by task.
Copy the keyboard layout file
- name: Copy keyboard layout file
become: yes
file:
src: frost.xkb
dest: /usr/share/X11/xkb/symbols/frost
owner: root
group: root
mode: '0644'
state: file
Add the ! layout
entry to evdev.lst
- name: Add layout to evdev.lst
become: yes
lineinfile:
path: /usr/share/X11/xkb/rules/evdev.lst
insertafter: "! layout"
line: " frost Swedish (Frost Dvorak)"
Add the ! variant
entry to evdev.lst
- name: Add variant to evdev.lst
become: yes
lineinfile:
path: /usr/share/X11/xkb/rules/evdev.lst
insertafter: "! variant"
line: " dvorak frost: Swedish (Frost Dvorak)"
Add the <layout>
entry to evdev.xml
- name: Add layout to evdev.xml
become: yes
xml:
path: /usr/share/X11/xkb/rules/evdev.xml
xpath: /xkbConfigRegistry/layoutList
backup: yes
input_type: xml
add_children:
- |
<layout>
<configItem>
<name>frost</name>
<shortDescription>frost dvorak</shortDescription>
<description>Swedish</description>
<languageList>
<iso639Id>swe</iso639Id>
</languageList>
</configItem>
<variantList>
<variant>
<configItem>
<name>dvorak</name>
<description>Swedish (Frost Dvorak)</description>
</configItem>
</variant>
</variantList>
</layout>
Reconfigure xkb-data
- name: Reconfigure xkb-data
become: yes
shell: dpkg-reconfigure xkb-data
Set the GNOME keyboard layout(s)
- name: Set keyboard layout
become: yes
become_user: frost
tags: dconf
dconf:
key: "/org/gnome/desktop/input-sources/sources"
value: "[('xkb', 'frost+dvorak'), ('xkb', 'dvorak')]"
state: present
Restart GNOME Shell without exiting all programs
- name: Restart GNOME Shell
shell: busctl --user call org.gnome.Shell /org/gnome/Shell org.gnome.Shell Eval s 'Meta.restart("Restarting…")'
Håppü Häcking!
Top comments (0)