Remapping Keys on Sway

3 minute read Published 8 May 2022

A simple way to remap keys on Sway WM.

I recently started using a Hewlett Packard SK-2026 keyboard with my laptop. It has a fairly standard layout except for one thing – there is a Home Home key where the Windows Windows key usually is.

Hewlett Packard SK-2026 Keyboard close-up of bottom left keys Based on a Japanese article about the HP Slate 21, it seems to be a variant for use with mobile devices. The Home key would open the Android launcher.

Problem🔗

I use the Sway tiling window manager on Linux and having a Windows key is essential to my workflow. It maps to Super_L whereas the Home key maps to XF86HomePage and redirects the browser to the homepage. It is not a modifier key and thus cannot be used in lieu of Super_L.

There must be a way to remap the Home key so it appears as Super_L instead.

Solution🔗

Xorg🔗

Xmodmap is a utility for modifying key and mouse mappings in the Xorg (aka X) display server. However, I am using Wayland so this wouldn’t work for me.

Wayland🔗

There isn’t a great unified solution for remapping keys on Wayland. It still has a lot of room for improvement before it can be on par with Xorg. The easiest approach I found was to replace the keycode’s mapping in XKB.

  1. Install aur/wev.
  2. Get the keycode for the Home key using wev.
    [14:     wl_keyboard] key: serial: 27025; time: 16170860; key: 180; state: 1 (pressed)
                        sym: XF86HomePage (65515), utf8: ''
    [14:     wl_keyboard] key: serial: 27027; time: 16170940; key: 180; state: 0 (released)
                        sym: XF86HomePage (65515), utf8: ''
    
    It is 180 for this keyboard.
  3. Find the key’s mapping in /usr/share/X11/xkb.
    $ grep -r -e 'key.*180.*>' /usr/share/X11/xkb/
    symbols/inet:    key <I180>   {      [ XF86HomePage          ]       };
    
  4. Change it to Super_L.
    $ sed -i 's|key <I180>   {      [ XF86HomePage|key <I180>   {      [ Super_L     ' /usr/share/X11/xkb/symbols/inet
    
  5. Reload Sway, and the key is mapped correctly according to wev.
     [14:     wl_keyboard] key: serial: 33081; time: 17356569; key: 180; state: 1 (pressed)
                         sym: Super_L      (65515), utf8: ''
     [14:     wl_keyboard] modifiers: serial: 0; group: 0
                         depressed: 00000040: Mod4
                         latched: 00000000
                         locked: 00000000
     [14:     wl_keyboard] key: serial: 33083; time: 17356625; key: 180; state: 0 (released)
                         sym: Super_L      (65515), utf8: ''
     [14:     wl_keyboard] modifiers: serial: 0; group: 0
                         depressed: 00000000
                         latched: 00000000
                         locked: 00000000
    

Note that this changes the mapping for keycode 180 on any keyboard. It is possible that it could affect a keyboard with a Home key in a more traditional position i.e. in a multimedia section or as an alternate Function key action.

The X in XKB🔗

There is something odd though: XKB stands for the X keyboard extension, but Sway is on Wayland. Sway uses wlroots for Wayland building blocks. This further uses libxkbcommon to parse and handle keyboard layouts. This library implements the XKB specification and does not have any relation with the X server itself. The symbols in /usr/share/X11/xkb are distributed in the xkeyboard-config package.

Comment Icon Comments🔗