Score:0

Linux and XKB workaround for additional Control_L event when pressing AltGr on Linux desktop over VMWare Horizon

de flag

I'm trying to find a fix for a keyboard issue when connecting to a Linux desktop using VMWare Horizon View. The issue seems to be known, and was described in 2012 on VMWare's knowledge base, available on archive.org. I have to add that I don't know much about how XKB works, so digging into this has been a learning experience.

The workarounds listed on the VMWware KB aren't satisfactory. I can confirm the description given, that there's an additional unwanted Control_L character when I hit AltGr. When I press AltGr+7 I expect a {, but instead I get an escape character 0x1b. This is what it looks like when running xev and hitting AltGr+7 (ISO_Level3_Shift is the expected keypress when hitting AltGr).

KeyPress event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444939915, (157,43), root:(388,257),
    state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444939920, (157,43), root:(388,257),
    state 0x4, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
    XKeysymToKeycode returns keycode: 92
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444944595, (157,43), root:(388,257),
    state 0x84, keycode 16 (keysym 0x7b, braceleft), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
mbLookupString gives 1 bytes: (1b) "
FilterEvent returns: False

KeyRelease event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444944763, (157,43), root:(388,257),
    state 0x84, keycode 16 (keysym 0x7b, braceleft), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
FilterEvent returns: False

KeyRelease event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444951582, (157,43), root:(388,257),
    state 0x84, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 37, synthetic NO, window 0x3000001,
    root 0x521, subw 0x0, time 2444951586, (157,43), root:(388,257),
    state 0x80, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
    XKeysymToKeycode returns keycode: 92
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

There's a suggestion on the VMWare KB to press AltGr, and then press and release the left Ctrl to trigger a KeyRelease event for Control_L, after which I can press 7 and get the output I'm looking for: XLookupString/XmbLookupString in that case return 7b, which is { as expected.

So after confirming the problem, I've looked into workarounds in Linux. I ran xkbcomp to get the live keymap definition by running:

xkbcomp $DISPLAY out.xkb

After looking at the generated out.xkb, I figured it might be possible to redefine my keymappings to expect Control_L in addition to the other keys. So to select some relevant parts, my out.xkb contained:

xkb_types "complete" {
...
  type "FOUR_LEVEL" {
    modifiers= Shift+LevelThree;
    map[Shift]= Level2;
    map[LevelThree]= Level3;
    map[Shift+LevelThree]= Level4;
  };
};
...
xkb_symbols "pc+no+inet(evdev)" {
...
  key <AE07> {
    type= "FOUR_LEVEL",
    symbols[Group1]= [    7,    slash,    braceleft,    division ]
  };
...
}

The braceleft in the above definition is what I'm trying to get to work right now. My idea was to simply redefine FOUR_LEVEL to expect Control_L in the appropriate cases, like this:

  type "FOUR_LEVEL" {
    modifiers= Shift+LevelThree+LControl;
    map[Shift]= Level2;
    map[LevelThree+LControl]= Level3;
    map[Shift+LevelThree+LControl]= Level4;
  };

I created a mapping with this setup, and then I tried to compile and load my modified file:

xkbcomp ctrl-hack.xkb
xkbcomp ctrl-hack.xkm $DISPLAY

Unfortunately, my changes don't seem to work as I had hoped. I don't get any errors, but I still get the 0x1b instead of { character when I hit AltGr+7. What could be going wrong?

Alternatively, I see that some other characters (like and $) seem to work despite also requiring the AltGr modifier, and receiving an additional unexpected Control_L. But testing while manually pressing Control_L, I see that works both with and without Control_L being pressed, so there seems to be some fallback definition for this symbol that isn't explicit in the xkbcomp output. I haven't figured out how this works yet. Is it possible to define similar fallbacks for the symbols I'm missing? Perhaps some sort of inheritance from console keyboard configuration, for instance? This would probably come from the same place as the 0x1b character that I receive when pressing Ctrl-AltGr-7. I can't find it in the XKB-config, so it has to be defined somewhere else.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.