This page in: Việt
I can't use dead-keys in X11 to input accented letters
Quick answer: you need to enable them in a custom keymap.
User-friendly answer: it's actually very easy to fix, so don't panic and read on...
Your Unicode keyboard layout for your chosen language, which works perfectly in the Mac OSX main GUI, now refuses to behave itself in X11, and the applications you want to run in X11. You have enabled the system keyboard layouts in the X11 preferences. You can input your normal, one-keypress letters. But the dead-keys which normally add an accent, just input spaces instead.
For some reason, X11 doesn't read our Unicode keyboard layouts accurately. Where it should be reading "dead key", it just reads "space". However, we can tell it what to do. Your best friend in this case is a little program called xmodmap.
xmodmap, as its "x" prefix shows, runs under X11. Don't try and run it in the Terminal, in your normal shell. It will complain about trying to open a window. It wants X11.
In X11, choose your keyboard layout (either a default layout, or an additional layout you've installed from a download like this Vietnamese additional keyboards package) in the Input Menu, then run
xmodmap -pke > layout_name.map
substituting a name to identify the layout which you've activated. You might want to make several of these keymaps, so you need to be able to tell them apart.
Nothing much happens in the X11 window, but you've just created a file called, e.g. "vietnamese_tcvn.map" in your user (~) folder. (This is the folder named after you. All your user settings and files are based on this folder. Think of it as your branch of the computer tree. :) )
I used "vietnamese_tcvn" for my file, because that was my Unicode layout when I encountered this problem.
So you now have a file describing all the active keys on your current layout. Open it in a text editor (e.g. TextEdit). You'll notice that every key has a keycode, and that they're not necessarily in the same order as your physical keyboard. However, you can usually identify them by the characters they input. If you're not sure which key is which, type "xev" in your X11 window, then press any key. xev shows you information about each keypress. For example, when I press my dead-key for the grave accent (`), xev outputs:
KeyPress event, serial 22, synthetic NO, window 0xc00001, root 0x57, subw 0x0, time 148597384, (1,193), root:(21,257), state 0x0, keycode 31 (keysym 0xfe50, dead_grave), same_screen YES, XLookupString gives 1 bytes: (60) "`" XmbLookupString gives 0 bytes: XFilterEvent returns: True
You can see "dead_grave" in that output, and "keycode 31". Press any key, to see what it inputs, and what its keycode is. You'll probably find that your dead-keys aren't working. Mine certainly weren't at that stage.
Note: xev tells you about all your keyboard activity. If you start typing around, scrolling, or generally being active, it will tell you about all of that! Type Ctrl-C to get out of xev.
Now, look at your keymap, which in my example is "vietnamese_tcvn.map". Look for the keycodes of the keys which should work as dead-keys. What is next to the keycode? In my example, for the grave dead-key, it should have been:
keycode 31 = dead_grave dead_grave 5 percent
but it wasn't. It said:
keycode 31 = space NoSymbol 5 percent
and that was why I was getting a space instead of my dead-key accent.
The keymap shows information in this pattern:
keycode xx = normal shift option shift-option
so my number 5 key, which showed up as:
keycode 31 = space NoSymbol 5 percent
was inputting a space when I pressed it once, nothing when I used the Shift, number 5 when I used the Option key, and the percent symbol when I used Shift-Option. It's useful to understand this pattern, so you can modify your own layouts. :)
Look at your keymap, and identify the keycodes of your dead-keys. You'll probably see that they're not inputting dead-key accents. That's why your dead-keys aren't working. X11 reads this keymap when it opens. And it's not getting the right information.
So, how do we give it the right information?
We write our own keymap. :)
We don't have to define all the keys, just the ones that aren't working, and any non-default-keyboard keys in the layout. This is because our new keymap is actually going to replace our chosen language keyboard-layout. So we need to specify any character which doesn't exist on a standard keyboard.
The standard keyboard layout depends on your locale. See:
If there is an existing Mac OSX locale for your language, you probably don't have this problem. If there isn't a locale for your language, you need to specify the closest one, to form a base locale for the added characters you will put into your keymap. So choose an existing locale which uses your alphabet, and has as many of your characters as possible.
There isn't a UTF8 locale for Vietnamese in OSX (I'm trying to create one, and will post the link to it when it is complete), so I chose the en_US.UTF-8 locale, since Vietnamese uses a Roman alphabet.
To see which characters are available, look inside the default locale you have chosen, for a file called "Compose". This will list all possible characters in that locale. For UTF8 locales, that's a lot! To make things easier, open the Compose file in your text editor, and search for "dead_", or the name of any other character you're seeking.
Once you have chosen your default locale as the suitable one to form a base for your own language, you can also choose that keyboard layout in the Input Menu and run:
xmodmap -pke > default_locale.map
to list all the characters it contains. That way you know what would normally be input if you used that layout.
Right, we're ready to write our own keymap, as a supplement to the default one. Open a text document (e.g. in TextEdit) and write down the first keycode you want to change. In my case, that was
keycode 31 =
Then choose from the Compose file, the characters you want it to input. In my case, that was:
keycode 31 = dead_grave dead_grave 5 percent
so it would input the grave accent as a dead-key when pressed normally and with Shift. That way I could use it for upper-case typing as well.
However, I don't want to lose access to the number 5, and the percentage sign. So I put them in for Option and Shift-Option respectively. Save your file as "mykeymap" or similar. All done.
Now, before you go on to other keycodes, test that this works. In X11, run:
Then try using that character. Does it work? It should. :)
Go back to your "mykeymap" file, and input the details for the other keys you want to change.
Note: you can input the description of the character or the Unicode hex, e.g. "eacute" or "U00E9". To find descriptions and Unicode hex, you can use the excellent freeware utility Unicode Checker, which converts all the different Unicode expressions, and has Services support. To find information about a character, simply type it into the main Unicode Checker window, then look at the information below. (You need to remove the plus sign from the Unicode hex before inserting it in your keymap, e.g. "U+20AB" becomes "U20AB".)
again, to test them.
You'll notice, however, that feeding a new keymap to xmodmap has disabled any characters in your chosen layout which aren't represented by the default keyboard, in my case the Australian English keyboard.
In my case, there were several one-keypress vowels, one crossed-d, and a currency sign which were no longer active. No problem! I added them to my keymap.
You can use either the descriptions in the Compose file for the default locale, or the Unicode codes, to describe characters. Here is my finished MyKeymap for my Vietnamese layout:
keycode 18 = U20AB plus equal plus keycode 26 = abreve Abreve 1 exclam keycode 27 = acircumflex Acircumflex 2 at keycode 28 = ecircumflex Ecircumflex 3 numbersign keycode 29 = ocircumflex Ocircumflex 4 dollar keycode 30 = dead_hook dead_hook 6 asciicircum keycode 31 = dead_grave dead_grave 5 percent keycode 33 = dead_belowdot dead_belowdot 9 parenleft keycode 34 = dead_tilde dead_tilde 7 ampersand keycode 36 = dead_acute dead_acute 8 asterisk keycode 37 = dstroke Dstroke 0 parenright keycode 38 = U01A1 U01A0 bracketright braceright keycode 41 = U01B0 U01AF bracketleft braceleft
This enables my five dead keys, my missing vowels, my crossed-d, my currency sign, and with Option and Shift-Option, all the keys those characters normally replace: the number and punctuation keys.
Now you know how to edit a keymap, you might like to add some more handy characters to the Option and Shift-Option fields. (You can always use NoSymbol to fill in blanks.) This ability can be useful, to save you switching layouts. In the main OSX GUI, you can modify keyboard layouts with a neat little application called Ukelele.
And you don't need to run:
everytime you open X11, either. To run that automatically, each time X11 is opened, type this in your X11 window:
cat mykeymap >> ~/.Xmodmap
This command creates a file called ".Xmodmap", which contains your keymap. X11 will read it every time it opens. To change that, just open the ".Xmodmap" file and edit the details.
Thanks to Jun. T. and Tom Gewecke of the Apple Unix Discussions Forum for their help.