<p>I didn't like fact that UCW layout is in fact just an overlay and not a
"proper" level 3, so I started studying how to create a custom keyboard layout.
Few notable resources: <aclass="reference external"href="TODO">XKB page on ArchWiki</a>, manpages for
<aclass="reference external"href="TODO">xkeyboard-config(7)</a>, <aclass="reference external"href="TODO">setxkbmap(1)</a> and <aclass="reference external"href="TODO">xkbcomp(1)</a> and looking into
<ttclass="docutils literal">/usr/share/X11/xkb/symbols/cz</tt> (found by grepping <ttclass="docutils literal">/usr/share/X11</tt> for
"ucw").</p>
<p>Another reason for creating my own layouts is various tweaks esp. on laptop
keyboards. For example, the laptop I am typing this sentence on has broken the
up arrow key, so I would like to map it somewhere. I use <ttclass="docutils literal">xmodmap</tt> for that,
but if this could be contained in a single layout, it would make stuff simpler
for me. (And as I will later learn, <ttclass="docutils literal">xmodmap</tt><aclass="reference external"href="TODO">does not work well</a> with xkb
layouts…)</p>
<p>Also, I have another tweak on my keyboards: Compose key. This really calls for
the custom layout! And when at it, I should create one for the ttys as well…</p>
<p>But this had quite a low priority (the <ttclass="docutils literal">kbd.sh</tt> script in <em>all</em> my homes does
the job well enough), so I didn't get to it in time. Luckily, maybe – if I were
quicker I would not end up in this rabbit hole. At this point, I knew the basic
stuff and was reasonably sure that I could hack it together, at least somehow;
what was stopping me was lack of time and not being sure how I want to manage
machine-specific tweaks in two different layout syntaxes (xkb for X11 and kbd
<p>… and he had a problem and asked me if I would have a look into it. Apparently,
<aclass="reference external"href="TODO">group switching didn't work in XWayland</a>. At first, I wanted to work it around
by finally creating the Unified UCW keymap™, but I wanted to learn more about
XKB (from TODO GUIDES), which took me quite long, again. (Studying, working,
helping with camps <em>and</em> fixing layouts takes some time…)</p>
<p>Also, since the issue is apparently bigger, solving all group switches would be
a better and more useful solution than just hacking up the Unified UCW keymap
(even though I want my tweaks to eventually be xkb-based anyway).</p>
<p>I had very little experience with Wayland until then, mostly because X11 worked
for me rather well. I tried running Sway few times before, but usually quickly
reverted to using Xorg for various reasons (Nvidia GPU in laptop, very laggy
mouse, maybe <em>this exact</em> issue with UCW layout) which I didn't feel like
solving at that moment.</p>
<p>I wanted to help my friend, though, so I started looking more into using Sway
on another laptop and reading about internals of input system on <aclass="reference external"href="TODO">Peter
Hutterer's blog</a> TODO NAME SPELLING? Occasionally I would randomly google
(<aclass="reference external"href="TODO">with DuckDuckGo</a> :-D) for the issue with group switching, just in case…</p>
</div>
<divclass="section"id="the-nerd-snipe-issue">
<h2>The nerd snipe issue</h2>
<p><aclass="reference external"href="TODO">TODO SOMEONE</a> on GitHub found out an interesting workaround: when they
<em>disabled</em> the group switch, the UCW layout <em>started working</em>. Complete "huh?"
moment, I knew I wanted to know more about why that worked. The
<aclass="reference external"href="TODO">xkeyboard-common(7) manpage</a> says about more group switching options, so I
randomly tried switching by Menu key in XWayland (using <ttclass="docutils literal">setxkbmap</tt> even
though it complained and was supposed to do nothing), and ended up with <em>both</em>
CapsLock and Menu adding diacritics.</p>
<p>After a bit of mathematic thinking (more in my <aclass="reference external"href="TODO">comment of the main issue</a>) I
concluded that it was actually working fine, just that the <ttclass="docutils literal">SetGroup</tt> action
was evaluated <em>twice</em>, which would overflow back to the first group when two
layouts are set (probably the most common case). Mathematic term for this issue
is "arithmetic in the Z_2 group" :-)</p>
<p>Corollary 2: A simple workaround is adding the UCW overlay twice, e.g.
<ttclass="docutils literal">setxkbmap us,cz,cz <spanclass="pre">-variant</span> ,ucw,ucw</tt> (and thus changing the algebraic group
to be Z_3).</p>
<p>I think that another workaround would be to change the <ttclass="docutils literal">compat</tt> rules for
XWayland, but it feels nasty to have such a quirk in xkeyboard-config database.
Changing them for everyone (in <ttclass="docutils literal">compat/evdev</tt> directly) might break other
systems, so that also does not seem to be a good way.</p>
<p>Corollary 3: We are fixing XWayland (or the way it processes events from Wayland).</p>
</div>
<divclass="section"id="learning-what-happens">
<h2>Learning what happens</h2>
<p>I continued reading, this time mostly <aclass="reference external"href="TODO">who-t's post series about custom
layouts</a>, <aclass="reference external"href="TODO">core Wayland protocol</a> as well as the source code of various
tools (<ttclass="docutils literal">xev</tt>, <ttclass="docutils literal">wev</tt>, <ttclass="docutils literal">xkbcli <spanclass="pre">interactive-wayland</span></tt>&c.) Given that I knew
very little about the inner workings of the stack, I wanted to find some code
that would be run and "enhance" it with so many debug prints that I would
understand what was the state of various parts of the Xwayland's "stacked xkb".
I kind of knew that one part of this is <em>somewhere</em> in the XWayland server,
whose code felt intimidating, so I wanted to determine where to start nudging
it from what APIs the clients use.</p>
<divclass="admonition tip">
<pclass="first admonition-title">Tip</p>
<p>Downloading various packages in Linux is rather simple, as well as their
rebuilding. In Arch, I can get the package's PKGBUILD just with <ttclass="docutils literal">yay <spanclass="pre">-G</span>
package</tt>, build it with <ttclass="docutils literal">makepkg</tt> and install it using <ttclass="docutils literal">yay <spanclass="pre">-U</span>
<spanclass="pre">package-….pkg.tar</span></tt>. Makepkg also has some options which allow me to tweak
the source code after downloading it and before building it.</p>
<pclass="last">Other distros are probably similar, e.g. for Debian-based distros one can
use <ttclass="docutils literal">apt source</tt>, <ttclass="docutils literal">debuild</tt> and <ttclass="docutils literal">apt install</tt> to do the same.</p>
</div>
<p>One interesting observation is that contrary to my expectation, XWayland does
not seem to use libxkbcommon (according to the <ttclass="docutils literal">/proc/PID/maps</tt> file). This
can have several reasons, but its source code also contains a slightly tweaked
version of (Xorg-style) xkb, which might mean I will be dealing with <aclass="reference external"href="TODO">the ugly
code</a> :-/ (Actually, XWayland might not process key events itself, instead
just passing them to clients, but this seems inconsistent with the issue – what
else would be introducing the second group switch?)</p>
<!-- understanding xev, XKeyEvents &c. -->
<!-- Note: neither xev is very barebones and does very little postprocessing of
events. (naturally.) -->
<!-- X11: state: 0x2000, sway: 0x4000 or 0x0. These state bits are *not*
mentioned in libX11 docs… (bits 13 and 14) -->
<!-- TO-MENTION:
- nested compositor issues
- the IM resolves compose? (I could bisect it, but too lazy)
- copy my issue comment in case link rots.
- list of all the packages I had downloaded and compiled -->