Skip to content

Instantly share code, notes, and snippets.

@santileortiz
Created October 16, 2018 13:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save santileortiz/31ee0787de0dc7579e5612207ae24f9e to your computer and use it in GitHub Desktop.
Save santileortiz/31ee0787de0dc7579e5612207ae24f9e to your computer and use it in GitHub Desktop.
The syntax for setting up a third level key in a .xkb file seems to be vey
picky, I still need to explore more xkbcomp's source code to know how things
work.
I noticed this because recently the way I used to define the AltGr key in my
custom layout stopped working. I'm not sure which commit in which project
caused this to stop working, could have been libxkbcommon (xkbcomp), xserver,
Gdk among others. What I do know is that suddenly pressing AltGr would set
GDK_MOD1_MASK in the received key release event. This modifier is treated by
Gdk (Together with GDK_CONTROL_MASK) as one that will NEVER serve to translate
a keycode into a keysym as its intent is GDK_MODIFIER_INTENT_NO_TEXT_INPUT.
This makes Gdk bail out in the translation of any keysym in the third level.
I tracked the bug down through several projects, by comparing my custom layout
with the latam layout that worked fine in all cases. In the end I discovered it
was an issue with the syntax I was using to assign the <RALT> key in my custom
layout.
xkb_symbols "basic" {
// Does not work
//key <RALT> {
// type= "TWO_LEVEL",
// symbols[Group1]= [ ISO_Level3_Shift, Meta_R ]
//};
// Does not work
//key <RALT> {
// type[Group1]= "TWO_LEVEL",
// symbols[Group1]= [ ISO_Level3_Shift, Meta_R ]
//};
// Does not work
//key <RALT> {
// type="ONE_LEVEL",
// symbols[Group1]= [ ISO_Level3_Shift ]
//};
// Works fine
key <RALT> {
type[Group1]="ONE_LEVEL",
symbols[Group1]= [ ISO_Level3_Shift ]
};
modifier_map Mod5 { <LVL3> };
modifier_map Mod1 { <LALT>, <META> };
};
I tested these symbols by using libxkbcommon's test suite. I added the symbols
into the file <libxkbcommmon repo>/test/data/altgr_decl_test. Then I tested
each of the 4 declarations for <RALT> by uncommenting it and running the
print-compiled-keymap test as follows:
$ cd <libxkbcommmon repo>
$ ./build/print-compiled-keymap -l altgr_decl_test,us
The expected modifier mapping for Mod1 is
modifier_map Mod1 { <LALT>, <META> };
but in all non-working options I got
modifier_map Mod1 { <LALT>, <RALT>, <META> };
The issue seems to be related to how different layouts are merged into each
other. Even though in the example above it looks like nothing is being merged,
two things have to be taken into account:
1. All layouts by default use the "pc" layout as base, so everything gets
merged on top of it.
2. In elementary OS to make keybindings work in internationalized keyboards
we copied a hack from GNOME, where the "us" layout is added in the last
group (which is why I tested with '-l altgr_decl_test,us' and not just
'-l altgr_decl_test'). Then, when an application is trying to match a
keybinding, it can lookup through all groups and the "us" keysym will be
the fallback. I think GNOME doesn't do this anymore, so elementary
shouldn't either, but last time I checked this was still being used.
As a result of this, until I have a better understanding of why only the last
declaration works fine, I'll make the following assumptions:
- A custom keyboard layout will usually be merged with other ones. I need
to test at least against "pc" and "us".
- A modifier key MUST be declared as above. Which means all modifier keys
will be of type ONE_LEVEL.
NOTE: I should create better tools to explore these kinds of issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment