In the current Tumbleweed, there are now two kbd packages:
- kbd-legacy, the old one
- kbd, the new one
To compare the package content, install QDirStat (zypper in qdirstat
) and
view both packages with qdirstat pkg:/kbd
.
This is the /usr/share/kbd/keymaps
directory (and nothing outside of that
directory) with all subdirectories except the xkb/
subdirectory there
(i.e. /usr/share/kbd/keymaps/xkb
) which belongs to the new kbd package.
/usr/share/kbd/keymaps
├── amiga
├── atari
├── i386
│ ├── azerty
│ ├── bepo
│ ├── carpalx
│ ├── colemak
│ ├── dvorak
│ ├── fgGIod
│ ├── include
│ ├── neo
│ ├── olpc
│ ├── qwerty
│ └── qwertz
├── include
├── mac
│ ├── all
│ └── include
├── ppc -> mac
└── sun
Many of the keymaps there start with the locale, but it's not completely consistent:
i386/quertz/
:
- croat.map.gz
- cz.map.gz
- cz-us-qwertz.map.gz
- de_alt_UTF-8.map.gz
- de_CH-latin1.map.gz
- de-latin1.map.gz
- de-latin1-nodeadkeys.map.gz
- de.map.gz
- de-mobii.map.gz
- fr_CH-latin1.map.gz
- fr_CH.map.gz
- hu.map.gz
- ro-latin2.map.gz
- sg-latin1-lk450.map.gz
- sg-latin1.map.gz
- sg.map.gz
- sk-prog-qwertz.map.gz
- sk-qwertz.map.gz
- slovene.map.gz
- sr-latin.map.gz
Notice exceptions like croat.map.gz
and slovene.map.gz
.
Some of the keymaps include another one with an include
statement.
zcat de-latin1.map.gz
# de-latin1.map: German keymap
...
...
keymaps 0-2,4-6,8-10,12
alt_is_meta
include "qwertz-layout"
altgr keycode 16 = at
control altgr keycode 16 = nul
altgr keycode 50 = mu
include "linux-with-alt-and-altgr"
plain keycode 83 = KP_Comma
include "euro2.map"
include "compose.latin1"
strings as usual
# Normal Shift AltGr Strg
keycode 1 = Escape Escape
keycode 2 = one exclam
keycode 3 = two quotedbl twosuperior nul
keycode 4 = three section threesuperior Escape
keycode 5 = four dollar
keycode 6 = five percent
keycode 7 = six ampersand
keycode 8 = seven slash braceleft
keycode 9 = eight parenleft bracketleft
keycode 10 = nine parenright bracketright
control altgr keycode 10 = Control_bracketright
keycode 11 = zero equal braceright
keycode 12 = ssharp question backslash
control altgr keycode 12 = Control_backslash
keycode 13 = dead_acute dead_grave
alt keycode 13 = Meta_acute
shift alt keycode 13 = Meta_grave
keycode 14 = Delete Delete
alt keycode 14 = Meta_Delete
keycode 15 = Tab Meta_Tab
keycode 26 = +udiaeresis +Udiaeresis
keycode 27 = plus asterisk dead_tilde
keycode 28 = Return
alt keycode 28 = Meta_Control_m
keycode 29 = Control
keycode 39 = +odiaeresis +Odiaeresis
Each key has up to four bindings, so this is easy to read and easy to edit.
Most important directories:
/usr/share/kbd
├── consolefonts
│ └── partialfonts
├── consoletrans
├── keymaps
│ ├── [amiga] (belongs to kbd-legacy)
. . ...
│ ├── [i386] (belongs to kbd-legacy)
. . ... (more subdirs that belong to kbd-legacy)
│ └── xkb
└── unimaps
/usr/share/kbd/keymaps/xkb
contains all the new keymaps directly without any
subdirectories. This is the only directory below /usr/share/kbd/keymaps/
that does not belong to kbd-legacy.
In addition to that, the new kbd package contains 33 commands + 3 symlinks in
/usr/bin
, 2 commands in /usr/sbin
, the corresponding man pages, message
translations and some miscellaneous files for its systemd service etc.
The naming is now much more consistent; now they always start with the
locale. There is no more croat.map.gz
; it's now hr.map.gz
("Hrvatska"),
there is no more slovene.map.gz
; it's now si.map.gz
.
Those keymaps are generated from xkb X11 keyboard definitions.
But the keymaps now have many more (128?) entries for each key which makes them much harder to read and to edit:
[sh @ balrog-tw-dev] ...kbd/keymaps/xkb 63 % zcat de.map.gz | head -n 10
keymaps 0-127
keycode 1 = Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape
keycode 2 = U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam U+0031 U+0021 U+00b9 U+00a1 U+0031 U+0021 U+00b9 U+00a1 Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam Meta_one Meta_exclam
keycode 3 = U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl U+0032 U+0022 U+00b2 U+215b U+0032 U+0022 U+00b2 U+215b Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_two Meta_quotedbl
keycode 4 = U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3 U+0033 U+00a7 U+00b3 U+00a3 U+0033 U+00a7 U+00b3 U+00a3 Meta_three Meta_three Meta_three U+00a3 Meta_three Meta_three Meta_three U+00a3
keycode 5 = U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar U+0034 U+0024 U+00bc U+00a4 U+0034 U+0024 U+00bc U+00a4 Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar Meta_four Meta_dollar
keycode 6 = U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent U+0035 U+0025 U+00bd U+215c U+0035 U+0025 U+00bd U+215c Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent Meta_five Meta_percent
keycode 7 = U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand U+0036 U+0026 U+00ac U+215d U+0036 U+0026 U+00ac U+215d Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand Meta_six Meta_ampersand
keycode 8 = U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape U+0037 U+002f U+007b U+215e Escape U+002f Escape Escape Meta_seven Meta_slash Meta_braceleft Meta_braceleft Meta_Escape Meta_slash Meta_Escape Meta_Escape
keycode 9 = U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape U+0038 U+0028 U+005b U+2122 Escape U+0028 Escape Escape Meta_eight Meta_parenleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_parenleft Meta_Escape Meta_Escape
/etc/vconsole.conf
(text consoles)/etc/X11/xorg.conf.d/00-keyboard.conf
(X11)/etc/sysconfig/keyboard
(NumLock etc.)/usr/share/systemd/kbd-model-map
(from the systemd package)/etc/X11/xorg.conf.d/00-keyboard.conf
(from the systemd package)
loadkeys
setxkbmap
xkbctrl
- Both packages are built from the same sources.
- They share the same
kbd.spec
file. - They have a different file list section:
kbd-legacy
:
where%files legacy %{kbd}/keymaps/{%{legacy_folders}}
%define legacy_folders amiga,atari,i386,include,mac,ppc,sun
kbd
: All the rest.
- SLES Manuals: Keyboard
man keymaps
- kbd.spec in OBS
- http://kbd-project.org/
- https://github.com/mike-fabian/langtable
- Keyboard layouts at Gate2Home
- Keyboards at Lexilogos
Check how relevant / up-to-date this is for SUSE Linux:
- https://wiki.archlinux.org/title/Linux_console/Keyboard_configuration
- https://wiki.archlinux.org/title/Xorg/Keyboard_configuration
This is used only for the inst-sys.
- Using
loadkeys
andxkbctrl
- Creating an UDEV rule in
/run/udev/rules.d/70-installation-keyboard.rules
(not copied to the target!)
Using localectl
(from the systemd universe) with a special command line since systemd is not running in the inst-sys:
systemd-firstboot --root /mnt --keymap my_keymap
Using localectl
:
- Query what the current keymap is:
localectl status
and filter for "VC Keymap" - Set the keyboard:
localectl set-keymap my_keymap
- List available keymaps:
localectl list-keymaps
The central data source for keyboards in YaST is /usr/share/YaST2/lib/y2keyboard/keyboards.rb
. It contains a Ruby hash like this:
{ "description" => _("German"),
"alias" => "german",
"code" => "de-nodeadkeys",
"legacy_code" => "de-latin1-nodeadkeys",
"suggested_for_lang" => ["de"]
},
{ "description" => _("German (with deadkeys)"),
"alias" => "german-deadkey",
"code" => "de",
"legacy_code" => "de-latin1"
},
{ "description" => _("German (Switzerland)"),
"alias" => "german-ch",
"code" => "ch",
"legacy_code" => "sg-latin1",
"suggested_for_lang" => ["de_CH"]
},
...
In AutoYaST, you specify a section <keyboard>
in the XML profile:
<keyboard>
<keymap>german</keymap>
</keyboard>
This can be either the alias
field or the code
field of the Ruby hash in /usr/share/YaST2/lib/y2keyboard/keyboards.rb
.
setxkbmap
localectl
localectl list-x11-keymap-models
localectl list-x11-keymap-layouts
/usr/share/X11/xkb/rules/base.lst
/etc/X11/xorg.conf.d/00-keyboard.conf
- Ubuntu:
/etc/default/keyboard
localectl set-x11-keyboard
sends a DBUS messageSetX11Keyboard
tolocaled
localed
receives the DBUS message and:- Checks with PolicyKit for permissions
- Writes a new
/etc/X11/xorg.conf.d/00-keyboard.conf
# Written by systemd-localed(8), read by systemd-localed and Xorg. It's
# probably wise not to edit this file manually. Use localectl(1) to
# instruct systemd-localed to update it.
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "at"
Option "XkbModel" "microsoftpro"
Option "XkbVariant" "nodeadkeys"
Option "XkbOptions" "terminate:ctrl_alt_bksp"
EndSection
man keymaps
= keyboard table descriptions forloadkeys
anddumpkeys