Keyboard & Input Methods
Marchyo provides a unified way to configure keyboard layouts, variants, input methods (IMEs), and XKB options across the system (TTY/console) and the desktop environment (Hyprland + fcitx5).
Defaults
Section titled “Defaults”Out of the box:
layouts = [ { layout = "us"; variant = "altgr-intl"; } "fi" ]options = [ "grp:win_space_toggle" ](Super+Space switches layout/IME)composeKey = "menu"
The altgr-intl variant (“English (US, intl., AltGr dead keys)”) behaves like a plain US layout for the unmodified keys — ', ", `, ~, ^ produce their normal characters, not dead keys. The international characters live behind the AltGr modifier (Right Alt).
Typography on AltGr
Section titled “Typography on AltGr”| Sequence | Result |
|---|---|
AltGr + - |
– (en dash) |
AltGr + Shift + - |
— (em dash) |
AltGr + 9 / AltGr + 0 |
‘ / ’ (curly single quotes) |
AltGr + Shift + 9 / AltGr + Shift + 0 |
“ / ” (curly double quotes) |
AltGr + [ / AltGr + ] |
« / » (guillemets) |
AltGr + 5 |
€ |
AltGr + 4 |
¤ (currency) |
The Menu key acts as Compose for everything else (Menu then ' then e → é, Menu then - - - → —, etc.).
If you want the stronger dead-key behavior of plain us(intl) (where ', ", `, ~, ^ wait for a follow-up letter):
marchyo.keyboard.layouts = [ { layout = "us"; variant = "intl"; } "fi" ];If you have no Menu key, point Compose elsewhere (or disable it):
marchyo.keyboard.composeKey = "caps"; # or "rwin", "rctrl", or nullLayouts
Section titled “Layouts”The marchyo.keyboard.layouts option accepts a list of layouts. Each can be a simple string or an attribute set for advanced configuration.
Simple layouts
Section titled “Simple layouts”marchyo.keyboard.layouts = [ "us" "fi" "de"];Layouts with variants
Section titled “Layouts with variants”marchyo.keyboard.layouts = [ "us" { layout = "us"; variant = "intl"; } # US International with dead keys { layout = "us"; variant = "dvorak"; }];Layouts with input methods
Section titled “Layouts with input methods”For CJK languages and other complex input, specify an IME:
marchyo.keyboard.layouts = [ "us" { layout = "cn"; ime = "pinyin"; } # Chinese with Pinyin { layout = "jp"; ime = "mozc"; } # Japanese with Mozc { layout = "kr"; ime = "hangul"; } # Korean with Hangul { layout = "us"; ime = "chewing"; } # Traditional Chinese with Zhuyin { layout = "us"; ime = "cangjie"; } # Hong Kong Cangjie 5];When an entry includes ime, the engine is added to the fcitx5 group after the keyboard layouts. Input starts in Latin (the keyboard layout), not in the engine. Korean (layout = "kr" with hangul) uses the kr104 variant.
Available IMEs
Section titled “Available IMEs”| IME | Language | Required package |
|---|---|---|
"pinyin" |
Chinese | qt6Packages.fcitx5-chinese-addons |
"mozc" |
Japanese | fcitx5-mozc |
"hangul" |
Korean | fcitx5-hangul |
"chewing" |
Traditional Chinese (Zhuyin) | fcitx5-chewing |
"cangjie" |
Hong Kong Chinese (Cangjie 5) | fcitx5-table-extra |
"unicode" |
Unicode picker | — |
Required packages are installed automatically when an IME is specified.
Layout attribute set options
Section titled “Layout attribute set options”| Option | Type | Default | Description |
|---|---|---|---|
layout |
string |
— | Keyboard layout code (e.g., "us", "fi", "cn") |
variant |
string |
"" |
Layout variant (e.g., "intl", "dvorak") |
ime |
string or null |
null |
Input method engine |
label |
string or null |
null |
Display label (auto-generated if null) |
Keyboard switching
Section titled “Keyboard switching”XKB options
Section titled “XKB options”Use marchyo.keyboard.options for standard XKB options. Default: ["grp:win_space_toggle"] (Super+Space to switch layouts).
marchyo.keyboard.options = [ "grp:win_space_toggle" # Super+Space to switch inputs "ctrl:swapcaps" # Swap Caps Lock and Left Control "caps:escape" # Map Caps Lock to Escape];Compose key
Section titled “Compose key”The compose key lets you type special characters via key sequences (e.g., Compose + ' + e = é).
marchyo.keyboard.composeKey = "shift-caps"; # Shift+Caps Lock (default: "menu")| Value | Key |
|---|---|
"menu" |
Menu key (default) |
"shift-caps" |
Shift+Caps Lock (Hyprland only) |
"ralt" |
Right Alt — avoid when using us(altgr-intl) or us(intl) (it needs Right Alt as AltGr) |
"rwin" |
Right Super/Windows |
"caps" |
Caps Lock |
null |
Disable compose key |
IME behavior
Section titled “IME behavior”Latin by default
Section titled “Latin by default”Input methods are off when a text field gets focus. Set autoActivateIME = true to start with the engine active:
marchyo.keyboard.autoActivateIME = true;Switching
Section titled “Switching”- A lone Shift (left or right) toggles between the current engine and Latin.
Super+Spaceand every key inimeTriggerKeycycle through the keyboard layouts first, then the engines.
marchyo.keyboard.imeTriggerKey = [ "Super+I" ]; # DefaultCJK fonts
Section titled “CJK fonts”When an ime of mozc, hangul, pinyin, chewing or cangjie is configured, Noto CJK is installed and fontconfig appends the matching region to the sans-serif, serif and monospace families:
mozc: JP (ja)hangul: KR (ko)pinyin: SC (zh-cn)chewing: TC (zh-tw)cangjie: HK (zh-hk)
Text tagged with a language gets that language’s forms. Untagged text uses the region of the first configured engine.
Fn mode
Section titled “Fn mode”marchyo.keyboard.fnMode = "media"; # top row sends media keys, Fn gives F1-F12marchyo.keyboard.fnMode = "function"; # top row sends F1-F12, Fn gives media keysnull (default) leaves the firmware or driver default. This writes hid_apple fnmode (1 = media keys first, 2 = F-keys first) and hid_asus / asus_wmi fnlock_default to modprobe. Keyboards that keep Fn-lock in firmware ignore it. hid_asus and asus_wmi read it at load time, so it applies after a reboot.
Keyboard backlight
Section titled “Keyboard backlight”marchyo.keyboard.backlight.enable (default true) binds XF86KbdBrightnessUp/Down, XF86KbdLightOnOff and Ctrl plus the display brightness keys to marchyo brightness --keyboard up|down|toggle. It acts on the first *kbd_backlight* LED and shows the shell OSD when the shell is installed. The level survives reboots through the stock systemd-backlight@leds:* service, so nothing extra is installed.
Shift+Caps Lock as Compose
Section titled “Shift+Caps Lock as Compose”With composeKey = "shift-caps", Caps Lock stays Caps Lock and Shift+Caps Lock sends Compose. It cannot be combined with an option that remaps Caps Lock (ctrl:swapcaps, ctrl:nocaps, caps:escape). Marchyo installs a symbols file and an evdev rules extension in /etc/xkb and exports XKB_CONFIG_EXTRA_PATH=/etc/xkb, which libxkbcommon (Hyprland) reads. The console and X server do not see the option, so they get no compose key. The change applies to new sessions.
Full example
Section titled “Full example”marchyo.keyboard = { layouts = [ { layout = "us"; variant = "altgr-intl"; } { layout = "fi"; } { layout = "us"; variant = "intl"; } { layout = "cn"; ime = "pinyin"; } { layout = "jp"; ime = "mozc"; } ]; options = [ "grp:win_space_toggle" ]; composeKey = "menu"; autoActivateIME = false; imeTriggerKey = [ "Super+I" ];};How it works
Section titled “How it works”- NixOS (
services.xserver.xkb) — Basic layout codes and variants are applied to the console/TTY for fallback support outside the graphical environment. - Hyprland (
home.keyboard) — Layout and XKB options are passed to Hyprland’s input configuration. - fcitx5 — Acts as the authoritative input manager in the graphical environment, managing layouts, IMEs, and layout switching.
All options reference
Section titled “All options reference”| Option | Type | Default | Description |
|---|---|---|---|
marchyo.keyboard.layouts |
list of strings or attrsets | [{ layout = "us"; variant = "altgr-intl"; } "fi"] |
Keyboard layouts and input methods |
marchyo.keyboard.options |
list of strings | ["grp:win_space_toggle"] |
XKB keyboard options |
marchyo.keyboard.composeKey |
string or null | "menu" |
Compose key (the Menu key by default) |
marchyo.keyboard.fnMode |
"media", "function" or null |
null |
Top-row default for Apple/ASUS keyboards |
marchyo.keyboard.backlight.enable |
bool | true |
Keyboard backlight key binds |
marchyo.keyboard.autoActivateIME |
bool | false |
Start with the IME engine active |
marchyo.keyboard.imeTriggerKey |
list of strings | ["Super+I"] |
Keys that cycle layouts, then engines |
marchyo.keyboard.variant |
string | "" |
Deprecated: sets the variant of the first layout and warns. Use { layout = "us"; variant = "intl"; } in layouts (migration) |