Should a Power-User Key Mapping Change Be This Difficult?

Post Syndicated from Bradley M. Kuhn original http://ebb.org/bkuhn/blog/2011/05/31/x.html

It’s been some time since X made me hate computing, but it happened
again today (well, yesterday into the early hours of today,
actually.

I got the stupid idea to upgrade to squeeze from lenny yesterday. I
was at work, but it was actually a holiday in the USA, and I figured it
would be a good time to do some sysadmin work instead of my usual
work.

I admittedly had some things to fix that were my fault: I had backports
and other mess installed, but upon removing, the upgrade itself was
more-or-less smooth. I faced only a minor problem with my MD device for
/boot not starting properly, but the upgrade warned me that I needed to
switch to properly using the UUIDs for my RAID arrays, and once I
corrected that, all booted fine, even with GRUB2 on my old hardware.

Once I was in X, things got weird, keyboard-wise. My meta and alt keys
weren’t working. BTW, I separate Alt from Meta, making my actual Alt key
into a meta key, while my lower control is set to an Alt (ala Mod2), since
I throw away caps lock and make it a control. (This is for when I’m on
the laptop keyboard rather than the HHKB.)

I’ve used the same xmodmap for two decades to get this done:

        keycode 22 = BackSpace
        
        clear Mod1
        clear Mod2
        clear Lock
        clear Control
        
        keycode 66  = Control_L
        
        keycode 64 = Meta_L
        keycode 113 = Meta_R
        keycode 37 = Alt_L
        keycode 109 = Alt_R
        
        add Control = Control_L
        
        add Mod1 = Meta_L
        add Mod1 = Meta_R
        
        add Mod2 = Alt_L
        add Mod2 = Alt_R
        

This just “doesn’t work” in squeeze (or presumably any Xorg
7.5 system). Instead, it just gives this error message:

        X Error of failed request:  BadValue (integer parameter out of range for operation)
          Major opcode of failed request:  118 (X_SetModifierMapping)
          Value in failed request:  0x17
          Serial number of failed request:  21
          Current serial number in output stream:  21
        

… and while my Control key ends up fine, it leaves me with no Mod1
nor Mod2 key.

There appear to be at least two Debian bugs
(564327
and 432011), which were
against squeeze before it was released. In retrospect, I sure wish
they’d have been release-critical!. (There’s also
an Ubuntu
bug
, which of course just punts to the upstream Debian bug.) There
are also two further upstream bugs at freedeskop
(20145
and
11822),
although Daniel
Stone
thinks the main
problem might be fixed upstream
.

I gather that many people “in the know” believe xmodmap to
be deprecated, and we all should have switched to xkb years ago. I even
got snarky comments to that
effect
. (Update🙂 However, after I made
this first post, quite angry after 8 hours of just trying to make my Alt
key DTRT, I was elated to see Daniel Stone
indicate that xmodmap should
be backwards compatible
. It’s always true that almost every time I
get pissed off about some Free Software not working, a developer often
shows up and tells me they want to fix it. This is in some ways just as
valuable as the thing being fixed: knowing that the developer doesn’t
want the bug to be there — it means it’ll be fixed eventually and
only patience is required.

However, the bigger problem really is that xkb appears to lack good
documentation. If any exists, I can’t find
it. madduck did this
useful blog post
(and,
later, vinc17 showed me
some docs he was working on too
). These are basically the only
things I could find that were real help on the issue, and they were
sparse. I was able to learn, after hours, that this should be the rough
equivalent to my old modmap:

        partial modifier_keys
        xkb_symbols "thinkpad" {
            replace key <CAPS>  {  [ Control_L, Control_L ] };
            modifier_map  Control { <CAPS> };
            replace key <LALT>  {  [ Meta_L ] };
            modifier_map Mod1   { Meta_L, Meta_R };
            key <LCTL> { [ Alt_L ] };
            modifier_map Mod2 { Alt_L };
        };
        

But, you can’t just load that with a program! No, it must be placed in
a file called /path/symbols/bkuhn, which it is then loaded with an
incantation like this:

        xkb_keymap {
                xkb_keycodes  { include "evdev+aliases(qwerty)" };
                xkb_types     { include "complete"      };
                xkb_compat    { include "complete"      };
                xkb_symbols   { include "pc+us+inet(evdev)+bkuhn(thinkpad)"     };
                xkb_geometry  { include "pc(pc105)"     };
        };
        

…which, in turn, requires to be fed into: xkbcomp -I/path
- $DISPLAY
as stdin. Oh, did I mention you have to get the
majority of that stuff above by running setxkbmap -print,
then modify it to add the bkuhn(thinkpad) part? I’m
impressed that madduck figured this all out. I mean, I know xmodmap was
arcane incantations and all, but this is supposed to be clearer
and better for users wanting to change key mappings? WTF!?!

Oh, so, BTW, my code in /path/symbols/bkuhn didn’t work. I tried every
incantation I could think of, but I couldn’t get it to think about Alt and
Meta as separate Mod2 and Mod1 keys. I think it’s actually a bug, because
weird things happened when I added lines like:

            modifier_map Mod5 { <META> };
        

Namely, when I added the above line to my /path/symbols/bkuhn, the Mod2
was then picked up correctly (magically!), but then both LCTL and LALT
acted like a Mod2, and I still had no Mod1! Frankly, I was too desperate
to get back to my 20 years of keystroke memory to try to document what was
going on well enough for a coherent bug report. (Remember, I was doing
all this on a laptop where my control key kept MAKING ME SHOUT INSTEAD OF
DOING ITS JOB.)

I finally got the idea to give up entirely on Mod2 and see if i could
force the literal LCTL key to be a Mod3, hopefully allowing Emacs to
again see my usual Mod1 Meta expectations for LALT. So, I saw what some
of the code in /usr/share/X11/xkb/symbols/altwin did to
handle Mod3, and I got this working (although it required a sawfish
change to expect Mod3 instead of Mod2, of course, but that part was 5
seconds of search and replace). Here’s what finally worked as contents
of /path/symbols/bkuhn:

        partial modifier_keys
        xkb_symbols "thinkpad" {
            modifier_map  Control { <CAPS> };
            replace key <LALT>  {  [ Meta_L ] };
            modifier_map Mod1   { Meta_L };
            key <LCTL> { type[Group1] = "ONE_LEVEL",
                         symbols[Group1] = [ Super_L ] };
            modifier_map Mod3 { Super_L };
        };
        

So, is all this really less arcane than xmodmap? Was the eight hours
of my life spent learning xkb was somehow worth it, because now I know a
better tool than xmodmap? I realize I’m a power user, but I’m not
convinced that it should be this hard even for power users. I felt
reminiscent of days when I had to
use Eric
Raymond’s mode timings howto to get X working
. That was actually
easier than this!

Even though spot claimed
this is somehow Debian’s fault
, I don’t believe him. I bet I
would run into the same problem on any system using Xorg 7.5. There
are clearly known bugs in xmodmap, and I think there is probably a
subtle bug I uncovered that exist xkbd, but I am not sure I can
coherently report it without revisiting this horrible computing
evening again. Clearly, that first thing I tried should have not made
two keys be a Mod2, but only when I moved META into Mod5, right?

BTW, If you’re looking for me online tomorrow early, you hopefully know
where I am. I’m going to bed two hours before my usual waketime. Ugh.
(Update: tekk
later typo’ed xmodmap as ’xmodnap‘ on identi.ca
.
Quite fitting; after working on that all night, I surely needed an xmodnap!

Update on 2013-04-03: I want to note that the X11 and now
Wayland developer
named Daniel
Stone
took an interest in this bug and actually followed up with me two
years later giving me a report. It is apparently really hard to fix
without a lot of effort, and I’ve switched to xkb (which I think is even
more arcane), but mostly works, except when I’m in Xnest. But my main
point is that Daniel stuck with the problem and while he didn’t get
resolution, he kept me posted. That’s a dedicated Free Software developer;
I’m just a random user, after all!