How to define custom keyboard mappings under Fedora Silverblue?

On a Fedora Workstation, I can configure custom keyboard layouts by dropping
files into /usr/share/X11/xkb/symbols/. For instance, let’s say that the
physical keyboard is mapped to us; here are some changes that I would
like to apply to its corresponding file, i.e.
/usr/share/X11/xkb/symbols/us[*]:

  • I regularly input some maths, so some letters ought to be typed straight from
    the keyboard, instead of using LaTeX, the character map or what-not. Here, λ
    and ∑ are mapped to the same key as 4:
key <AE04> {	[ 4, dollar, 0x10003BB, 0x1002211 ]};
  • For many texts, there is no harm done using " as the quotation mark. There
    are, however, instances when being typographically correct is paramount. For
    such cases, I have this key handy when I need typographic quotation marks:
key <AB01> {	[ w, W, 0x100201C, 0x100201D ]};

You get the crux of the process: I search for a character’s Unicode code point
and I stick the code to some key. There is a couple dozens of such
customizations on the system running Workstation, but I obviously cannot ship
things like that with Silverblue since /usr is read-only.

One would think that there might be a way to load keyboard configurations say
from $HOME. Would you know how to do that, I would appreciate very much
pointers to how it is done.

Alternatively, is there a was to override a specific file/path in /usr under
Silverblue? The process of overriding and/or overlaying packages is well
documented, but I would rather not go the rabbit hole of compiling a bespoke
xkeyboard-config package that would override the default one.


[*] I am aware that the changes will be lost on the next xkeyboard-config
update and I can deal with that.

:thinking: Maybe you can try with xmodmap in xorg user session. Here the tutorial or here.

2 Likes

Here is a Silverblue working example where I remapped the Right AltGR Key to a “Windows” key

If you need, I can dig out some docs I used in the past to set up the above

2 Likes

Thank you for the reply.
Your solution looked promising given that it uses a language I am familiar with, unlike intercepting xev events.
There is a hiccup, though: it seems that Wayland cannot cope with mappings defined in ~/.xkb/symbols. Here is the steps I followed:

  • Create a file ~/.xkb/symbols/eg that contains exactly what you have in ~/.xkb/symbols/sway_altgr.
  • Log out and back in, then press AltGr: nothing happened.
  • Run localectl set-keymap eg; result: Failed to set keymap: Keymap eg is not installed.

All in all, yes, it would be much appreciated if you dug those docs up! Maybe your method is only suited for Sway? My system is under Wayland; that was not explicit in the OP, although I indicated it via a tag.

Hmm… From a cursory look, it seems that Xmodmap understands a static set of characters. Looking at https://wiki.linuxquestions.org/wiki/List_of_Keysyms_Recognised_by_Xmodmap, there are many characters that I would like to remap to some keys right now that are not listed on that page. The ideal solution would allow for remapping any Unicode character.

Let‘s see if the way paved by @returntrip below will bear any fruits and I will go with that. Otherwise, I will come back to Xmodmap as a stopgap solution, albeit I have not yet tested if it is actually a solution under my system‘s configuration.

It goes without saying, thank you for taking a look and proposing a way out.

1 Like

It might be that Gnome (btw Sway works with Wayland) does not load xkb files automatically: gnome3 - How can I autoload xkb customisations in GNOME? - Unix & Linux Stack Exchange.

I have used these links as reference:

https://www.charvolant.org/doug/xkb/html/node5.html

https://git.sr.ht/~jman/dotfiles/tree/refs/heads/master/xkb/README.md

[(btw Sway works with Wayland)]

Thanks for the correction.

It might be that Gnome […] does not load xkb files automatically…

Both the page that you linked and the actual fix therein linked state that some files must be written to under /usr/share/X11/xkb/, whether for customising mappings or for making GNOME auto-load said mappings. I wonder if there exists documentation somewhere that explain to achieve the same thing without mutating /usr.

I have used these links as reference: (URL 1 →charvolant-dot-org); (URL 2→sr-dot-org)

If I read that correctly, neither pages are concerned with where to put the configurations, but rather with how to create them. The second one is specifically aimed at Sway users and finding a similar writing for GNOME[1] will be my next endeavour.


  1. If GNOME is able to load configurations from $HOME at all. ↩︎

1 Like

In Silverblue /usr/local is RW and its content will be symlinked to /usr therefore you could create /usr/share/X11/xkb/ in /usr/local/share/X11/xkb/

Update: the above is incorrect. For some reason, I was convinced that stuff was getting symlinked. But in my case, the wayland session is read from /usr/local/share/wayland-sessions/ by GDM.

The magic of mirroring /usr/local/share/X11/xkb to /usr/share/X11/xkb via
symlinks seems to have no effect on this system.

I have settled on stopping going sideways and just locally compile
xkeyboard-config. It might be a rough way of going about remapping some keys,
but it works™. @returntrip, thank you again for your efforts.

Here are the full steps for the curious eyes—and for future reference for self:

toolbox enter --distro fedora --release 35

sudo dnf install rpmdevtools

curl -LO 'https://src.fedoraproject.org/rpms/xkeyboard-config/raw/f35/f/xkeyboard-config.spec'

spectool --get-files xkeyboard-config.spec

tar --extract --bzip2 --file xkeyboard-config-2.33.tar.bz2

mv xkeyboard-config-2.33.tar.bz2 xkeyboard-config-2.33.tar.bz2.original

#rpmdev-setuptree

cp xkeyboard-config.spec $HOME/rpmbuild/SPECS/

cp SOME-PATH/TO/THE/us-bespoke xkeyboard-config-2.33/symbols/us

tar --create --file xkeyboard-config-2.33.tar
tar --create --bzip2 --file xkeyboard-config-2.33.tar.bz2

cp xkeyboard-config-2.33.tar.bz2 $HOME/rpmbuild/SOURCES/

cd $HOME/rpmbuild/SPECS/

rpmbuild -bs xkeyboard-config.spec

cd ../SRPMS/

sudo dnf install \
    gettext{,-devel} \
    libxslt \
    meson \
    'perl(XML::Parser)' \
    'pkgconfig(glib-2.0)' \
    'pkgconfig(x11) >= 1.4.3' \
    'pkgconfig(xorg-macros) >= 1.12' \
    'pkgconfig(xproto) >= 7.0.20' \
    xkbcomp \
    git-core

rpmbuild --rebuild xkeyboard-config-2.33-2.fc35.src.rpm

And, to definitely nail it,

# Under a superuser shell
rpm-ostree override replace THE/PATH/TO/rpmbuild/RPMS/noarch/xkeyboard-config-2.33-2.fc35.noarch.rpm

localectl set-keymap us

systemctl reboot

Sorry, maybe I have not explained myself properly: you do not have to symlink anything. You just create whatever file you need under /usr/local/ and the system will do the magic for you.

Example:

If you create /usr/local/share/wayland-sessions/swaywm.desktop the file swaywm.desktop will automagically show in /usr/share/wayland-sessions/

Incorrect see post above

Sorry, maybe I have not explained myself properly: you do not have to symlink anything. You just create whatever file you need under /usr/local/ and the system will do the magic for you.

I understood that part correctly. To wit:

mkdir --parents /usr/local/share/X11/xkb/symbols

# Attempt n°1
touch /usr/local/share/X11/xkb/symbols/foo
file /usr/share/X11/xkb/symbols/foo
    # …foo: cannot open `…foo' (No such file or directory)

# Attempt n°2
touch /usr/local/share/X11/xkb/symbols/woe
systemctl reboot
file /usr/share/X11/xkb/symbols/woe
    # …woe: cannot open `…woe' (No such file or directory)

The difference between what you can do and what I cannot very likely lies in the different ways Sway and GNOME handle keyboard configurations.

However, zooming out of the narrow OP—which is solved, albeit dirtily—if those /usr/local/… ⇒ /usr/… symlinks are meant to be an invariant that should generally hold, I think you uncovered a bug here. To be completely sure, if you have a partition to spare, you could try a Fedora Linux 35.* (Silverblue) / GNOME 41.* setup and witness the bug for yourself.

Apologies for giving you incorrect information. I have amended my posts.

No worries.

PS[1]. In case the current solution might actually help someone else, I amended the snippet to use mock and indicate how to access the toolbox-built binary from the host.

toolbox enter --distro='fedora' --release='35'

sudo dnf install rpmdevtools mock

curl -LO 'https://src.fedoraproject.org/rpms/xkeyboard-config/raw/f35/f/xkeyboard-config.spec'

spectool --get-files='xkeyboard-config.spec'

tar --extract --bzip2 --file='xkeyboard-config-2.33.tar.bz2'

mv xkeyboard-config-2.33.tar.bz2{,.original}

#rpmdev-setuptree

# Bump the spec’s Release field, say
sed --in-place '10s/Release:    2/Release:    3/' xkeyboard-config.spec

cp xkeyboard-config.spec $HOME/rpmbuild/SPECS/

cp SOME/PATH/TO/THE/us-bespoke xkeyboard-config-2.33/symbols/us

tar --create --bzip2 --file='xkeyboard-config-2.33.tar.bz2' xkeyboard-config-2.33

cp xkeyboard-config-2.33.tar.bz2 $HOME/rpmbuild/SOURCES/

cd $HOME/rpmbuild/SPECS/

rpmbuild -bs xkeyboard-config.spec

cd ../SRPMS/

mock --root='fedora-35-x86_64' --rebuild='xkeyboard-config-2.33-3.fc35.src.rpm'

exit # the toolbox

# Get the ID of the container from which we just exited.
toolbox list
podman cp 'CONTAINER_ID:/var/lib/mock/fedora-35-x86_64/result/xkeyboard-config-2.33-3.fc35.noarch.rpm' /SOME/PLACE

sudo rpm-ostree override replace /SOME/PLACE/xkeyboard-config-2.33-3.fc35.noarch.rpm

localectl set-keymap us

systemctl reboot

  1. It seems that I cannot edit my own post. A cursory look on the web indicates that the default time limit for self-edits in Discourse is two months. I wonder how long is that limit under this Discourse instance. Or, maybe newbies cannot self-edit… ↩︎

1 Like

I believe libxkbcommon 1.0.0 + xkeyboard-config 2.33 provide a new improved extension mechanism, as explained by Peter Hutterer in a multi-part blog series ending with A pre-supplied “custom” keyboard layout for X11

See the libxkbcommon User-configuration doc.

I think this can significantly simplify the steps above, although I am not very familiar with Silverblue.