Skip to content

Creating a Custom Keyboard Layout (and How It Works with Toshy)

RedBearAK edited this page Jun 14, 2026 · 2 revisions

This guide is for one specific wish: you want some keys on your keyboard to type different characters than your normal layout gives them — for example, you use a German keyboard but want the US-position brackets and braces ([ ] { }) for programming, without giving up German typing.

The right tool for that is a small custom keyboard layout, not a Toshy remap. A layout change happens at the level that actually decides which character a key produces, so it is system-wide and permanent: it works in every application, at the login screen, on a text console, and — importantly — when Toshy is not running at all. (If you have solved this before with a Toshy config remap, this replaces that approach with one that no longer depends on Toshy being active.)

The whole thing is one short file you create in your home directory.


1. Is this the right fix for you?

There are two different problems people often mix up:

  • "My shortcuts fire the wrong action on my non-US layout." That is what Toshy's layout correction already handles automatically — you don't need to do anything in this guide.
  • "I want some keys to type different characters." That is a layout change, and that is what this guide covers.

The two are independent and they cooperate (see Section 8), so doing this does not interfere with Toshy.

Throughout, the running example is: a German (QWERTZ) keyboard, adding [ ] { } on the keys where US keyboards have them, reached with AltGr, while the keys keep producing their normal German characters otherwise.


2. Before you start: Wayland or X11?

This matters, because the easy method only works on one of them.

The home-directory method below works on Wayland sessions, which use libxkbcommon to build the keymap and read your personal files. It does not work on X11 sessions, because the X server only looks in system directories. If you are on X11, skip to Section 7.

Check which one you are on:

echo $XDG_SESSION_TYPE      # prints "wayland" or "x11"

The rest of Sections 3–6 assume Wayland.


3. How XKB finds your layout (the 30-second version)

You only need three facts:

  • The keyboard system searches your personal folder, ~/.config/xkb/, before the system folders, so anything you put there is used first.
  • A layout is a file inside symbols/. A variant is a named section inside that file.
  • You will create one file, put your changes in a named section, and reference it as layout(variant).

That is enough to follow every step.


4. Create the layout file

Make the folder and create one file:

mkdir -p ~/.config/xkb/symbols

Create ~/.config/xkb/symbols/custom with this content:

// ~/.config/xkb/symbols/custom
// A German layout with US-position brackets/braces added on AltGr.

partial alphanumeric_keys
xkb_symbols "programming" {

    include "de(basic)"
    name[Group1] = "German (US braces, programming)";

    // Each key lists four levels:  [ base, Shift, AltGr, Shift+AltGr ]
    // The first two keep the normal German characters; the last two add the
    // brackets and braces. FOUR_LEVEL makes the AltGr levels reachable.

    key <AD11> { type[Group1]="FOUR_LEVEL",
                 [ udiaeresis, Udiaeresis, bracketleft,  braceleft  ] };
    key <AD12> { type[Group1]="FOUR_LEVEL",
                 [ plus,       asterisk,   bracketright, braceright ] };
};

What each part does:

  • include "de(basic)" starts from the standard German layout, so every key you don't touch behaves exactly as before.
  • name[Group1] is the label that shows up in layout switchers (and the name Toshy will read for this layout).
  • Each key line replaces one key with four levels. <AD11> is the key that is [ on a US keyboard (ü on German); <AD12> is the US ] key (+ on German). Levels 1–2 keep the German ü/Ü and +/*; levels 3–4 (AltGr and Shift+AltGr) add the brackets and braces.

Two things worth knowing:

  • Give the file a new name like custom. Do not name it de — a file named de in your home folder would hide the entire system German layout instead of building on it.
  • For a key whose base character is a letter (like ü above), use FOUR_LEVEL_SEMIALPHABETIC instead of FOUR_LEVEL if you want Caps Lock to still capitalize it. For bracket keys it makes no difference.

Adapt freely: pick whatever keys and levels suit you, and replace any keysym with the character you want. A list of keysym names (bracketleft, braceright, and so on) is in the system file /usr/share/X11/xkb/keysymdef.h or the standard X keysym tables online.


5. Test it before turning it on (don't skip this)

A broken layout can leave you unable to type, so check it in a safe, offline way first. The xkbcli tool (Fedora package libxkbcommon-utils, similarly named elsewhere) compiles your layout without applying it:

xkbcli compile-keymap --layout custom --variant programming | grep -i group1

If your file is valid you'll see your label:

        name[1]="German (US braces, programming)";

You can also confirm the brackets landed where you intended:

xkbcli compile-keymap --layout custom --variant programming | grep -i bracketleft

If you instead get an error, fix the file and run it again. Nothing has changed on your live keyboard yet, so you can iterate safely.


6. Turn it on

How you activate a layout depends on your environment.

Sway / Hyprland and similar (apply it directly — no registration needed):

Sway, in your config:

input "type:keyboard" {
    xkb_layout "custom"
    xkb_variant "programming"
}

Hyprland, in your config:

input {
    kb_layout = custom
    kb_variant = programming
}

GNOME / KDE Plasma (register it so it appears in Settings):

Full desktops pick layouts from a registry, so for your custom layout to show up in the keyboard-settings list you register it by adding a few small files under ~/.config/xkb/rules/ (an evdev, evdev.xml, and evdev.lst entry), then log out and back in. Rather than reproduce that here, follow one of these, which walk through it with working examples:

A note on setxkbmap: it only affects X11 and XWayland applications, not native Wayland apps, so it is not a reliable way to apply a layout on a Wayland session. Use your compositor's or desktop's own setting as above.


7. If you are on X11

The home-directory method does not apply: an X server reads only the system location, /usr/share/X11/xkb/. To add a custom layout on X11 you edit the files there (as root) and register it in the system rules — which also means your changes are overwritten whenever the xkeyboard-config package updates, so you'll need to reapply them.

Because that path is well covered already, follow an established guide rather than duplicating it here:

The symbols-file content from Section 4 is the same; only where it lives and how it is registered differ.


8. Using it alongside Toshy

A custom layout and Toshy do different jobs and stay out of each other's way:

  • Your custom layout decides which characters your keys type.
  • Toshy corrects which shortcuts fire, so your macOS-style shortcuts keep working regardless of layout.

Toshy reads your layout's actual compiled keys, so it adapts to a custom layout on its own. In the example here you only added characters on the AltGr levels and left the base keys untouched, so Toshy sees the same base layout as before and nothing about its behavior changes. If a custom layout instead moves base-level keys around, Toshy notices and adjusts its shortcut correction to match — no configuration needed either way.

And because this is a real layout rather than a running remap, your characters are there even when Toshy is stopped, on the login screen, or on a fresh machine where Toshy isn't installed yet.


9. Troubleshooting

  • AltGr doesn't produce the brackets. Your session may not be using Right Alt as the AltGr (level-3) key. Add the option lv3:ralt_switch in your compositor/desktop keyboard settings, or confirm which key is your AltGr.
  • The layout doesn't appear in GNOME/KDE Settings. That list comes from the registry — complete the registration step in Section 6 and log out and back in.
  • Something looks wrong. Re-run the xkbcli compile-keymap check from Section 5; it reports the exact line of any mistake.
  • You're stuck with a bad layout. Switch back to a normal layout through your desktop's keyboard settings (or your compositor config), then fix the file and re-test with xkbcli before turning it on again.

Clone this wiki locally