0

END GOAL

I use Arch Linux with bspwm as my window manager and sxhkd as a hotkey daemon. I want to map a certain key combination in my sxhkdrc so that it shuffles through different keyboard layouts. For example:

# Shuffle through keyboard layouts
super + e
    *action to be executed*

LOCALES

First, I do not know whether I am required to add Serbian locales as I only (from time to time) want to activate the Serbian keyboard layouts. My thinking is that keymaps are enough. Just in case, I generated Serbian locales; so now when I run localectl list-local, the output is:

en_US.UTF-8
sr_RS.UTF-8
sr_RS.UTF-8@latin

These respectively correspond to:

  • English locale for the U.S. – UTF-8 encoding
  • Serbian locale for Serbia – Cyrillic script – UTF-8 encoding
  • Serbian locale for Serbia – Latin script – UTF-8 encoding

KEYMAPS

The three layouts I want to use (be able to shuffle through) are:

  • us = US English
  • sr-cy = Serbian in Cyrillic script
  • sr-latin = Serbian in Latin script

I know that I can edit /etc/vconsole.conf and set KEYMAP=sr_cy instead of us or use localectl set-keymap sr_cy.

Here are my concerns with that:

  1. It is not an elegant solution.
  2. I cannot shuffle through different layouts. I have to run the command and specify the desired layout each time.
  3. Would such change persists globally even after I log out or reboot the system? If the answer is yes, I will potentially be in trouble. I use LVM on LUKS encryption and for me to decrypt my disk I need us layout. Hence, if I forget to switch from Cyrillic script before rebooting, it's bye bye forever.

QUESTION

Is there any way for me to add multiple keymaps in /etc/vconsole.conf and have the us be the default one? If so, what do I need to do to switch between them. Is it a simple command or do I need a small script? If that is not an option, what is the best way to get to my end goal.

I have tried finding the answer to having multiple keymaps but I was not able to find anything applicable to my problem. I would appreciate a solution or even advice and suggestions especially if it advances my knowledge. Thank you in advance!

Vladimir
  • 149
  • 2
  • 8

3 Answers3

2

You are getting "Error loading new keyboard description" because setxkbmap actually needs different layout names than those you are setting in the commands.

If you run localectl list-keymaps | grep sr, you will, as expected, get: sr-cy and sr-latin.

If you run localectl list-locales | grep sr, you will also get expected result: sr_RS.UTF-8 and sr_RS.UTF-8@latin.

But, localectl list-x11-keymap-layouts| grep sr returns nothing, and instead you have to use another two-letter abbreviation: localectl list-x11-keymap-layouts| grep rs which returns rs that is used for Serbian keyboard layout under X11.

So, for Cyrillic you actually need to use setxkbmap rs and that then defaults to Cyrillic layout,

and to activate Latin layout, you have to specifically enable this variant for the Serbian keyboard layout, as it is not the default: setxkbmap -layout rs -variant latin

I myself use this command: setxkbmap -layout rs,rs,de,us -variant latin,,,dvp -option 'grp:alt_shift_toggle'. This does the following:

  • Adds Serbian layout as my default and sets a Latin variant for it
  • adds Serbian layout with its default (Cyrillic)
  • Adds German layout with its default
  • adds US layout and sets a Dvorak-Programmer layout for it
  • Adds option to switch between the layouts with Alt+Shift key combination.

The -layout and -variant have to be set in the same order, and if nothing is set for the variant (meaning nothing after the comma), it will use the default for that language.

I have these locales enabled in /etc/locale.gen and generated with sudo locale-gen command.

If I list them with localectl:

localectl list-locales
C.UTF-8
de_DE.UTF-8
en_DK.UTF-8
en_US.UTF-8
sr_RS.UTF-8
sr_RS.UTF-8@latin

And my default localectl looks like this:

localectl status
System Locale: LANG=en_US.UTF-8
               LC_NUMERIC=sr_RS@latin
               LC_TIME=sr_RS@latin
               LC_MONETARY=sr_RS@latin
               LC_PAPER=sr_RS@latin
               LC_NAME=sr_RS@latin
               LC_ADDRESS=sr_RS@latin
               LC_TELEPHONE=sr_RS@latin
               LC_MEASUREMENT=sr_RS@latin
               LC_IDENTIFICATION=sr_RS@latin
    VC Keymap: sr-latin
   X11 Layout: rs,latin

I use Arch Linux and I3 as a tiling manager and this line in my ~/.config/i3/config

exec --no-startup-id sleep 6 && setxkbmap -layout rs,rs,us,de -variant latin,,dvp, -option 'grp:alt_shift_toggle'

loads the layouts and enables layout switching with a simple key combination.

I also have

exec --no-startup-id gxkb

which adds an icon representing the current keyboard layout to my i3blocks bar.

I know OP does not use the same configuration, but I think that this can easily be translated to their setup.

d00mil
  • 21
  • 3
1

I cannot comment due to a lack of reputation. I don't know the answer, just want to share my thoughts.

First the worst case. Could you not recover from not being able to type in your passphrase by creating and booting from an external drive like a usb-stick to recover your files from the internal drive? Maybe you could try that to be prepared for the worst situation.

I never used localectl and it seems overly strong for what you need, to just change the keyboard layout as it controls localization of other software as well. I usually use setxkbmap. I am pretty sure but give no guarantee, that changes you make with setxkbmap die with the X-server, so a reboot would reset, but I don't give guarantee for anything. However this could be testable: make a copy of the us keyboardmap, swap two keys (at least one is part of your decrypt passphrase), apply that copy, reboot the system, now you can check wether the new layout is still applied (I hope it's clear what I mean, if your passphrase is: asdf, then swap f and g and see if you have to type asdf or asdg).

For this to be of any use to you, I am of course assuming a lot of things. If you don't use X, then this is not usefull at all.

bananabook
  • 62
  • 5
  • 1
    Thank you for sharing your thoughts! To address your first comment: Yes. Now that I think about it, I am pretty sure I could chroot into the system and then decrypt the partition. However, as you went on, all these are really painful solutions for a simple problem. To answer your second comment: Yes, I use X. Second, setxkbmap resets for sure as I use it to change Esc and CapsLock. The change takes place only after X session starts and dies with the session. I've never used setxkbmap for anything else other than that. I'll look into whether I could change the entire layout with it. – Vladimir May 20 '22 at 20:59
  • It's not really a solution, rather an idea for a test you would have to run once to see how the system behaves. But there could always be something simpler. Changing layouts with setxkbmap is pretty cool. The layoutfiles look complicated but really you just need to copy the one you already like and change what you want to change, they are fairly readable. They are in /usr/share/X11/xkb/symbols as can be seen from the manpage. You can just try `setxkbmap us` and see if it did sth. – bananabook May 20 '22 at 21:12
1

I use setxkbmap to switch between Dvorak and QUERTY. I have a bash script at ~/.local/bin/toggle_kbd (which is included in my PATH), which my window manager has bound to a shortcut. It just runs a case statement to set my keyboard to whichever one it currently isn't. I'm using the keymap names listed in localectl list-keymaps:

#!/usr/bin/env bash

case $(setxkbmap -query | grep layout | awk '{ print $2 }') in
          us) setxkbmap sr-cy ;;
       sr-cy) setxkbmap sr-latin ;;
    sr-latin) setxkbmap us -variant altgr-intl ;;
           *) setxkbmap us -variant altgr-intl ;;
esac

It will also reset to your locale's keyboard (the normal one you boot up with) whenever X is restarted. This does cycle through them instead of setting a specific one. I don't know how big of a deal that is for you, but the script idea could accommodate that easily enough.

Jeremy Meadows
  • 300
  • 1
  • 7
  • Thank you so much! This seems to be what I was looking for! I have one more question and please pardon my (currently) poor knowledge of bash scripting. I made this script executable at saved it in a directory where I keep my other small scripts. However, every time I run it, I get this message: "Error loading new keyboard description". What am I doing wrong? – Vladimir May 21 '22 at 17:03
  • If I can run it successfully, I will have no problem mapping a key combination in sxhkdrc to run it automatically for me. – Vladimir May 21 '22 at 17:05
  • 1
    @Vladimir Hmm, that sounds like you don't have the `sr-*` layouts installed or something. Can you switch to that layout successfully some other way? `setxkbmap` looks for language information stuff in `/usr/share/X11/xkb/symbols`, and `sr` doesn't exist on my machine, so I'm guessing it needs to be installed manually. – Jeremy Meadows May 21 '22 at 22:04
  • Thank you for the feedback! You are correct. I listed the symbols under the path which you have specified and no sr-* layouts are there. I will look into how to install them, – Vladimir May 23 '22 at 18:48
  • I was not able to find a solution to this. Listing the contents of /usr/share/X11/xkb/symbols does not list any sr-* layouts. However, when I type localectl list-keymaps I see both sr-cy and sr-latin. Any suggestions or should I try and make a new post? – Vladimir May 24 '22 at 14:41