1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Sway keysym</title>
<link rel="stylesheet" href="./style.css" />
<link rel="icon" href="./favicon.ico" sizes="any" />
<!--link rel="icon" href="./icon.svg" type="image/svg+xml" / -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#241504" />
<meta name="color-scheme" content="light dark">
</head>
<body>
<header>
<h1>Sway keysym</h1>
</header>
<article>
<p>
Under the <a href="https://swaywm.org/">Sway</a> Wayland compositor, we could set set <code>xkb_layout</code> and <code>xkb_options</code> for keyboards in order to do weird key mapping related things. Many people use <code>caps:ctrl_modifier</code> and <code>caps:escape</code> in <code>xkb_options</code> (see <a href="https://man.openbsd.org/xkeyboard-config">xkeyboard-config(7)</a> for other options) to make Caps Lock function as an extra Ctrl or Esc key.
</p>
<p>
If all you want to do is do a relatively common modification like that, chances are that <code>xkb_variant</code> and <code>xkb_options</code> already has what you want, and you should just set that.
</p>
<hr />
<p>
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 <code>xkb_options</code>. (<code>caps:shift</code> doesn't differ much from normal Caps Lock, make it confusingly documented and doesn't make the Caps Lock function as an extra Shift.)
</p>
<p>
On X11, I would simply use <code>xmodmap -e "keysym Caps_Lock = Shift_L"</code>. Now my Caps Lock functions as an extra Left Shift. Works just alright.
</p>
<p>
But now that I switched to Wayland, Sway in particular, <code>xmodmap</code> for X11 isn't going to work. What I ended up doing was the following:
</p>
<p>
<b><code>$HOME/.xkb/symbols/gbcustom</code></b>
</p>
<pre>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 ] };
};</pre>
<p>
Note that here, the "<code>key</code>" lines are in the form <code>key <X> { [ A, B, C, D ] } ;</code>, where "<code>X</code>" is the keycode symbolic name of the physical key you want to press. In my case, it is <code>CAPS</code>. Check <code>/usr/share/X11/xkb/symbols/pc</code> and <code>/usr/share/X11/xkb/symbols/latin</code>, or the relevant files for your keyboard configuration, to look up the keycode symbolic name from the name you're used to. (Looking up <code>Shift_L</code> in <code>symbols/pc</code> gets you to <code>LFSH</code>, which is what you would use in place of "<code>X</code>". <code>A</code> is triggered when <code>X</code> is pressed alone, <code>B</code> when it's pressd with Shift, <code>C</code> with AltGr, and <code>D</code> with both AltGr and Shift.
</p>
<p>
<b><code>$HOME/.config/sway/config</code></b>
</p>
<pre>input "1:1:AT_Translated_Set_2_keyboard" {
xkb_layout "gbcustom"
}</pre>
<p>
Of course, replace "<code>1:1:AT_Translated_Set_2_keyboard</code>" with your actual keyboard identifier listed in <code>swaymsg -t get_inputs</code>. And reload Sway.
</p>
<p>
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 <code>xmondmap</code> line to <code>.xinitrc</code>. Hopefully things would get better as Wayland matures.
</p>
<p>
<a href="https://github.com/swaywm/sway/issues/4250">This GitHub issue</a> and <a href="https://www.city17.xyz/keychron/#xkb-here-be-dragons">jman's article on this</a> were extremely helpful. Thanks to <a href="https://sr.ht/~brocellous">brocellous</a> for pointing out the solution involving custom options.
</p>
<hr />
<p>
Another, potentially better method involving defining custom <code>xkb_options</code>, propsed by brocellous:
</p>
<p>
<b><code>$HOME/.xkb/symbols/customsymbol</code></b>
</p>
<pre>// Remap caps to Shift_L
partial modifier_keys
xkb_symbols "caps_lshift" {
replace key <CAPS> {
type[group1] = "ONE_LEVEL",
symbols[group1] = [ Shift_L ],
actions[group1] = [ SetMods(modifiers=Shift) ]
};
};</pre>
<p>
<b><code>$HOME/.xkb/rules/evdev</code></b>
</p>
<pre>! option = symbols
custom:caps_lshift = +customsymbol(caps_lshift)
! include %S/evdev</pre>
<p>
<b><code>$HOME/.config/sway/config</code></b>
</p>
<pre>input "1:1:AT_Translated_Set_2_keyboard" {
xkb_layout "gb"
xkb_options "custom:caps_lshift"
}</pre>
</article>
<footer>
<ul role="list">
<li><a href="./">Home</a></li>
<li>Runxi Yu</li>
<li><a rel="license" href="./pubdom.html">Public Domain</a></li>
</ul>
</footer>
</body>
</html>
|