Haven't use Fedora or Gnome (or XFCE) for that purpose for a long time. But remapping keys to functions happen on several layers, and doing it at WM layer is troublesome in my humble opinion. Key strokes/codes come from kernel (from IRQs in hardware, etc) to Xorg, which numbers all of them and passes back to applications (whether is passes all of them to the applications is another story).
The applications that Xorg passes the key codes include the WMs (XFCE or Gnome or even KDE), and the windows open by those applications. What the tools like keymapping desktop apps do, is that they tap in the keycode configuration of Xorg. Either by creating new keyboards (
setxkbmap) modifying keys (
xmodmap) or even remapping in memory before re-sending the code to a windows (IMEs).
If we tap into the Xorg keycodes ourselves we can configure the keyboard for any system (that runs Xorg that is). I'll use my own keyboard:
The outline shows a key that I'll use as an example, the one with a musical note. We will make that key work as an up arrow.
First let's have a look how Xorg sees my keyboard:
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Logitech USB Optical Mouse id=10 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=14 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Power Button id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ USB 2.0 Camera id=11 [slave keyboard (3)]
↳ Asus Laptop extra buttons id=12 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=13 [slave keyboard (3)]
Well yeah, I guess that my key (the musical note) is in "Asus Laptop extra buttons". Which means that it is under the Virtual Keyboard. Good, that means that I can use
xev in the following way to find its keycode:
xev -event keyboard
If it was not part of the virtual keyboard I would need to go through all events (including mice events) which would make it hard to find, not impossible but hard. I then pres my musical note key whilst
xev is running and find that Xorg understands it as follows:
KeyPress event, serial 28, synthetic NO, window 0x1a00001,
root 0x496, subw 0x0, time 32080036, (381,333), root:(382,352),
state 0x0, keycode 234 (keysym 0x1008ff32, XF86AudioMedia), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
Good, that means it is keycode 234. That also shows that it is mapped to
XF86AudioMedia which does nothing on my WM (xmonad, 'cause it ignores a good deal of the XF86 standard). But anyhow, we have a key to remap. To perform that we do:
xmodmap -e 'keycode 234 = Up NoSymbol Up'
And my musical note key works as an Up arrow. Moreover, this is WM independent. To make it work on reboot you need to place the
xmodmap expression into a
keycode 234 = Up NoSymbol Up
During the WM initialisation. Which files
~/.profile, something else, are run during XFCE initialisation is another question. WMs are particularly unstandardised about which files are run. You can always run that by hand though.
.Xmodmap file contains a mapping one per line, and can therefore be used to remap several keys. The
! mark is a comment indicator in that file.
How does that work?
For a start let's understand why I needed to write
Up NoSymbol Up instead of simply
Up. Actually I didn't need but it is common to give at least three (sometimes four) mapping for a key. The mapping mean the action to take when the key is:
= <key pressed> <shift+key> <ctrl+key> <ctrl+shift+key>
Ctrl+Up works badly in some applications, this makes this example not that good.)
OK, so we remapped one key. But how to find the correct action to remap keys to. Arrows are simple: Up, Down, Left, Right; letters also are simply remapped by adding the letter as the argument. But what about that
XF86AudioMedia thing we had before? Or how to make a key to be a sleep or power button?
To get your current mappings you do:
It prints a very long list, including several
XF86 modifiers (e.g.
XF86WebCam). These can be added to any key just like we did with the Up arrow above. And the full list can be found in the Xorg source code.
Unfortunately, just like the comment in the source states:
X.Org will not be adding to the XF86 set of keysyms, though they have
been adopted and are considered a "standard" part of X keysym definitions.
XFree86 never properly commented these keysyms, so we have done our
best to explain the semantic meaning of these keys.
XFree86 has removed their mail archives of the period, that might have
shed more light on some of these definitions. Until/unless we resurrect
these archives, these are from memory and usage.
It may be difficult to find the exact purpose of each of those. And, thanks to that lack of a well defined standard, WMs implement only some of those mapping. And different WMs implement different mapping. Moreover, some WMs have configuration tools to what these mappings do whilst others don't. Some WMs ignore pretty much all of these mappings.
One way to test whether your WM support a specific mapping is to try it. For example I'll try
XF86XK_ToDoList by first removing the
XK from the define and remapping an unused keycode:
xmodmap -e 'keycode 248 = XF86_ToDoList'
xdotool to make up the keypress of such a keycode:
xdotool keydown 248
xdotool keyup 248
My WM certainly does not support
XF86_ToDoList since nothing happened (actually I do not think any WM support that one).
You can then search for the functionality you need for your keys and remap them once you find the functionality. Given that XFCE supports it, of course.
If you change your keyboard between different languages, using
setxkbmap or a tool that calls
setxkbmap behind the scenes, the mapping will be undone. IMEs are fine since they operate independently from Xorg.
The mapping work when you're logged on. You can create a "power on" keys
Be careful when testing something like
XF86PowerOff, you may inadvertently force a hard reboot.