- arm_auto_apply (gui.rs ~1625): compile profile.window_match.class and .title regexes once, then poll hyprctl for a client that matches before firing layout-apply. Fall back to 'first non-empty class' when neither pattern is configured, so existing profiles keep working. Closes the security/correctness gap where any open window could trigger layout-apply against the desktop. - New-team wizard (gui.rs ~1438): profile.characters.truncate is replaced with resize(slots, Character::default()) so a wizard with N members and zero existing characters now actually gets N Launch buttons. Character gains #[derive(... Default)]. - CHANGELOG entries. cargo test 96+/0; clippy clean.
6.0 KiB
Changelog
0.1.0 — unreleased
- Rust CLI daemon:
enboxer run|press|status|macros|doctor - YAML profile: maps, targets (
current/others/all/ groups),game_binds - Configurable
passthrough(empty by default; example profile uses ESDF) - Hyprland 0.56 Lua binds installed only while a managed game or VFX overlay is focused
- Key delivery via
hl.dsp.send_shortcut/send_key_state(no game injection) - Stock loot map: assist → CTM on → Interact with Target once → delay → CTM off
- Video FX:
grimregion capture, overlay viewer, hover pass-through to source slot - Unit tests for hotkey parse, passthrough, targets, loot sequence, example profile load
- Bind IPC line no longer duplicated
ipc(Hyprland hotkeys actually reach the daemon) - Video FX overlay is
mpv(--wayland-app-id=enboxer-vfx) with JSON reload;grimcapture enboxer runclears binds on ctrl-c; emptywindow_matchmatches nothing- Live check:
send_shortcutto an unfocused XWayland window; overlay window classenboxer-vfx - Per-character
assist_key/follow_key; map steps usingbind: assist|followresolve to the current main's keys - Layout wizard
borderlesstoggle installs a Hyprlandwindow_rule(rounding 0, border_size 0) onrun - Layout page: drag canvas over the monitor rectangle; tile moves clamp to the monitor bounds
- T8: clipboard IPC verb
clipboardreadswl-paste/xclipand delivers Ctrl+V to every non-leader captured slot; GUI button on Session page; routing plan unit-tested - T11: named-profiles list in File menu (
Load named…submenu) with Refresh; listing helper unit-tested against a tempdir - T12: unit test for
type_to_othersrouting (others_clientshelper, excludes leader, per-char × per-slot plan) and forapply_layoutshort-circuiting whenENBOXER_ALLOW_LAYOUTis unset - T9 (real):
src/wayland_layer.rs—zwlr_layer_shell_v1Wayland client with shm-backed buffers, 3×5 bitmap digit glyphs,wl_pointerclick routing; per-slotOverlayHandleviaOverlayHubinsession::run. Live path gated behindENBOXER_ENABLE_OVERLAY=1;cargo testdoes not connect to Wayland - T10 (real):
src/toplevel_export.rs—zwlr_export_dmabuf_unstable_v1Wayland client; per-frame format negotiation (ARGB8888 / XRGB8888), synthetic-PNG fallback for tests. Live path gated behindENBOXER_ENABLE_TOPLEVEL=1;gbm_bo_mapis documented as the upgrade step for actual pixel reads - T13: mirror-mode mouse click broadcast —
hypr::deliver_clickposts compositor pointer events to every non-leader captured slot; press-and-hold guard deferred - T14: round-robin bind target (
round_robin/rr) — rotates through ALL slots including the leader, in slot-number order, wrapping; per-map cursor - T15: Teams + Lutris launcher.
src/team.rs(Team, list_teams, teams_dir, current_team),src/lutris.rs(LutrisGame parser,load_allwith bad-YAML tolerance),src/launcher.rs(SpawnPlan merging Lutris config with per-character wine-prefix override). GUI: Teams menu (New / Switch / Refresh / Show / Delete) and Launch menu (per-character + Launch all); Lutris picker visible only in the New-team flow. Direct Wine spawn — never callslutrisCLI game_binds.interactexample uses Alt+J (Master's request). Interact with Target is a built-in WoW keybind; enBoxer just routes the keystroke.docs/MACROS.mdrewritten for current retail (The War Within era, 2026): rename "CTM" → Auto-Interact (the CVar), document Alt+J for Interact with Target, document per-character Assist / Follow macro override, add optional Pet Attack / Target Last Target keybinds.
Unreleased — Interact chain (ISBoxer-style mapped key)
- Smart interact shortcut. A step with
bind: interactnow expands at compile time into the full CTM-on → Interact-with-Target → sleepwalk_delay_ms→ CTM-off chain, driven byprofile.interact(stylewalk_delay_ms). One user keypress, four keystrokes dispatched to every captured slot. Styles:
standard(default): chain runs, CTM ends off.auto: chain runs, CTM stays on (toggle viactm_offlater).hold: press fires CTM-on + Alt+J; putbind: ctm_offinrelease_stepsto fire it on hotkey release.
- The example
lootmap (Alt+G) andinteractmap (Alt+I) now use the shortcut. Aloot_manualmap (Ctrl+Alt+G) exercises the explicit chain for users who want per-step control. - New tests:
interact_smart_shortcut_standard_emits_full_sequence,interact_smart_shortcut_auto_emits_two_no_tail,interact_smart_shortcut_hold_emits_press_only. 92/92 unit tests pass; clippy clean. - Docs:
docs/MACROS.md"Smart interact shortcut" section,docs/NOTES.mdcallout,examples/profile.yamlupdated with comments.
Note: After this change,
bind: "interact"is a single Alt+J send (game_binds.interact). The full chain trigger is nowbind: "smart_interact". Examples and tests updated.
-
Security: IPC runtime dir is now
chmod 0o700and the Unix socket ischmod 0o600immediately afterUnixListener::bind. Any local user with read access could speak our IPC protocol (Command::Typeetc.); this is the cheapest defense. Helpers:profile::chmod_runtime_dir()andprofile::chmod_socket(path). -
GUI: New-team wizard now pads
profile.characterstoslotsbefore stampinglutris_game. A wizard with 5 members and an empty character list previously saved a team with zero Launch rows; it now fills the rows withCharacter::default()and applies the Lutris game to each. -
GUI:
arm_auto_applynow waits for a client matchingprofile.window_match.class/.titleregexes before firinglayout-apply, instead of firing on the first non-empty client list. With no patterns configured it still requires a non-empty class on the matched client, so existing profiles behave the same. This preventslayout-applyagainst the desktop when only a terminal (or any unrelated window) is open. -
Profile:
CharacterderivesDefault(needed for the padding).