1

This is NOT a duplicate of Changing the keyboard layout/mapping on both the console (tty) and X in an X/console agnostic way?, where a system-wide /etc/default/keyboard is discussed.

I'm looking to use a user-specific file, ~/.keyboard, with xkb settings that is used by both X (e.g., + LXDE), as well as by the (kernel) virtual consoles (VTs/TTYs).

As may be seen from cat $(which setupcon), virtual consoles can pick up a user-specific ~/.keyboard file (or a VARIANT thereof) if user's environment is preserved when setupcon is run:

sudo -E setupcon

where setupcon will (more or less) convert the xkb-based ~/.keyboard settings (XKBMODEL, XKBLAYOUT, XKBOPTIONS, etc.) into console keymap type (via ckbcomp) and loadkeys the result into consoles. If user's environment is NOT preserved,

sudo setupcon

then /etc/default/keyboard is picked up.

However, as far I can see, in X setxkbmap only picks up the system-wide /etc/default/keyboard file. The user-specific ~/.keyboard is not picked up by setxkbmap. But that is what I need. In other words, I'm trying to feed ~/.keyboard to setxkbmap. I would like to be able to have this done both at X login (e.g., with a line in ~/.xsessionrc), as well as to be able to make changes to ~/.keyboard while in X and have them applied through setxkbmap (without sudo), much like setxkbmap -option provides.

Note that I'm NOT trying to manually create a user-specific xkb directory hierarchy and use that with xkbcomp -I. However, if there is an automated way of doing that with ~/.keyboard as the input, that could be an acceptable workaround.

As of now, the only way I see is a hack: manually parse ~/.keyboard, extracting XKBOPTIONS and then write an equivalent setxkbmap -option for each. I cannot believe for this hack to be the only way, although seeing https://who-t.blogspot.com/2020/02/user-specific-xkb-configuration-part-1.html makes me question that belief.

As of now I'm using Debian with X (+ LXDE). I don't think it makes a difference for Wayland, but if it does, please explain.

0mid
  • 435
  • I think the hack you mention is indeed the only way. However, you don't need to do it manually, you can automate the process with Sed (although it is still a shame that there is no way to directly use the file). If you are interested, I can write an answer. – Quasímodo Dec 10 '20 at 12:45
  • 1
    Thanks for your comment, @Quasimodo. Yes, using sed, awk, python, etc., is what I meant by "manually parse ~/.keyboard ...", as opposed to have it automatically read by setxkbmap. I can do that myself, but it is hard to believe this feature is not there in setxkbmap. – 0mid Dec 10 '20 at 21:17

1 Answers1

0

In case it is useful to someone else, here is the hack I mentioned above that I ended up using for now.

~/bin/setxkbmap.sh parses ~/.keyboard, extracting the xkb settings, and runs equivalent setxkbmap command(s) in X. ~/bin/setxkbmap.sh may be called manually, or automatically at X startup through a line in, e.g., ~/.xsessionrc.

~/bin/setxkbmap.sh:

#!/bin/bash
# Parse ~/.keyboard, extracting the xkb settings, and run equivalent
# setxkbmap command(s) in X.

source ~/.keyboard setxkbmap_cmd=(setxkbmap -model "${XKBMODEL}") setxkbmap_cmd+=(-layout "${XKBLAYOUT}")

Clear previously-set options first; otherwise, these will be

appended to whatever is already there.

setxkbmap_cmd+=(-option)

-r : do not allow backslashes to escape any characters

-a array: assign the words read to sequential indices of the array

variable ARRAY, starting at zero

IFS=',' read -r -a xkbopts <<< "${XKBOPTIONS}" for opt in "${xkbopts[@]}"; do setxkbmap_cmd+=(-option "${opt}") done

"${setxkbmap_cmd[@]}"

~/.keyboard:

XKBMODEL="pc105"
XKBLAYOUT="us"

ctrl: specifies options coming from /usr/share/X11/xkb/symbols/ctrl

file.

XKBOPTIONS="ctrl:menu_rctrl,ctrl:nocaps,ctrl:swap_rwin_rctl,terminate:ctrl_alt_bksp"

~/.xsessionrc:

# ~/.xsessionrc is sourced by Xsession (a sh script), everytime an X
# session is started. See 'man xsession' for details.

Explicitly use bash, as ~/.xsessionrc is called by sh (dash in

Debian 9 GNU/Linux).

bash ~/bin/setxkbmap.sh

0mid
  • 435