Mapping right-Alt to Meta (Windows/Super) key

I tried mapping right-Alt to Meta with xmodmap, and xev reports that it works (it sees “Super_L”) but I don’t get the menu that I get when pressing the Windows key on a keyboard that actually has a Windows key.

(I’m trying to use an old IBM Model M keyboard without a Windows key, but I have a modern keyboard to test with.)

Here’s my .Xmodmap:

keycode 108 = Super_L
keycode 105 = Menu

And some output from xev when I press right-Alt:

KeyPress event, serial 40, synthetic NO, window 0x3c00001,
    root 0x20e, subw 0x0, time 219420412, (64,150), root:(2535,773),
    state 0x0, keycode 108 (keysym 0xffeb, Super_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3c00001,
    root 0x20e, subw 0x0, time 219420508, (64,150), root:(2535,773),
    state 0x8, keycode 108 (keysym 0xffeb, Super_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

So it seems like it ought to be working, but it’s not.

I’m running:

dave@MONOLITH:~$ uname -a
Linux MONOLITH 6.2.0-37-generic #38~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov  2 18:01:13 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
dave@MONOLITH:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Neon
Description:    KDE neon 5.27
Release:        22.04
Codename:       jammy
1 Like

It turns out xmodmap can not do this, at least on the keyboard I have and on KDE Plasma. (It works OK for mapping other keys, but not for the Alt-to-Meta mapping.)

But I got it working another way. It was difficult. I’m going to explain how I did it the best I can.

I remapped right-Alt on an IBM Space Saver Keyboard (SSK), which is the compact version of the Model M, connected via a PS/2-to-USB converter.

I used the method at Wyatt's Blog: Unicomp Mini M Review, Keyboard Remapping

(If that link dies, I suggest finding it via the Wayback Machine).

You’d better read that first, for the rest of this to make any sense.

The hardest part was figuring out which device in /sys/devices/ was my keyboard.

To do that:

1 - I ran sudo evtest. That gave me:

Available devices:
/dev/input/event0:      Sleep Button
/dev/input/event1:      Power Button
/dev/input/event2:      Power Button
/dev/input/event3:      Video Bus
/dev/input/event4:      MSI MYSTIC LIGHT 
/dev/input/event5:      HDA Intel PCH HDMI/DP,pcm=3
/dev/input/event6:      HDA Intel PCH HDMI/DP,pcm=7
/dev/input/event7:      HDA Intel PCH HDMI/DP,pcm=8
/dev/input/event8:      HDA Intel PCH HDMI/DP,pcm=9
/dev/input/event9:      HDA NVidia HDMI/DP,pcm=3
/dev/input/event10:     HDA NVidia HDMI/DP,pcm=7
/dev/input/event11:     HDA NVidia HDMI/DP,pcm=8
/dev/input/event12:     HDA NVidia HDMI/DP,pcm=9
/dev/input/event13:     PixArt USB Optical Mouse
/dev/input/event14:     3Dconnexion SpaceNavigator
/dev/input/event15:     Wacom Intuos S Pen
/dev/input/event16:     Wacom Intuos S Pad
/dev/input/event17:     ID Innovations Inc. Input Device
/dev/input/event18:     UVC Camera (046d:0990)
/dev/input/event19:     Keychron Keychron V3
/dev/input/event20:     Keychron Keychron V3 Mouse
/dev/input/event21:     Keychron Keychron V3 System Control
/dev/input/event22:     Keychron Keychron V3 Consumer Control
/dev/input/event23:     Keychron Keychron V3 Keyboard

(Your output will differ depending on hardware in your system.)

Try to guess which of the event* devices is your keyboard. Give evtest the number you guessed (in this case 0 to 23) and press a few keys - when you see some keyboard output from evtest, you’ve found it.

With a little trial-and-error, using evtest that way indicated that device ‘event17’ is my SSK keyboard. “ID Innovations Inc. Input Device” is the PS2-to-USB converter’s USB name (again, yours may differ).

With that info, I took the output from find /sys/ -iname *modalias|grep input to see the list of devices at the /sys/devices level. That gave me:

/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input7/modalias
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input5/modalias
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input8/modalias
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input6/modalias
/sys/devices/pci0000:00/0000:00:1f.3/sound/card0/input9/modalias
/sys/devices/pci0000:00/0000:00:1f.3/sound/card0/input12/modalias
/sys/devices/pci0000:00/0000:00:1f.3/sound/card0/input10/modalias
/sys/devices/pci0000:00/0000:00:1f.3/sound/card0/input11/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.3/1-7.3:1.2/0003:3434:0331.000A/input/input24/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.3/1-7.3:1.2/0003:3434:0331.000A/input/input22/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.3/1-7.3:1.2/0003:3434:0331.000A/input/input23/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.3/1-7.3:1.2/0003:3434:0331.000A/input/input21/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.3/1-7.3:1.0/0003:3434:0331.0008/input/input20/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.3/1-5.3.3/1-5.3.3:1.0/0003:046D:C626.0005/input/input14/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.3/1-5.3.1/1-5.3.1:1.0/0003:056A:0374.0003/input/input17/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.3/1-5.3.1/1-5.3.1:1.0/0003:056A:0374.0003/input/input15/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.3/1-5.3.2/1-5.3.2:1.0/0003:04F2:0939.0004/input/input13/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.4/1-5.4.4/1-5.4.4:1.0/0003:154A:0002.0006/input/input18/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.4/1-5.4.1/1-5.4.1:1.0/input/input19/modalias
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:1462:7D30.0001/input/input4/modalias
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input1/modalias
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00/input/input0/modalias
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00/input/input3/modalias

The question is: Which of those is the SSK keyboard?

As stated in the Wyatt’s Blog post, the directory that contains each of the files listed above has a file called ‘name’ which contains the USB name of the device (in my case the USB name of the PS2-to-USB converter, “ID Innovations Inc. Input Device”). When you find that directory, you can look at the ‘modalias’ in that directory for the next step.

To find that, do:

find /sys/ -iname '*name' -type f -exec grep '<string>' {} +

Replace with part of the USB device name you’re looking for. I used:

find /sys/ -iname '*name' -type f -exec grep 'Innovations' {} +

Ignore any error messages; just look for the line that contains the USB name you’re looking for. I got:

$ find /sys/ -iname '*name' -type f -exec grep 'Innovations' {} +
find: ‘/sys/kernel/tracing’: Permission denied
find: ‘/sys/kernel/debug’: Permission denied
find: ‘/sys/fs/pstore’: Permission denied
find: ‘/sys/fs/bpf’: Permission denied
find: ‘/sys/fs/fuse/connections/50’: Permission denied
find: ‘/sys/fs/fuse/connections/49’: Permission denied
grep: /sys/devices/pci0000:00/0000:00:14.3/net/wlo1/phys_port_name: Operation not supported
grep: /sys/devices/pci0000:00/0000:00:1c.1/0000:04:00.0/net/enp4s0/phys_port_name: Operation not supported
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.4/1-5.4.4/1-5.4.4:1.0/0003:154A:0002.0009/input/input23/name:ID Innovations Inc. Input Device
grep: /sys/devices/virtual/net/lo/phys_port_name: Operation not supported

That’s telling you where to find the modalias file - in this case in sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.4/1-5.4.4/1-5.4.4:1.0/0003:154A:0002.0009/input/input23/.

(Yes, I know this is “input23” while above we had “event17”. I guess the numbers don’t necessarily match.)

So then cat the ‘modalias’ file in that folder. I got:

$ cat /sys/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.4/1-5.4.4/1-5.4.4:1.0/0003:154A:0002.0009/input/input23/modalias
input:b0003v154Ap0002e0100-e0,1,4,11,14,k74,75,77,7D,7E,7F,B7,ram4,l0,1,2,3,4,sfw

As per the blog post, you need the output up to (and excluding) the first dash - in my case ‘input:b0003v154Ap0002e0100’.

With that, I created a file ‘/etc/udev/hwdb.d/remap_ibmssk.hwdb’ as follows:

evdev:input:b0003v154Ap0002e0100*
 KEYBOARD_KEY_700e6=KEY_RIGHTMETA

Note I had to add the * at the end of the first line. The value after KEYBOARD_KEY comes from evtest as described in the Wyatt’s Blog post.

‘KEY_RIGHTMETA’ comes from include/linux/input-event-codes.h (google for it). It also works if you put in the numeric value instead (in this case that would be 126).

Then:

dave@MONOLITH:~$ sudo systemd-hwdb update
dave@MONOLITH:~$ sudo udevadm control --reload-rules
dave@MONOLITH:~$ sudo udevadm trigger

…and it works!

Simple? No. But possible? Yes.

2 Likes

Added 11 days later:

For reasons I don’t understand, that worked for a while then stopped working.

Changing the file /etc/udev/hwdb.d/remap_ibmssk.hwdb to use the numeric value of the key (in this case ‘126’ instead of ‘KEY_RIGHTMETA’) makes it work OK. So, here’s my new ‘/etc/udev/hwdb.d/remap_ibmssk.hwdb’:

evdev:input:b0003v154Ap0002e0100*
 KEYBOARD_KEY_700e6=126

To be as clear as I can: the value to the left of the = sign (700e6) is from evtest; it’s the value of the key you want to press (700e6 is the right-Alt on my IBM SSK keyboard). The value to the right of the = sign (126) is the key you want generated when you press.

That value comes from include/linux/input-event-codes.h , one of the header files used to build the Linux kernel. Google on that to find a copy, but as I write this post, one copy is here (I think it’s Linus Torvald’s github account):

The relevant portion where I got the ‘126’ value is this:

#define KEY_KPCOMMA		121
#define KEY_HANGEUL		122
#define KEY_HANGUEL		KEY_HANGEUL
#define KEY_HANJA		123
#define KEY_YEN			124
#define KEY_LEFTMETA		125
#define KEY_RIGHTMETA		126
#define KEY_COMPOSE		127

Isn’t there a relevant option for this in keyboard settings?

1 Like

You’d think so, wouldn’t you?