Skip to content

About

Omarchy 键位管理插件(fork of meviusisback/keybinds-plugin)· 自写改动在 local 分支

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Omarchy Keybindings Plugin (meviusisback.keybinds)

Omarchy Linux Quickshell Python 3.10+ License: MIT

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.


✨ Features

  • 🚀 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_ZH in backend/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.lua is 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.py fails 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 + S for 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 the SUPER chords), then ghostty (its own keybind entries), then herdr inside that window. The panel lists the two inner layers too, by shelling out to ghostty +list-keybinds / +show-config --default and parsing the [keys] table of ~/.config/herdr/config.toml. Those rows carry managed_by, which is the flag the panel already uses to hide edit/reset/delete (they belong to another config file), plus ghostty's =unbind entries 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 as DEAD - <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 .bak backups) and invokes hyprctl reload for instantaneous application without session restarts.

🚀 Installation

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 --enable

On 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.


📖 Usage

From the Graphical Desktop

  1. Summon the plugin via omarchy-shell shell summon meviusisback.keybinds (or your configured launcher/keybinding).
  2. Search by shortcut (e.g. SUPER + W), action name (e.g. Terminal), category, or command.

From the Terminal

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-keybinds

or 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 directly

Or 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.


🛠️ CLI Command Reference

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。② ③ 两层在面板里是只读分组,改它们请编辑各自的配置文件。

⚙️ Configuration & Lua Sync

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.lua are preserved.

🧪 Testing

Automated unit tests cover key normalization, Lua parser safety, comment handling, unbind detection, and conflict evaluation:

tests/run                    # or: tests/run -v, tests/run TestKeybindsBackend

tests/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.



🗑️ Removal

# 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

🔒 Security & Privacy

  • 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.lua and 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.lua to bindings.lua.bak and applies the change atomically via an atomic rename.

🏗️ Architecture

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

📄 License

Distributed under the MIT License. See LICENSE for details.

About

Omarchy 键位管理插件(fork of meviusisback/keybinds-plugin)· 自写改动在 local 分支

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages