Configure Xorg to type ligatures

By Olivier Mehani <shtrom-kb@ssji.net>

Abstract

This gives a way to configure Xorg to be able to type ligatures, as in the French language œ or Æ.

Introduction

Generic US keyboard mappings have proven to be the most efficient for general tasks (Dvorak, and the humonguous time to learn it that I have not undergone myself yet, not taken into account). There are some situations, however, in which it is not the most appropriate that is, typing foreign languages with weird characters. Usually, using an us mapping with the intl option activates gives access to accented symbols through the use of dead keys, but not all special characters are available.

The following quickly describes how to setup such dead key modes to type ligatures like æ or Œ in xorg.

Updates to this document

01/04/2012

Despite the comment in the introduction, I have been using Dvorak keymaps for more than two years now. It took me about 3 weeks to get back to a non-frustrating typing speed, and I can still get back to the QWERTYs of my colleagues quite easily (actually, more easily than from QWERTY to AZERTY). This document is still valid, replacing the intl variant with dvorak-intl one, which behaves exactly the same, just swapping the keys over.

As a side note, more than changing the keymap to Dvorak, which seems to make only a marginal improvement, I found switching to a keyboard such as the TypeMatrix 2030, or any other keyboard with the keys arranged in a proper matrix, rather than the stupid typewriter-style ragged rows, made wonders to my typing comfort. The Enter and Backspace located in the middle are also quite handy.

The Basics

As Xorg can be configured to use dead keys, it can also be specified that the use of the Shift+AltGr keys combined with others can yield specific, dead-key-like behaviors. This includes the option to type Shift+AltGr,o,e to type an œ or Shift+AltGr,Shift+a,Shift+e to obtain an Æ.

Quick'n Dirty Solution: setxkbmap

The simplest way to set this up is to add the lv3:ralt_switch_multikey Xkb option for the current X session. This instructs Xorg to consider the shifted right alternate key (usually AltGr) as a Multi_key. The Multi_key is used to tell that the next key is part of a sequence and should not be interpreted on its own directly. This allows to combine several characters into one.

The option lv3:ralt_switch_multikey can be set using setxkbmap as follows (the verbose way to emphasize on the modifications).

$ setxkbmap -print
xkb_keymap {
        xkb_keycodes  { include "xfree86+aliases(qwerty)"       };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+us(intl)"   };
        xkb_geometry  { include "pc(pc105)"     };
};
$ setxkbmap -option lv3:ralt_switch_multikey
$ setxkbmap -print
xkb_keymap {
        xkb_keycodes  { include "xfree86+aliases(qwerty)"       };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+us(intl)+level3(ralt_switch_multikey)"     };
        xkb_geometry  { include "pc(pc105)"     };

Testing That It Works (Or Debugging)

One can never be sure so, after issuing the setxkbmap command, it's always good to check that the new settings work properly. Of course, hitting the specific key sequence and getting the desired character is a dead giveaway that it works. If it doesn't, though, the xev can be of valuable help. This tool displays (among others) the key-related events received by X applications when a specific keystroke happens.

When hitting first AltGr, then Shift+AltGr with the mouse over xev's window, one should see the following in the console used to launch it. The ouptut to look for is the one with Multi_key when hitting Shift+AltGr.

...
KeyPress event, serial 32, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426798790, (97,92), root:(2070,111),
    state 0x10, keycode 113 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426798830, (97,92), root:(2070,111),
    state 0x90, keycode 113 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 29, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426795702, (97,92), root:(2070,111),
    state 0x10, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 32, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426796158, (97,92), root:(2070,111),
    state 0x11, keycode 113 (keysym 0xff20, Multi_key), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: True

KeyRelease event, serial 32, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426796230, (97,92), root:(2070,111),
    state 0x91, keycode 113 (keysym 0xff20, Multi_key), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 32, synthetic NO, window 0x2e00001,
    root 0x6a, subw 0x0, time 426798422, (97,92), root:(2070,111),
    state 0x11, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False
...

Making That More Definitive: xorg.conf

A cleaner solution, which makes the modification systemwide and available for all users is to configure the option direclty in the configuration file of Xorg: /etc/X11/xorg.conf. This sits in the InputDevice section for the keyboard.

Section "InputDevice"
        Identifier  "Keyboard0"
	Driver      "kbd"
	Option	"XkbModel" "pc105"
	Option	"XkbLayout" "us"
        Option  "XkbVariant" "intl"
        Option  "XkbOptions" "lv3:ralt_switch_multikey"
EndSection

Other resources

Acknowledgments

This issue has been bugging me for a long time, without getting on my nerves enough so that I actually try to fix it for more than a few minutes in a row. I'd like to thank Hamish for giving more emphasis on that, and getting me to focus long enough (particularly deciphering files /usr/share/X11/xkb/symbols/fr and /usr/share/X11/xkb/symbols/level3) so that I got to a clean solution.


Page generated: 2012-04-01T12:11:24+10:00
Source: $Id: xorg-ligatures.xml 69 2012-04-01 02:11:26Z shtrom $
Stylesheet: $Id: page.xsl 68 2010-06-18 05:01:18Z shtrom $