Under the Sway Wayland compositor, we could set
set xkb_layout
and xkb_options
for keyboards in order to do weird
key mapping related things. Many people use caps:ctrl_modifier
and
caps:escape
in xkb_options
(see
xkeyboard-config(7) for
other options) to make Caps Lock function as an extra Ctrl or Esc key.
If all you want to do is do a relatively common modification like that,
chances are that xkb_variant
and xkb_options
already has what you
want, and you should just set that.
But if what you want isn’t covered in the standard XKB files, hear my
story. I personally wanted Caps Lock to function as an additional Shift
key, which isn’t covered in xkb_options
. (caps:shift
doesn’t differ
much from normal Caps Lock, make it confusingly documented and doesn’t
make the Caps Lock function as an extra Shift.)
On X11, I would simply use xmodmap -e "keysym Caps_Lock = Shift_L"
.
Now my Caps Lock functions as an extra Left Shift. Works just alright.
But now that I switched to Wayland, Sway in particular, xmodmap
for
X11 isn’t going to work. What I ended up doing was the following:
$HOME/.xkb/symbols/gbcustom
default partial alphanumeric_keys
xkb_symbols "basic" { // leave "basic" in-tact unless you know what you're doing
include "gb" // or whatever base layout you use, most likely "us"
name[Group1] = "English (UK) Customized";
key <CAPS> { [ Shift_L, Shift_L, Shift_L, Shift_L ] };
};
Note that here, the “key
” lines are in the form
key <X> { [ A, B, C, D ] } ;
, where “X
” is the keycode symbolic name
of the physical key you want to press. In my case, it is CAPS
. Check
/usr/share/X11/xkb/symbols/pc
and /usr/share/X11/xkb/symbols/latin
,
or the relevant files for your keyboard configuration, to look up the
keycode symbolic name from the name you’re used to. (Looking up
Shift_L
in symbols/pc
gets you to LFSH
, which is what you would
use in place of “X
”. A
is triggered when X
is pressed alone, B
when it’s pressd with Shift, C
with AltGr, and D
with both AltGr and
Shift.
$HOME/.config/sway/config
input "1:1:AT_Translated_Set_2_keyboard" {
xkb_layout "gbcustom"
}
Of course, replace “1:1:AT_Translated_Set_2_keyboard
” with your actual
keyboard identifier listed in swaymsg -t get_inputs
. And reload Sway.
There might be better ways to do so, but I’ve got this to work. For
these unusual setups, it is a bit complicated and not as straightforward
as adding a xmondmap
line to .xinitrc
. Hopefully things would get
better as Wayland matures.
This GitHub issue and jman’s article on this were extremely helpful. Thanks to brocellous for pointing out the solution involving custom options.
Another, potentially better method involving defining custom
xkb_options
, propsed by brocellous:
$HOME/.xkb/symbols/customsymbol
partial modifier_keys
xkb_symbols "caps_lshift" {
replace key {
type[group1] = "ONE_LEVEL",
symbols[group1] = [ Shift_L ],
actions[group1] = [ SetMods(modifiers=Shift) ]
};
};
$HOME/.xkb/rules/evdev
! option = symbols
custom:caps_lshift = +customsymbol(caps_lshift)
! include %S/evdev
$HOME/.config/sway/config
input "1:1:AT_Translated_Set_2_keyboard" {
xkb_layout "gb"
xkb_options "custom:caps_lshift"
}