# Dvorak with QWERTY's brackets on KDE Plasma (Wayland)

> A small XKB layout that keeps Dvorak's letters but leaves [ ] { } - _ = + where QWERTY has them, and gives QWERTY letters while Ctrl or Meta is held, so copy and paste don't move. A second layout in Plasma 6.6 on Wayland. The first time, KWin only finds it after a log-out, and its log says why.

Guide · Published 2026-10-30 · Updated 2026-10-30  
Web page: https://blog.jacq.cc/guides/dvorak-qwerty-brackets-kde-wayland/

I wanted Dvorak's letters with `[ ] { } \ | - _ = +` still on their QWERTY keys, as a second layout next to my usual `au` (the same keys as US). Copy and paste should stay easy too: on plain Dvorak, `Ctrl+C` and `Ctrl+V` move to the QWERTY `I` and `.` keys.

![A drawing: a keyboard with Dvorak letters where the - = [ ] \ keys glow green because they stay on their QWERTY keys, and a pill in the corner switches between au and dvq](../../../assets/dvorak-qwerty-brackets-kde-wayland/cover.svg)

No stock layout does this. The closest is `gb(dvorakukp)`, "English (UK, Dvorak, with UK punctuation)". It keeps `- = [ ]` on their QWERTY keys, but it's built on UK Dvorak: Shift+2 gives `"`, Shift+3 gives `£`, the `\` key gives `# ~`, and `\ |` moves to the extra key next to left Shift, which US and Australian keyboards don't have. So I wrote my own: US Dvorak, five keys moved back, and QWERTY letters while Ctrl or Meta is held.

:::note[Status, October 2026]
Kubuntu 26.04, KDE Plasma 6.6 on Wayland, libxkbcommon 1.13. Installed on 30 October 2026. The Ctrl and Meta keys are tested in libxkbcommon, the library KWin uses, but not yet app by app.
:::

## The layout

![The dvq layout on a US keyboard: Dvorak letters, with - = [ ] and \ green because they stay on their QWERTY keys, and / ? pink because it moved to the QWERTY ' key](../../../assets/dvorak-qwerty-brackets-kde-wayland/layout.svg)

*`dvq`. Green keys are where QWERTY has them. The pink one moved.*

| QWERTY key | US / `au` | `dvq` | Dvorak |
| --- | --- | --- | --- |
| `-` | `- _` | `- _` | `[ {` |
| `=` | `= +` | `= +` | `] }` |
| `[` | `[ {` | `[ {` | `/ ?` |
| `]` | `] }` | `] }` | `= +` |
| `'` | `' "` | `/ ?` | `- _` |

`\ |` is on the same key in all three. Dvorak's `/ ?` had to go somewhere, and the `'` key was the one left free: Dvorak has `- _` there, and those are back on their own key now. `' "` stays where Dvorak puts it, on the QWERTY `q` key.

With Ctrl or Meta held, every key gives its QWERTY symbol instead ([Step 3](#step-3-ctrl-and-meta-on-qwerty-keys)).

## What you need

| Part | Notes |
| --- | --- |
| KDE Plasma 6 on Wayland | Mine: Plasma 6.6 on Kubuntu 26.04 |
| `xkbcomp` | Only for the script's compile check. In apt as `x11-xkb-utils` |
| sudo | The files go in `/etc/xkb` |

## Step 1: Download the files

```bash
mkdir dvq && cd dvq
for f in install.sh dvorak-qwerty custom-types evdev.xml; do
  curl -fsSO https://blog.jacq.cc/keyboard-layout/$f
done
```

Four files: [install.sh](https://blog.jacq.cc/keyboard-layout/install.sh), the layout [dvorak-qwerty](https://blog.jacq.cc/keyboard-layout/dvorak-qwerty), its key types [custom-types](https://blog.jacq.cc/keyboard-layout/custom-types) and [evdev.xml](https://blog.jacq.cc/keyboard-layout/evdev.xml). MIT licence ([LICENSE](https://blog.jacq.cc/keyboard-layout/LICENSE)).

## Step 2: The layout file

```text
default partial alphanumeric_keys
xkb_symbols "basic" {
    include "us(dvorak)"
    name[Group1] = "English (Dvorak, QWERTY brackets and -=)";

    replace key <AE11> {[ minus,        underscore ]};
    replace key <AE12> {[ equal,        plus       ]};
    replace key <AD11> {[ bracketleft,  braceleft  ]};
    replace key <AD12> {[ bracketright, braceright ]};

    // ... 29 keys with QWERTY levels for Ctrl and Meta (Step 3)
};
```

`include "us(dvorak)"` pulls in all of US Dvorak, and each `replace key` line changes one key, here the four that go back to QWERTY. Key names are positions, not letters. `AE` is the number row, `AD` the top letter row and `AC` the home row. `<AE11>` is the key right of `0`, `<AD11>` and `<AD12>` are the two right of QWERTY's `P`, and `<AC11>` is the one right of `;`.

To move other keys, add more lines. `us(dvorak)` in [xkeyboard-config's symbols/us](https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/us) shows what's on each key.

## Step 3: Ctrl and Meta on QWERTY keys

An XKB key can have more levels than plain and Shift, and its key type decides which modifiers pick which level. So each of the 29 keys that differ from QWERTY gets four levels: Dvorak, Dvorak with Shift, then QWERTY and QWERTY with Shift. Three of them:

```text
replace key <AB03> { type[Group1] = "DVQ_ALPHA", [ j, J, c, C ] };
replace key <AB04> { type[Group1] = "DVQ_ALPHA", [ k, K, v, V ] };
replace key <AC11> { type[Group1] = "DVQ_PUNCT",
                     [ slash, question, apostrophe, quotedbl ] };
```

No stock key type does this, so `custom-types` defines two. The lines that matter, from `DVQ_ALPHA`:

```text
modifiers = Shift + Lock + Control + Mod4;
map[Shift] = Level2;
map[Lock] = Level2;
map[Control] = Level3;            preserve[Control] = Control;
map[Control+Shift] = Level4;      preserve[Control+Shift] = Control;
map[Mod4] = Level3;               preserve[Mod4] = Mod4;
```

`preserve` is the important part. Without it, XKB counts Ctrl as used up by the key, and apps get a plain `c` instead of `Ctrl+C`. `Mod4` is Meta, so KDE's own shortcuts stay on their QWERTY keys too: `Meta+Alt+K` for the next layout, `Meta+L` to lock the screen. Alt on its own stays Dvorak, because menus underline the letter you type. `DVQ_PUNCT` is the same without Caps Lock, for keys whose Dvorak symbol isn't a letter. It's the idea behind macOS's "Dvorak - QWERTY ⌘" layout.

Two catches:

- **`type[Group1]`, not `type`.** My first try had `type = "DVQ_ALPHA"`, and `au`, the first layout, lost every Ctrl shortcut: `Ctrl+C` gave no symbol at all. A type without a group applies to every layout on that key. `Group1` is the layout's own group, and the `:2` that the second layout gets moves it to the right place.
- **The stock XKB option `custom:types` loads the types.** It reads `types/custom`, which libxkbcommon finds in `/etc/xkb` before the system folder. Without the option the types are unknown, every key falls back to one level, and Shift stops giving capitals. The script turns it on. It's also in System Settings > Keyboard > Key Bindings, under Miscellaneous options: "Use user-defined custom XKB types".

I tested the keymap in libxkbcommon itself, from Python: `Ctrl+C`, `V`, `X` and `Z`, `Ctrl+Shift+C`, `Ctrl+Alt+K` and `Meta+Alt+K` give the QWERTY letter with the modifiers still set, on `dvq` and on `au`. VS Code may still use the Dvorak positions, because it matches shortcuts by physical key and the layout's plain symbols. If it does, set `"keyboard.dispatch": "keyCode"` in its settings. I haven't tried that yet.

## Step 4: evdev.xml

KWin finds the layout without it. System Settings only lists layouts from `evdev.xml` files, though, and libxkbregistry merges this small one with the system list. The layout then shows up in System Settings > Keyboard > Layouts as "English (Dvorak, QWERTY brackets and -=)", with the short label `dvq`.

## Step 5: Install

```bash
bash install.sh
```

Run it as yourself, not with sudo: it asks for the password once, for the copy. It's safe to run again. What it does:

1. Compiles the layout with `xkbcomp` from a temporary folder, so a typo stops it before anything is installed.
2. Copies the three files to `/etc/xkb/symbols/dvorak-qwerty`, `/etc/xkb/types/custom` and `/etc/xkb/rules/evdev.xml`. It stops if someone else's `types/custom` is already there.
3. Turns on `custom:types` in `~/.config/kxkbrc`, after your other options.
4. Adds `dvorak-qwerty` after your current layouts in `~/.config/kxkbrc`, labelled `dvq`. With no layouts set yet, it starts from the system's (`localectl`).
5. Sets `Meta+Alt+K` (Switch to Next Keyboard Layout) if it's empty. Mine was.

KWin 6.6 ignores the old `reloadConfig` DBus signal on `/Layouts`. It reloads its layouts when `kxkbrc` changes through `kwriteconfig6 --notify`, and only when a value actually changes, so the script writes each key that way.

## Step 6: Log out and back in, the first time

On the first install, the script ends with:

```text
🟠 KWin hasn't loaded it yet: it only searches /etc/xkb if that existed when KWin started. Log out and back in
```

libxkbcommon looks for layouts in `~/.config/xkb`, `~/.xkb`, `/etc/xkb`, then `/usr/share/X11/xkb`. KWin builds that list once, when it starts, and leaves out folders that don't exist yet. On my laptop none of the first three existed, so KWin only searched `/usr/share/X11/xkb`. KWin logs to the system journal, not your user journal:

```bash
journalctl -b _COMM=kwin_wayland | grep -i xkb
```

```text
kwin_xkbcommon: XKB: [XKB-338] Couldn't find file "symbols/dvorak-qwerty" in include paths
kwin_xkbcommon: XKB: [XKB-338] 1 include paths searched:
kwin_xkbcommon: XKB: [XKB-338]         /usr/share/X11/xkb
kwin_xkbcommon: XKB: [XKB-338] 3 include paths could not be added:
kwin_xkbcommon: XKB: [XKB-338]         ~/.config/xkb
kwin_xkbcommon: XKB: [XKB-338]         ~/.xkb
kwin_xkbcommon: XKB: [XKB-338]         /etc/xkb
kwin_xkbcommon: XKB: [XKB-661] Couldn't process include statement for 'dvorak-qwerty'
```

KWin then keeps the layouts it had, so nothing changes on screen.

[Image: Two panels of libxkbcommon's search folders. Left, KWin started before /etc/xkb existed: ~/.config/xkb, ~/.xkb and /etc/xkb are crossed out and only /usr/share/X11/xkb is searched. Right, after logging out and in: /etc/xkb is searched and has symbols/dvorak-qwerty]

*The same four folders before and after a log-out.*

Log out and back in, and KWin starts with `/etc/xkb` in its list. After an edit to the layout, run the script again and log out once more.

The first install put the files in `~/.config/xkb`. When KWin didn't load them, the first guess was its `cap_sys_nice` capability: libxkbcommon ignores home-folder paths in programs that run with extra privileges. That's why the files moved to `/etc/xkb`, which didn't help either. The log above shows the guess was wrong: `~/.config/xkb` is in KWin's list, it just didn't exist yet. It should work after a log-out too, but I haven't tried it.

## Step 7: Switch layouts

`Meta+Alt+K` goes to the next layout, and the tray icon shows `au` or `dvq`. If the script found that shortcut already set, it left it: look in System Settings > Shortcuts > Keyboard Layout Switcher.

The lock screen uses whichever layout is active. If your password fails there, check the layout first.

## Remove it

In System Settings > Keyboard, remove `dvq` under Layouts and untick "Use user-defined custom XKB types" under Key Bindings. Then delete the files:

```bash
sudo rm /etc/xkb/symbols/dvorak-qwerty /etc/xkb/types/custom /etc/xkb/rules/evdev.xml
```

Keep that order: with the option still on and `types/custom` gone, no keymap compiles, not even `au`.

## Sources

- [libxkbcommon: user configuration](https://xkbcommon.org/doc/current/custom-configuration.html): the search folders and the `evdev.xml` format
- [libxkbcommon: the XKB keymap text format](https://xkbcommon.org/doc/current/keymap-text-format-v1-v2.html): key types, levels and `preserve`
- [xkeyboard-config: symbols/us](https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/us): `us(dvorak)`
- [xkeyboard-config: symbols/gb](https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/gb): `gb(dvorak)` and `gb(dvorakukp)`

## Change history

- 2026-10-30: First published.

Licence: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Credit "HomeLab Guides (blog.jacq.cc)" with a link to https://blog.jacq.cc/guides/dvorak-qwerty-brackets-kde-wayland/. Code downloads: MIT. Details: https://blog.jacq.cc/licence/
