Dead keys on Linux: bringing back the Windows behaviour
On Linux, two grave accents cost four keystrokes, two on Windows. Understanding the Compose tables and restoring the Windows behaviour with ~/.XCompose.
Do you write Markdown on a keyboard with dead keys? Then you know the ordeal of the code fence. On my Debian box, opening a triple-backtick block takes six keystrokes. On Windows: three, plus a space. The culprit is neither your desktop environment nor your distribution — it’s the Compose tables.
The problem in numbers
On a dead-key layout, the grave key inserts nothing on its own: it waits for the next character. Accent + vowel = accented vowel. Accent + space = the bare accent. So far, so good.
Note: the name comes from typewriters. A dead key printed the accent without advancing the carriage — no spacing, no character of its own. The next letter overprinted the same spot, forming
éin ink on ink. Computing inherited the term: X11 literally names these keysdead_grave,dead_acute…
| To produce | Linux (default) | Windows |
|---|---|---|
| One grave accent | 2 keystrokes | 2 keystrokes |
| Two grave accents | 4 keystrokes | 2 keystrokes |
A code fence ``` | 6 keystrokes | 4 keystrokes (3 + space) |
On Windows, typing a dead key twice emits the character twice. On Linux, each pair of keystrokes yields only one character — hence the doubled bill for `` and ```.
The culprit: the Compose tables
On Linux, dead-key resolution is defined by the Compose tables — historically X11, nowadays also implemented by libxkbcommon. Your locale’s table lives under /usr/share/X11/locale/. For an en_US.UTF-8 locale:
grep "<dead_grave>" /usr/share/X11/locale/en_US.UTF-8/Compose
<dead_grave> <space> : "`"
<dead_grave> <dead_grave> : "`"
There’s the culprit: the second line maps two presses of the dead key to a single grave accent. That’s the X11 convention, and it’s everywhere: GNOME, KDE Plasma, MATE and XFCE all resolve dead keys through the same tables, whether via GTK, Qt, IBus or fcitx — they all implement the same specification. Windows and macOS are the odd ones out: there, doubling a dead key emits the character twice.
Switching desktop environments won’t save you. Overriding the table will.
The fix: ~/.XCompose
The table can be overridden per user, in ~/.XCompose:
# ~/.XCompose — user overrides
# Keep everything from the system table (dead keys, Multi_key, etc.)
include "%L"
# Windows-like behaviour: a dead key typed twice emits the character twice
<dead_grave> <dead_grave> : "``"
# Same trick for the other dead keys, if ever wanted:
# <dead_acute> <dead_acute> : "''"
# <dead_circumflex> <dead_circumflex> : "^^"
# <dead_tilde> <dead_tilde> : "~~"
The include "%L" directive pulls in your locale’s system table (%L expands to its path); the next line overrides it.
Warning: without the
include,~/.XComposereplaces the whole system table — say goodbye to è, à, ù and every other composition.
Activating it
The table is loaded when your session and your applications start:
- IBus is running (the default under GNOME, and often elsewhere): run
ibus restartfrom a terminal in your session, then close and reopen your applications. - Otherwise: log out, log back in.
- Under Wayland, GTK and Qt rely on libxkbcommon, which reads the same
~/.XComposewhen each application starts — restarting the application is generally enough.
So the mechanism isn’t X11-specific: X11 or Wayland, same table, same fix.
Sanity check
| Keystrokes | Expected result |
|---|---|
Grave then e | è — accents untouched |
| Grave then space | ` — unchanged |
| Grave × 2 | `` — 2 keystrokes instead of 4 |
| Grave × 3 then space | ``` — Windows parity |
Going further
- The
Compose(5)man page documents the full format: includes,Multi_key, long sequences. - The Arch wiki page on XCompose lists known per-toolkit quirks.
- The same principle applies to every dead key: circumflex, diaeresis, tilde — ready-made lines, commented out, in the file above.
Conclusion
Six keystrokes for a code fence was never a fatality — just a Compose-table convention, overridable in three lines. My ~/.XCompose now allow to make less keystrokes, and typing my Markdown blocks is simplified.
Comments