I am trying to remap the keys found on a Japanese keyboard to be Alt, Super, Return, and Shift. Here is a good description of the kind of keyboard I'm using. (I am actually using a Filco Majestouch 2 TKL Japanese keyboard). The idea is to have a perfectly normal English keyboard where the extra keys under the thumbs are remapped to Alt, Return, etc. I am doing this using xkb under Ubuntu.

The keyboard's bottom row looks like this:

<LCTL> <LWIN> <LALT> <MUHE> <SPCE> <HENK> <HKTG> <RALT> <MENU> <RCTL>

I'd like it to look like this:

<LCTL> <LALT> <LWIN> <LALT> <SPCE> <RALT> <RTRN> <MENU> <RALT> <RCTL>

Remapping LWIN, LALT, RALT, and MENU worked, but remapping MUHE, HENK, and HKTG hasn't.

On top of this I tried remapping AB11 to Shift_R and AE13 to BackSpace. The result is that AB11 does nothing just like MUHE, HENK, and HKTG, but AE13 did get remapped to BackSpace and works as intended.

Until now I've been using the basic keycodes defined (as I understand) in /usr/share/X11/xkb/keycodes/xfree86. Because of this, my keyboard layout's symbols file started like this:

default
xkb_symbols "basic" {

Since MUHE, HENK, HKTG, AB11, and AE13 are defined in /usr/share/X11/xkb/keycodes/evdev, I assumed I should change that to evdev, but that did not help:

default
xkb_symbols "evdev" {

Is there anything else I need to do in order to use MUHE etc? Do I need to ensure some other part of the input system uses evdev? I am not sure how to do that. I am on Ubuntu 14.04 32-bit, but the same behavior happens on 18.04 64-bit.

Here is the full code I use to remap those keys (I omitted unrelated parts of the layout):

default
xkb_symbols "evdev" {
    // Swap Caps Lock and Escape.
    key <CAPS> {        [       Escape  ]       };
    // key <ESC>  {        [     Caps_Lock    ]       };
    key <ESC> { type[Group1]="TWO_LEVEL", [ Multi_key, Multi_key ] };

    key <LWIN> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Alt_L ]
    };

    key <LALT> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Super_L ]
    };

    key <MUHE> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Alt_L ]
    };
    // placeholder for <SPCE>

    key <HENK> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Alt_R ]
    };

    key <HKTG> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Return ]
    };

    key <RALT> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Menu ]
    };

    key <MENU> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Alt_R ]
    };

    // LSGT is the extra key in the European layout that is found between the
    // left Shift and Z.
    key <LSGT> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Super_L ]
    };


// Japanese keyboard bottom row:
// <LCTL> <LWIN> <LALT> <MUHE> <SPCE> <HENK> <HKTG> <RALT> <MENU> <RCTL>
// Desired bottom row:
// <LCTL> <LALT> <LWIN> <LALT> <SPCE> <RALT> <RTRN> <MENU> <RALT> <RCTL>

// Other extra Japanese keys:

// Between / and right shift: <AB11>
    key <AB11> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        Shift_R ]
    };

// Between = and Backspace: <AE13>
    key <AE13> {
        type[Group1]="ONE_LEVEL",
        symbols[Group1]=[        BackSpace ]
    };

// Modifier numbers:
// Mod1 = Alt
// Mod2 = Num_Lock
// Mod4 = Super
// Mod5 = ISO Level3 Shift
// Shift = Shift

// <AB11> is Shift
    modifier_map Shift { Shift_L, Shift_R };
// <LALT> is Super, <LSGT> is Super too
    modifier_map Mod4 { Super_L, Super_R };
// <MENU> is Alt, <LWIN> is Alt too
    modifier_map Mod1 { Alt_L, Alt_R };
// we map a bunch of keys to ISO Level3 Shift
    modifier_map Mod5 { ISO_Level3_Shift };
};

Edit: turns out the code I posted above is (mostly?) correct, however some mechanism in xkb that is meant for enabling "multimedia" keys and other "unusual" keys clobbers the mappings above. The bottom row buttons work now, but the AB11 key still does not perform as an additional Shift key. Still, that is some progress.

Here is a description of this "inet" clobbering happening. The listing below shows that it happens in my case, too:

$ setxkbmap ef -print
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete"  };
    xkb_compat    { include "complete"  };
    xkb_symbols   { include "pc+ef+inet(evdev)" };
    xkb_geometry  { include "pc(pc105)" };
};

Note the bit that says: xkb_symbols { include "pc+ef+inet(evdev)" };. That means that it first applies the normal pc layout (US QWERTY), then whatever layout I have selected (here called ef, though I didn't call it that, I guess it's just a variable name that's reused for all layouts), and then inet(evdev) is applied. Inside symbols/inet, you can find this block:

xkb_symbols "evdev" {
    key <HKTG>   {      [ Hiragana_Katakana     ]       };
    key <HENK>   {      [ Henkan                ]       };
    key <MUHE>   {      [ Muhenkan              ]       };

and apparently this gets applied because my keyboard is an "inet keyboard"; in rules/base you can find this:

! $inetkbds = acer_c300 acer_ferrari4k acer_laptop \
...
              pc105 \
...

as well as further down this block:

  $inetkbds     =       +inet(%m)

So now the question is how to make my keyboard not get seen as an inet keyboard?

Or alternatively, could this be what's causing it? Inside rules/evdev, there is this block:

! model     =   symbols
  $evdevkbds    =   +inet(evdev)+inet(%m)
  applealu_jis  =   +inet(evdev)+macintosh_vndr/jp(alujiskeys)
  *             =   +inet(evdev)

The last line would apparently mean that no matter what keyboard you have, if you base your keyboard layout on evdev by doing xkb_symbols "evdev" {, you always get inet(evdev) added in the end, overriding your symbols.

I don't know xkb well enough to know which is the case, so some guidance would be greatly appreciated.

I still don't know why I can't remap AB11. Is something still missing? I define AB11 as Shift_R and then give it the Shift ability via modifier_map Shift { Shift_L, Shift_R };. Yet in xev, when I press this button, it does indeed get recognized as Shift_R, but state is still 0x0 (no modifiers), rather than 0x1 (Shift) which it should be:

KeyPress event, serial 38, synthetic NO, window 0xdc00001,
    root 0x1ef, subw 0x0, time 1701230053, (441,592), root:(444,729),
    state 0x0, keycode 97 (keysym 0xffe2, Shift_R), same_screen YES,
    XKeysymToKeycode returns keycode: 62
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

There doesn't seem to be anything overriding this key (or any other key with the same keycode) in inet(evdev).

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.