A DE-independent keyboard layout auto-switcher for Linux Wayland.
Like PuntoSwitcher / CarambaSwitcher, but for Linux Wayland.
- Grabs the physical keyboard at the kernel level via
evdev— no compositor involvement. - Passes all keystrokes through a virtual
UInputkeyboard to the compositor. - Tracks a rolling word buffer of characters the user is typing.
- On word boundary (Space / Enter / Tab / punctuation): runs an n-gram language detector on the buffered word; if the word scores higher in another layout → auto-converts it.
- Direct Injection: Erases the word via Backspaces and re-types it in the correct layout directly through the virtual keyboard. No external tools like
ydotoolneeded! - Compositor Native: Switches system layout via D-Bus (GNOME, KDE) or compositor commands (Sway, Hyprland).
- DE Independent: Works on GNOME, KDE Plasma, Sway, Hyprland, and more.
- Multi-Layout Support: Supports 2, 3, or more layouts (e.g., English, Russian, and Ukrainian).
- Fast & Reliable: Uses direct
uinputinjection for near-instant text conversion. - Zero Configuration for Core: Auto-detects your desktop environment and keyboards.
- Linux Wayland session
- Python 3.11+
python-evdev,dasbus,click(Python packages)- User in
inputgroup
# 1. Install dependencies
pip install .
# 2. Setup permissions and config
python -m power_switcher setup
# 3. Build n-gram profiles (optional, built-in fallbacks provided)
python -m power_switcher.detection.build_profiles
# 4. Run daemon
python -m power_switcher daemon --verbose| Hotkey | Action |
|---|---|
Alt+Pause |
Convert current word + switch layout |
Alt+Pause (within 3s) |
Undo last conversion |
Ctrl+Alt+Z |
Convert selected text + switch layout |
Config file: ~/.config/power_switcher/config.toml
[general]
layouts = ["en", "ru"] # Supports 2+ layouts
hotkey_convert = "alt+pause"
hotkey_selection = "ctrl+alt+z"
default_layout = "en"
auto_detect = true
[detection]
threshold = 2.5
min_word_len = 3Built-in layouts: en, ru, ua, de.
Adding a new layout:
- Add a keycode→char table in
power_switcher/maps/keycode_map.py. - Register it in the
LAYOUTSdict. - Run
python -m power_switcher.detection.build_profiles.
Physical Keyboard → evdev grab → KeyProcessor → UInput passthrough → Compositor
│
├─ KeyBuffer (word tracking)
├─ ModifierState (shift/ctrl/alt)
├─ LayoutSet (multi-layout maps + n-gram profiles)
├─ LayoutBackend (D-Bus / IPC layout switch)
└─ UInput (direct text injection)
| DE/Compositor | Backend | Notes |
|---|---|---|
| GNOME | GNOMESwitchBackend |
Uses UInput key simulation for layout switching. |
| KDE Plasma | KDELayoutBackend |
Uses D-Bus org.kde.keyboard. |
| Sway | SwayLayoutBackend |
Uses swaymsg. |
| Hyprland | HyprlandLayoutBackend |
Uses hyprctl. |
MIT