A modern, intuitive graphical frontend plugin for Omarchy Linux to view, search, modify, and create Hyprland keybindings with live interactive key recording, smart free key recommendations, collision detection, and safe Lua synchronization.
- 🚀 On-Demand Launch: Summon the floating manager anytime via
omarchy-shell shell summon meviusisback.keybinds(or bind it to a key) — no top status bar clutter. - 🗂 Category Filter Chips with Counts: Chips are generated from the backend, so they always match the classifier in
backend/keybinds_manager.py(CATEGORY_ORDER) and show how many rows each one contains. Each binding is categorized by what it does (Workspace / Window / App / System / Display / Capture / Clipboard / Media / Notification / Voice / Island / Terminal (ghostty) / Terminal (herdr) / Custom) rather than by which Omarchy file happens to define it — that keeps dozens of unrelated things out of one bucket and personal overrides out of "Custom". The list is grouped by category, alphabetically inside each group. - 🔤 Alphabetical Sorting: Within every category, active bindings and catalog presets are sorted in case-insensitive alphabetical order by action name.
- ⭐ Dedicated Modified & Custom Section: Easily review and manage all personal shortcut overrides and custom keybindings in one place with 1-click ↺ Reset to Default and 🗑️ Delete.
- 🈶 Chinese Labels (display-only): every row shows a Chinese description from
DESCRIPTION_ZHinbackend/keybinds_manager.py, with the English original kept beside it in dim text. Only the display changes - the configs still hold the English descriptions, because Omarchy's own binding files are overwritten by package updates,island-bindings.luais regenerated by the island's settings, and the backend matches an override against the default it replaced by description. Anything missing from the table simply renders in English;python3 tests/test_backend.pyfails loudly if an Omarchy default or catalog preset has no label. - 💡 Smart Free Key Recommendations: When creating or editing an action, the modal automatically scans for 100% free, unassigned shortcuts matching the action's first letter (e.g.
SUPER + S,SUPER + SHIFT + Sfor Spotify) and offers 1-click suggestion chips. - ⌨️ Multi-Method Key Recorder:
- Live keyboard capture: click to record and press any combination.
- Modifier toggle pills: toggle SUPER, CTRL, ALT, or SHIFT with ease.
- Quick-key chips: instantly select common special keys (RETURN, SPACE, ESCAPE, TAB, F1-F12).
⚠️ Collision Detection & 1-Click Rebind: Detects shortcut collisions in real-time, displays detailed conflict cards, and offers 1-click rebind options for colliding actions.- 📜 Actions Catalog: Browse pre-configured Hyprland / Omarchy window management, workspace, media, and system presets ready to bind.
- 🖱️ Mouse Scroll Sync: Automatically respects your configured scroll sensitivity multiplier (
scroll_factor) and direction (natural_scroll) from the Mouse Settings plugin (meviusisback.mouse-settings). - 🔍 Record-to-Find Shortcut Lookup: Click Record to Find next to the search bar and press any key chord on your keyboard to instantly locate its assigned action (or reveal that it's unassigned with a 1-click + Create Keybinding shortcut).
- 🖥️ Terminal Layers, Read-Only (
⌨️ Terminal (ghostty),🤖 Terminal (herdr)): A keystroke is offered to three owners, outermost first — Hyprland (owns theSUPERchords), then ghostty (its ownkeybindentries), then herdr inside that window. The panel lists the two inner layers too, by shelling out toghostty +list-keybinds/+show-config --defaultand parsing the[keys]table of~/.config/herdr/config.toml. Those rows carrymanaged_by, which is the flag the panel already uses to hide edit/reset/delete (they belong to another config file), plus ghostty's=unbindentries as struck-through "已解绑" rows naming the action they removed. See 键盘三层模型. - 🕳 Cross-Layer Shadow Detection: Two rows in different layers sharing a chord is not a Hyprland conflict, so it is reported separately as
shadowed_by: Hyprland|ghostty(rendered asDEAD - <layer> rebinds this key). This is what catches the classic failure where an inner-layer binding is perfectly valid but silently unreachable. - 🔄 Safe Lua Sync & Live Reload: Writes directly to
~/.config/hypr/bindings.lua(with automatic.bakbackups) and invokeshyprctl reloadfor instantaneous application without session restarts.
Install directly from the marketplace with the Omarchy CLI (it clones and links the plugin into ~/.config/omarchy/plugins/):
omarchy plugin add https://github.com/meviusisback/keybinds-plugin --enableOn first launch, the plugin will offer to add a Keybindings Manager entry to your Omarchy launcher (Setup → Keybindings → Keybindings Manager). You can accept or dismiss this — it only asks once per session. You can also toggle this anytime from the 📋 Add to Launcher / ✓ In Launcher button in the app's header bar.
- Summon the plugin via
omarchy-shell shell summon meviusisback.keybinds(or your configured launcher/keybinding). - Search by shortcut (e.g.
SUPER + W), action name (e.g.Terminal), category, or command.
The plugin's bin/ directory is not on PATH by default — Omarchy only puts
/usr/share/omarchy/bin there. Either call the wrapper by its installed path:
~/.config/omarchy/plugins/meviusisback.keybinds/bin/omarchy-keybindsor link it once into your personal bin (the wrapper resolves symlinks correctly):
mkdir -p ~/.local/bin
ln -s ~/.config/omarchy/plugins/meviusisback.keybinds/bin/omarchy-keybinds ~/.local/bin/omarchy-keybinds
omarchy-keybinds # launch the GUI directlyOr summon via the shell IPC:
omarchy-shell shell summon meviusisback.keybinds '{}'Note: as a panel plugin, nothing appears until it is summoned, and the raw IPC
exits 0 even when the shell refuses it (it answers ok / unknown — e.g. while
the plugin is disabled). The wrapper turns a refusal into a visible error with
the matching omarchy plugin enable hint.
The plugin includes a full-featured CLI backend engine:
# One-time setup if you want the short command name (see "From the Terminal"):
# ln -s ~/.config/omarchy/plugins/meviusisback.keybinds/bin/omarchy-keybinds ~/.local/bin/omarchy-keybinds
# List all active keybindings, presets, conflicts, and mouse settings in JSON
omarchy-keybinds list
# Create or modify a shortcut
omarchy-keybinds set "<KEY>" "<DESCRIPTION>" "<COMMAND>" "[ACTION_LUA]" "[OLD_KEY]"
# Example:
omarchy-keybinds set "SUPER + SHIFT + B" "My Browser" "omarchy-launch-browser"
# Reset a modified shortcut back to Omarchy default
omarchy-keybinds reset "SUPER + SHIFT + B"
# Disable / unbind a shortcut
omarchy-keybinds disable "SUPER + W"
# Re-enable a previously disabled default shortcut
omarchy-keybinds enable "SUPER + W"
# Reload Hyprland configuration
omarchy-keybinds reload
# Read-only view of the layers inside the terminal window (ghostty + herdr),
# including which chords never reach their layer
omarchy-keybinds terminal一次按键依次交给三个主人,越靠外越优先:
| 层 | 配置文件 | 能用的键 | 谁写 |
|---|---|---|---|
| ① Hyprland | ~/.config/hypr/bindings.lua(本插件写这个) |
SUPER 全家 + 任意未被占用的组合 |
本插件 / omarchy-keybinds |
| ② ghostty | ~/.config/ghostty/config |
ctrl+… / alt+… / super+…(只要 ① 没占) |
keybind = 触发器=动作,keybind = X=unbind 把键让给内层 |
| ③ herdr | ~/.config/herdr/config.toml [keys] |
prefix+… 或 alt+…/ctrl+alt+… 直连键 |
herdr 自己 |
结论与规矩:
- ① 抢走的键,② ③ 永远收不到;ghostty 绑住的键,herdr 也收不到(除非那条 ghostty 条目是
=unbind,或用csi:/esc:/text:/unconsumed:把键转进去)。所以「herdr 的alt+3按了没反应」通常不是 herdr 的问题,而是 ② 吃掉了它 —— 面板里这类行会显示DEAD - ghostty rebinds this key。 - ghostty 的
super+…组合只有在 Hyprland 没绑 时才能穿透到窗口里。 - ghostty 没有行内注释:
keybind = X=unbind # 说明会报error.InvalidAction,注释必须单独一行。 - 改完 ghostty 配置在窗口里按
ctrl+shift+,(内置reload_config)立即生效;ghostty +validate-config可离线校验;ghostty +list-keybinds显示真正生效的集合。 - 本插件只写
bindings.lua。② ③ 两层在面板里是只读分组,改它们请编辑各自的配置文件。
The plugin manages personal overrides in ~/.config/hypr/bindings.lua:
- Custom / Rebound Keybindings: Generated with standard
o.bind(...)directives. - Disabled Keybindings: Generated with
hl.unbind(...)directives. - Safety Backups: A backup (
bindings.lua.bak) is created automatically before any write operation. - Comment Preservation: Personal comments and manual custom blocks in
bindings.luaare preserved.
Automated unit tests cover key normalization, Lua parser safety, comment handling, unbind detection, and conflict evaluation:
tests/run # or: tests/run -v, tests/run TestKeybindsBackendtests/run is python3 -B -m unittest discover -s tests -p "test_*.py": the
-B matters. The shell watches this plugin folder and reloads every plugin when
anything in it changes, so a stray tests/__pycache__/*.pyc from a plain
unittest run blinks the desktop bar mid-use.
# Remove the plugin from Omarchy (keeps your personal ~/.config/hypr/bindings.lua untouched)
omarchy-shell shell hide meviusisback.keybinds >/dev/null 2>&1 || true
omarchy-shell shell removePlugin meviusisback.keybinds >/dev/null 2>&1 || true
rm -f ~/.config/omarchy/plugins/meviusisback.keybinds- Local-only: The plugin runs entirely on your machine. It has no network access, no telemetry, and reads only your Hyprland keybinding configuration (
~/.config/hypr/bindings.luaand the Omarchy default bindings). - No keylogging: The interactive recorder captures keystrokes only in-memory to display the pressed chord; nothing is persisted to disk or transmitted.
- Safe Lua writes: All key chords, descriptions, and commands are validated and escaped before being written to
bindings.lua. Invalid chords (containing characters that could break out of a Lua literal) are rejected, and string values are escaped so a crafted binding description cannot inject arbitrary Lua. - Automatic backups: Every write first copies the existing
bindings.luatobindings.lua.bakand applies the change atomically via an atomic rename.
keybinds-plugin/
├── manifest.json # Omarchy plugin manifest (declares kind: ["panel"], keepLoaded: true)
├── KeybindsPanel.qml # Main GUI window with search, category tabs, and active key list
├── EditKeybindDialog.qml # Modal dialog for creating/editing shortcuts with smart free recommendations
├── KeyRecorder.qml # Interactive keyboard event catcher, modifier pills, and live conflict check
├── KeyBadge.qml # Visual keyboard chord badge renderer
├── bin/
│ └── omarchy-keybinds # CLI wrapper script
├── backend/
│ └── keybinds_manager.py # Python engine for parsing defaults, user Lua config, conflicts, and mouse sync
├── tests/
│ └── test_backend.py # Unit tests for parser and backend operations
└── README.md # Documentation
Distributed under the MIT License. See LICENSE for details.
