Switching Xorg keyboard layout on OpenBSD

       449 words, 3 minutes

I own laptops with a French keyboard. And when my Cloud servers reboot for maintenance, I have to enter their FDE passphrase. This is done by some VNC-like stuff that don’t work well with non-US layout keyboard.

Here’s a few minimalistic options to switch keyboard layout on OpenBSD.

Of course, if you run a complex DE, like Gnome, KDE or even XFCE, there is a graphical tool that allows switching keyboard layout. But when using cwm(1), you have to dig elsewhere.

Configuring an Xorg alternate keyboard layout

Although Xorg on OpenBSD works out-of-the-box, you can add extra configurations. Reading xorg.conf.d(5), one may discover that directories such as /etc/X11/xorg.conf.d and /usr/X11R6/share/X11/xorg.conf.d may be use to add extra configuration. As the latter already exists, I used it to add my keyboard configuration:

# cat /usr/X11R6/share/X11/xorg.conf.d/60-keyboards.conf
Section "InputClass"
  Identifier "Multiple keyboard layouts"
  MatchIsKeyboard "on"
  Option "XkbLayout" "fr,us"
  Option "XkbOptions" "grp:alt_shift_toggle"
EndSection

After restarting Xorg, the keybindings Alt + Shift allows to switch between FR and US layout.

This is nice and easy but I didn’t found a way to query (and print) the actual layout value. So I reverted the Xorg configuration ; by simply deleting the 60-keyboards.conf.

Using scripts to switch and query keyboard layouts

The stock tool named setxkbmap(1) allows setting, switching and querying keyboard layouts. So I first wrote a simple script that switches between FR and US layouts:

# cat ~/scripts/switchkb.sh
#!/bin/sh
#
# Switch keyboard layout
#

PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin"

_dkbd="fr"  # Default layout
_akbd="us"  # Alternate layout

[[ "$(setxkbmap -query | awk '/^layout:/ { print $2 }')" == "$_dkbd" ]] \
  && setxkbmap -layout $_akbd \
  || setxkbmap -layout $_dkbd

exit 0
#EOF

My default layout is FR. When I run it once, the keyboard switches to US layout. When I run it twice, the keyboard layout is back to FR. Loop.

That script is binded to 4-k (aka Win + k) in my cwmrc(5) file

# cat ~/.cwmrc
(...)
bind-key 4-k "~/scripts/switchkb.sh"
(...)

I also added a function to my termbar implementation that would show me the current keyboard layout:

# cat ~/scripts/termbar
(...)
function kbd {
  echo -n "  $(setxkbmap -query | awk '/^layout:/ { print $2 }')"
}
(...)

Using desktop notifications

Another option to get the current keyboard layout is to use desktop notification. With cwm, a nice notification system is dunst(1). After a small modification in the switch script:

#!/bin/sh
#
# Switch keyboard layout
#
PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin"

[[ "$(setxkbmap -query | awk '/^layout:/ { print $2 }')" = "fr" ]] \
  && ( setxkbmap -layout us; notify-send 'Keyboard' ' US' ) \
  || ( setxkbmap -layout fr; notify-send 'Keyboard' ' FR' )

exit 0
#EOF

the layout switch will trigger a visible alert.

Keyboard switch notification