Rust Hyprland multibox controller for World of Warcraft - rewrite of enBuddy
Go to file
en 9d2f51685d Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams
Layout wizard (T7):
- App::layout_canvas with monitor backgrounds, click-to-select, draggable tiles
- borderless Hyprland window_rule on run
- App::refresh_monitors + Refresh monitors button; monitors cache for canvas sync

Routing extras (T8, T13, T14):
- clipboard IPC verb (wl-paste / xclip -> Ctrl+V to non-leader slots)
- mirror-mode mouse click broadcast via hypr::deliver_click
- round_robin / rr bind target rotates through ALL slots (leader included)

Slot overlay (T9 real):
- src/wayland_layer.rs: zwlr_layer_shell_v1 client, shm buffers, 3x5 bitmap
  digit glyphs, wl_pointer click -> swap <slot>
- gated ENBOXER_ENABLE_OVERLAY=1; cargo test does not connect

Covered-window VFX capture (T10 real):
- src/toplevel_export.rs: zwlr_export_dmabuf_unstable_v1 client
- ARGB8888 / XRGB8888 format negotiation, synthetic-PNG fallback for tests
- gated ENBOXER_ENABLE_TOPLEVEL=1; gbm_bo_map upgrade documented

Teams + Lutris launcher (T15):
- src/team.rs: Team, list_teams, teams_dir, current_team
- src/lutris.rs: LutrisGame parser, load_all with bad-YAML tolerance
- src/launcher.rs: SpawnPlan merges Lutris config + per-character wine-prefix
- GUI: Teams menu (New / Switch / Refresh / Show / Delete) + Launch menu
- Lutris picker visible only in New-team flow; direct Wine spawn, no lutris CLI

Tests: 89 passed; 0 failed (up from 24).
Clippy: clean with -D warnings.

Safety:
- No live hyprctl dispatch that moves / resizes / pins / closes the session.
- All Wayland paths feature-gated; cargo test does not connect.
- apply_layout still gated by allow_layout + confirm_apply.

Files: 14 modified + 6 new (src/{launcher,lutris,overlay,team,toplevel_export,wayland_layer}.rs)
Diff: +1570 / -29
2026-09-15 17:18:37 +02:00
docs Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
examples Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
src Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
.gitignore Initial enBoxer: mapped-key routing and Video FX on Hyprland. 2026-09-15 07:19:15 +02:00
AGENT.md Document full product goals; gate layout; named profiles; type-to-others. 2026-09-15 09:11:31 +02:00
AGENTS.md Document full product goals; gate layout; named profiles; type-to-others. 2026-09-15 09:11:31 +02:00
Cargo.lock Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
Cargo.toml Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
CHANGELOG.md Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00
DESCRIPTION.md Point remote at https://gitea.nettsi.de/en/enbuddy 2026-09-15 07:26:44 +02:00
GOALS.md Document full product goals; gate layout; named profiles; type-to-others. 2026-09-15 09:11:31 +02:00
LICENSE Initial enBoxer: mapped-key routing and Video FX on Hyprland. 2026-09-15 07:19:15 +02:00
opencode.json Initial enBoxer: mapped-key routing and Video FX on Hyprland. 2026-09-15 07:19:15 +02:00
PLAN.md Document full product goals; gate layout; named profiles; type-to-others. 2026-09-15 09:11:31 +02:00
README.md Document full product goals; gate layout; named profiles; type-to-others. 2026-09-15 09:11:31 +02:00
TASKS.md Finish the project (T7..T15): layout wizard, broadcast, overlay, dmabuf, teams 2026-09-15 17:18:37 +02:00

enBoxer

Mapped-key routing and live window crops for World of Warcraft on Arch Linux + Hyprland. Rust.

You list which hotkeys go where. Everything you do not list stays on the focused primary. A passthrough list can leave movement keys alone (the example uses ESDF). Alt-tab off the team and the desktop is normal.

Nothing is loaded into the game. Hyprland delivers keys with hl.dsp.send_shortcut. You bind macros in WoW yourself.

Doc What
GOALS.md What this project is for (read this)
AGENTS.md Rules for Grok / OpenCode
PLAN.md Shipped vs next
DESCRIPTION.md One-page description
AGENT.md Designer / PM / worker contract
TASKS.md OpenCode tickets
CHANGELOG.md What landed
docs/DESIGN.md Routing model
docs/NOTES.md WoW interact / Hyprland capture
docs/VIDEO.md Live crop of another client
docs/MACROS.md In-game macros

Routing (three modes)

Toggle with Shift+Alt+M (configurable) or enboxer mode maps|mirror|off while the daemon runs. A Hyprland notification shows the new mode.

  1. maps — only keys you listed under maps are intercepted and sent where the map says. Everything else goes to the front window.
  2. mirror — the front window still gets the real key; the same key is cloned to the other game windows. passthrough (e.g. ESDF) is not cloned.
  3. off — nothing is intercepted. All keys go to the front window. The mode-toggle hotkey still works.

A map is a hotkey plus steps (send a key, send a named game_bind, wait) plus a target.

Interact / loot

WoWs Interact with Target bind (plus Click to Move) walks an alt to the target and loots or talks. One press. Spamming it makes characters circle. The stock loot map: assist others → CTM on → interact once → wait walk_delay_ms → CTM off. See docs/MACROS.md.

Video FX

A region of another client is captured (grim) and shown on the primary. While the cursor is over that viewer, keys and clicks go to the source slot only. Covered sources need compositor toplevel export (not in this phase); keep the source visible for a live picture.

Optional Hyprland snippet: examples/hyprland.lua.

Build

cd ~/git/enBoxer
cargo build --release
install -Dm755 target/release/enboxer ~/.local/bin/enboxer

Needs Hyprland 0.56 (Lua dispatchers), hyprctl, grim, and mpv (Video FX overlay).

Use

enboxer          # control panel (File / Session / Video / Maps)
enboxer run -c ~/.config/enboxer/profile.yaml   # daemon only
enboxer doctor

The GUI saves ~/.config/enboxer/profile.yaml. Start routing from Session → Start routing.

Layout places every captured client (stacked / grid / main+strip), then Make main swaps a minion into the large tile. Hotkeys: Ctrl+` swap next, Ctrl+F1… focus slot, Ctrl+Shift+F2… swap that slot to main, Ctrl+Shift+R reset layout.

enboxer press Alt+G fires a map without a Hyprland bind (daemon must be running).

License

GPL-3.0-or-later.