Skip Navigation

[Rant] Why is there no sane way to remap keys?

I recently switched to Hyprland on my laptop and was able to set it up as I like, but I struggle hard to set up keybinds to simply print different characters when pressing certain key combinations.

For example, one small snippet from my .Xmodmap (there are more in this file but that’s enough for a minimal working example)

keycode 108 = Mode_switch
keycode 38 = a A adiaeresis Adiaeresis

This allows me to press the A key in combination with the right Alt key to print an ä or an Ä when shift is pressed, to.

wtype and built-in key binding

After some research I found wtype which allows me to write arbitrary text when called with the parameters.

After I learned that Hyprland (or Wayland) does not distinguish between Alt_R and Alt_L (they’re shown as Alt_R and Alt_L in wev with different keysyms, so they’re clearly two different keys) and I accepted it, I just found out that this tool only works when being in a terminal emulator and not in a GUI application so this tool is useless for me.

keyd

Then I tried keyd. After setting it up and adding my user to the needed groups and starting the service and trying to figure out how to actually define keymaps I was able to send something when pressing a defined key combination.

But: Nothing else than ASCII.

The dev thinks it’s a Chromium problem based on this issue but it actually isn’t. I wasn’t able to send an ä to ANY application, no matter if GUI or terminal or Qutebrowser.

Since there is basically no online resources or user community for this tool, I cannot find any usable information on this issue except the unrelated Chrome reference and thus I removed it again because I cannot use it for what I want to use it for.

xkb

For whatever reason Wayland (or Hyprland) uses certain parts of the X keyboard extension, so I also tried this one.

Despite being absurdly complex and annoying to setup I was able to configure a user based keyboard variant using user-based symbols. From what I’ve taken from various sites my config should do nothing more than remapping Alt_R to ISO_Layer3_Shift just for testing purposes.

But all I achieved was reproducibly crashing Hyprland when setting it up to actually use said keyboard variant and there seems to be no log file.

yeah, that’s where we are

Again, it’s not about the umlauts, and not about the German keyboard layout, and not about switching lkayouts on-the-fly, it’s just to demonstrate what I mean. You can replace ä with any other character you want.

After a long night of trying out to have the Xmodmap functionality in Wayland using Hyprland as compositor I ended up with not being successful.

I give up for now.

Maybe one day there will be an actually working solution requiring nothing more than two lines in a file.

1
1 comments
  • Sooooo … There is an update on this rant – or a solution. I took the time and learned the absolute minimum and basics of xkb. And after a lot of crashes with proper error messages and trying quite some time I was able to replicate my current .Xmodmap using xkb and implement it as custom layout.

    Since sharing is caring, here is the fully documented file.

    // vim:syntax=xkb
    
    
    // Manually cobbled together using those sources:
    //
    // https://github.com/hardfau1t/dotfiles/blob/main/xkb/.config/xkb/symbols/cust
    // https://github.com/swaywm/sway/issues/4250
    // https://www.charvolant.org/doug/xkb/html/node5.html
    // The file /usr/share/X11/xkb/symbols/us
    //
    // Set up for and tested with a Dell XPS 13 9380 laptop, but it should work
    // With any keyboard variant. Just include the correct variant and change the
    // keys accordingly.
    //
    // Place this in the file `${HOME}/.xkb/symbols/custom-bindings`
    //
    // For Hyprland set this in the config (other compositors or WMs might have
    // something similar where you can define the keyboard layout):
    //
    //     input {
    //        kb_layout = custom-bindings
    //        [more/other input configuration]
    //     }
    //
    // NOTE: If it crashes, some of the configuration is wrong or could not be
    //       properly loaded. Unfortunately there aren’t useful logs. Try to
    //       comment out individual parts of this file until it stops crashing,
    //       then start over from there adding one section/line after another
    //       and reload and test the configuration.
    //
    // GOOD LUCK! :)
    
    
    // Layout definition
    //
    // The layout uses the basic US layout and the level3 ralt_switch to make the
    // right ALT key actually usable as level3 switch (referred to as AltGr from
    // now on).
    //
    // All the other includes are referring to this file. If you do not use the US
    // layout, make sure to adapt the key definitions in the other sections.
    //
    // In `/usr/share/X11/xkb/symbols` you’ll find the variants. This file uses the
    // variant `us`. Again: Just open your matching symbols file, there you’ll see
    // all the sections in similar syntax, just take from there what you need.
    default partial alphanumeric_keys
    xkb_symbols "basic" {
        name[Group1]= "English (US, RALT, customizations)";
        include "us"
        include "level3(ralt_switch)"
        include "custom-bindings(umlauts)"
        include "custom-bindings(quotation-marks)"
        include "custom-bindings(punctuation)"
        include "custom-bindings(script-numbers)"
    };
    
    
    // German umlauts
    //
    // The corresponding base letters with AltGr and Caps+AltGr return the umlaut
    // types of that letter. Also the sparsely used “uppercase ß” is available
    // with AltGr+Caps+s
    //
    // äÄ   öÖ   üÜ   ßẞ
    xkb_symbols "umlauts" {
        key  {[  a , A , adiaeresis , Adiaeresis  ]};
        key  {[  o , O , odiaeresis , Odiaeresis  ]};
        key  {[  u , U , udiaeresis , Udiaeresis  ]};
        key  {[  s , S , ssharp     , U1E9E       ]};
    };
    
    
    // Quotation marks
    //
    // z and x pressed with AltGr or AltGr+Caps create outer („“) and inner (‚‘)
    // German quotation marks.
    //
    // c and v do the same for the English quotation marks (“” and ‘’).
    //
    // z, x = „“ & ‚‘   c, v = “” & ‘’
    xkb_symbols "quotation-marks" {
        key  {[  z , Z , doublelowquotemark   , singlelowquotemark    ]};
        key  {[  x , X , leftdoublequotemark  , leftsinglequotemark   ]};
        key  {[  c , C , leftdoublequotemark  , leftsinglequotemark   ]};
        key  {[  v , V , rightdoublequotemark , rightsinglequotemark  ]};
    };
    
    
    // Punctuation characters
    //
    // When pressed with AltGr the following symbols are returned.
    //
    // -   “Halbgeviertstrich”, a type of dash used as replacement for various
    //     other punctuation in German (–), identical to an “en dash” character.
    //
    // +   typographically correct apostrophe (’)
    //
    // .   Ellipsis character (…).
    xkb_symbols "punctuation" {
        key  {[  minus      , underscore , U2013     ]};
        key  {[  apostrophe , quotedbl   , U2019     ]};
        key  {[  period     , greater    , ellipsis  ]};
    };
    
    
    // Subscript and superscript numbers
    //
    // When pressing the numbers from the numbers row with AltGr or AltGr+Caps,
    // numbers are returend in subscript (AltGr) or superscript (AltGr+Caps).
    //
    // AltGr+Number      = Text ₁₂₃₄₅₆₇₈₉₀ more text
    // 
    // AltGr+Caps+Number = Text ¹²³⁴⁵⁶⁷⁸⁹⁰ more text
    xkb_symbols "script-numbers" {
        key  {[  1, exclam      , U2081 , U00B9  ]};
        key  {[  2, at          , U2082 , U00B2  ]};
        key  {[  3, numbersign  , U2083 , U00B3  ]};
        key  {[  4, dollar      , U2084 , U2074  ]};
        key  {[  5, percent     , U2085 , U2075  ]};
        key  {[  6, asciicircum , U2086 , U2076  ]};
        key  {[  7, ampersand   , U2087 , U2077  ]};
        key  {[  8, asterisk    , U2088 , U2078  ]};
        key  {[  9, parenleft   , U2089 , U2079  ]};
        key  {[  0, parenright  , U2080 , U2070  ]};
    };