I have found that the XRDP keyboard layout problem is unsolvable the "easy" way, as things sometimes can be in Linux.
Fortunately, there is a workaround, as there is often in Linux.
- - -
** Fair warning : This is monk's work, but tremendously satisfying in the end. **
Problems & solutions seen elsewhere on the Internets :
- Using xrdp-genkeymap command line tool does not generate proper keyboard files most of the time (arrows and CTRL and ALT not working is a common issue, even if you generate the file on the local console).
- The REAL problem with XRDP seems to be that the /etc/xrdp/km-0409.ini file is always used, regardless of what you do with setxb* commands. So once the XRDP session is launched, it hard wires the km-0409.ini file into the keyboard.
- There's no way to change it afterwards, say for example with the XFCE panel utility to change layouts or with shell commands like setxkbmap (or many others, I've tried everything). For example, on your panel, sure, it will show changing between your keyboards but the layout will NOT actually change !
- - -
The "hard" way to solve this is to design your own keyboard map using XEV and Unicode/ASCII charts.
NOTE : This, as far as I know, does not allow 'dead keys' (for example in typical Canadian French layouts, there is a dead key for the 'grave' and 'circumflex' and 'diaresis', which means you hit one key, then the letter, and only THEN do you get the output of a accented letter. I did not find any way to get this to work in XRDP)
- - -
**Guide to creating your own keymap**
These instructions are easier if you work with a US Keyboard but it can apply to any language combination if you are patient and willing to create your own personal keymap.
1) Make a backup copy of the original /etc/xrdp/km-0409.ini. Preserve this original file somewhere at all times, it is a basic US keyboard and maps properly all the arrows, CTRL, ALT, etc. keys, and in case of any problems you can always revert to it or copy chunks of it to restore important keys like your arrows.
2) Load up a website with Unicode/ASCII listings, such as :
Any character has its own hexadecimal and decimal value. You will need those to create your keyboard map.
3) Finding out the KEY CODE with XEV : This is the physical number assigned to a given key on your keyboard. This is found out with XEV, it is a shell tool that probably comes preinstalled on your distro.
Here is a typical output for a key, here I pressed 'a' on my keyboard, for any key pressed with XEV you will have the key press and key release events.
KeyRelease event, serial 37, synthetic NO, window 0x3c00001,
root 0x178, subw 0x0, time 923536206, (203,103), root:(754,551),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
KEYCODE 38 is the physical code of the key that is labeled 'a' on my keyboard. Right now XEV tells me that it is mapped to KEYSYM (key symbol = unicode/ASCII) HEX # 0x61.
That is a HEX value. The km-0409.ini file contains decimal values, so you need to convert.
A great tool to do this is 'qalc' or 'qalculate' which is a shell calculator. Type 'qalc' to get into it, and then issue the command hex(value), as below (do not include the 0x prefix)
 ~ $ qalc
hex("61") = 97
So now we know that the physical letter 'a' on the keyboard maps to the unicode/ASCII letter 'a' (symbol # 97). You can also find websites on the Internet to do this conversion for you.
4) Format of the km-0409.ini file
If you look into km-0409.ini file, you will find 5 sections in it, each with a label.
Each section contains a FULL keyboard map. Certains keys let you change from one to the other. This will allow us to hack our way into the capability of switching keymaps dymically in the XRDP session. I will explain this later.
Sections are [noshift], [shift], [altgr], [capslock] and [shiftcapslock].
Here is the explanation :
[noshift] and [shift] are your basic layouts.
- [noshift] is what happens when you simply press a key.
- [shift] is like SHIFT+a which procudes 'A' normally.
[altgr] is what is supposed to happen with the right ALT key (right of your spacebar). However, I did not manage to get this working on XRDP. An example in Windows, for French Canadian users, AltGr+2 will generate '@'.
[capslock] and [shiftcapslock] allow you to map a complete secondary layout. How it works is exactly like [noshift] and [shift] except that those keys are used when your CAPSLOCK is turned on. In effect, this can function as a layout switcher hotkey.
For example what I did on my system is that I created my own custom French Canadian layout on the [noshift] and [shift] by modifying the basic US Layout which was already in the file, and then I copied the mapping for the basic US Layout into the Capslock groups. So, in effect, when I press Caps Lock, I am switching from my french to my US layouts and vice versa.
The only downside is that when you go back to your local desktop, you will often find yourself in Caps Lock. But, I find it is a small price to pay to have a custom keymap that I can control. Otherwise, the only other way to switch will be to override the km-0409.ini with the layout you want, and restart the XRDP daemon.
5) Individual lines of the km-0409 file
Now let's look at KEYCODE 38 from the example above in our basic [shift] and [noshift] sections.
The format of each line in the sections is :
For example, for KEYCODE 38 (physical letter 'a') in [noshift] is :
So, physical key 38 is mapped to unicode/ASCII 97 decimal, 0x61 hex. That's what we saw in XEV.
Let's look at KEYCODE 38 in [shift] :
This show that Shift+a is mapped to decimal 65. Let's look at numbermonk.com, at the page :
On this page we find the following information :
'65: ASCII code for Uppercase A'
Ok perfect, so physical 'a' [noshift] = 'a' and physical 'a' [shift] = 'A'.
(N.B. - Don't ask what the 65:65 or 97:97 means. Just put the number in there twice and don't ask any questions. No one knows what this means at all.)
- - -
** Now we have a basic understanding of the key concepts :
- Finding out of a KEYCODE with XEV.
- We have a nice unicode/ASCII chart at http://code-ascii.outils-webmaster.com/ there are others but this one has all the accented characters in one view, contrarily to numbermonk which is a bit more tedious to navigate.
- We understand how the km-0409.ini file works and how the different sections come into play.
So you have all the tools to create your own custom keymap. I decided since there were no dead keys for french, I would map all my accented letters onto the numbers above the letters (since I still have the NumPad).
For example, part of the [noshift] section of my layout is something like this :
This corresponds to many of the accented french letters, mapped onto 1, 2, 3, 4, etc. physical calls.
The layout is logical (to me) and I've learned to use it within a few hours. For example, if I press the whole top row of my mapped keys : äëïöüîôûìòù-ç this is what I get, and if I hold Shift, I get ÄËÏÖÜÎÔÛÌÒÙ »Ç so you can see this is very easy to use for me ! And, of course, I used caps lock to switch back and forth as needed.
I need to use a slash or some brackets inside a shell or in an e-mail ? (or an exclamation mark which I ran out of keys and did not map into the french layout!)
No problem... Hit Caps lock and boom ! I'm back to a default US Layout, because what I did is that I copied the ENTIRE keymap from the US Layout [shift] and [noshift] sections into [capslock] and [shiftcapslock] so whenever the 'caps lock' is ON, I'm effectively using a US Layout, as I am right now.
There is no problem with every letter being uppercase because, remember, I mapped the [capslock] to the original [noshift] and the [shift] to [shiftcapslock]. Downsides being, 'capslock' is sometimes on when I return to my local desktop and also, I effectively have no capslock key available in XRDP, since it is now a layout switcher.
The upside is that I can hot-swap layouts with 'capslock'. Otherwise, I'd have to overwrite km-0409.ini with a script, such as :
rm -f km-0409.ini
cp fr.ini km-0409.ini
systemctl restart xrdp
Where I have fr.ini as my french layout and en.ini as my english (US) layout. Of course here you notice the last line is to restart XRDP which means reconnecting. This is an annoyance but if you really want 'capslock' to type angry messages at people, it's another solution.
I hope this guide helps, I haven't really found anything detailing how to do this yet in forums.
- - -
My own source files can be found at http://cloclotron.net/files/fr-ca.tar
In this tar ball you will find :
- map.jpg : A visual representation of the keyboard I made for myself.
- mapping : The layout for each key
- en.ini : The default km-0409.ini (US layout)
- fr.ini : The layout pictured in map.jpg and mapping, which I have copied to /etc/xrdp/km-0409.ini
- - -
-kharv writing out of Montréal, Québec, Canada.