This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
cargo build --release # Build optimized binary
cargo run # Run in debug mode
cargo clippy # Lint
cargo publish --allow-dirty # Publish to crates.ioAUR package: kb-layout-daemon-git
The daemon requires the user to be in the input group. For testing without logout:
sg input -c "./target/release/kb-layout-daemon"Control via D-Bus:
dbus-send --session --print-reply --dest=org.kblayout.Daemon /org/kblayout/Daemon org.kblayout.Daemon.GetMode
dbus-send --session --print-reply --dest=org.kblayout.Daemon /org/kblayout/Daemon org.kblayout.Daemon.ToggleMode
dbus-send --session --print-reply --dest=org.kblayout.Daemon /org/kblayout/Daemon org.kblayout.Daemon.SetMode string:"passive"Single-binary daemon with one main.rs file (~445 lines). Key components:
Global State (atomics)
GRAB_MODE: AtomicBool- Current mode (grab vs passive)CURRENT_LAYOUT: AtomicU32- Tracks active keyboard layout index
Threading Model
- Main thread: Initializes config, finds keyboards, spawns monitor threads
- One thread per physical keyboard: Runs
monitor_keyboard()loop - D-Bus service thread: Runs async tokio runtime for
org.kblayout.Daemon
Two Operating Modes
- Grab mode: Exclusive device access via
EVIOCGRAB, events forwarded through uinput virtual keyboard. Ensures correct layout on first keystroke (~1ms latency). - Passive mode: No device grabbing, just monitors events. Zero latency but first key after switch may use old layout.
Key Functions
load_config()- Reads~/.config/kb-layout-daemon/config.tomlfind_keyboards()- Scans/dev/input/event*matching config namesmonitor_keyboard()- Per-keyboard event loop (grab/read/forward)create_virtual_keyboard()- Creates uinput device with KEY, MSC_SCAN, and REL axesswitch_layout()- D-Bus call toorg.kde.keyboardto change layout
Virtual Keyboard Requirements The virtual keyboard must include MSC_SCAN events and relative axes, otherwise some keys won't work in grab mode.
~/.config/kb-layout-daemon/config.toml
Find keyboard device names with:
cat /proc/bus/input/devices | grep -A 4 "Name="Located in widget/ directory. Install to ~/.local/share/plasma/plasmoids/org.kblayout.toggle/. Uses Plasma5Support.DataSource with "executable" engine to run D-Bus commands.