Grok round-6 verification was No-Go. Fixes:
A. LayoutSlot.id was written as 0 by every constructor
(generate Stacked/Grid/main_strip, capture_from, the GUI pad
literals), so the find-by-id lookups in resize_slot / move_slot
never hit a tile and Free-mode Apply size/position always
failed with "no layout slot for slot id N". Constructors now
assign real 1-based ids (index+1, out.len()+1, i+2 for the
strip); capture_from uses the slot id from the window tuple.
layout::apply and reset_slot_lock now find the tile by id
instead of by Vec index.
B. The `slots` IPC formatter emitted "{id} 0x{address} ..." while
addresses already carry their own 0x prefix ("0xa"), producing
"1 0x0xa ..."; the parser split on whitespace so any multi-word
window title broke the field alignment. Both sides now use a
tab separator and the address passes through unchanged.
C. examples/profile.yaml still shipped the dropped schema
(window_match block + passthrough list). Replaced with a note
that matching is by process tree and every mapped hotkey is
intercepted.
D. CHANGELOG 0.1.0 still advertised passthrough (lines 19, 24)
and window_match (27, 78). Annotated as removed.
E. Lying comments: launcher.rs called the prefix "per-team" (it is
per-character); gui.rs::arm_auto_apply doc claimed it matched a
regex.
F. arm_auto_apply still hardcoded an empty spawned-pid set and
fell back to matching any client with a non-empty class -- the
round-4 Item-3 placeholder was what actually ran. It now takes
the real child pid and matches via pid_is_ancestor.
G. spawn_plan dropped the Child with no wait thread (zombie, same
bug round-6 fixed in launch_game). Now reaps in a background
thread.
H. page_session never refreshed the games list, so the dropdown
was empty on first paint. Added a games_loaded flag and a
one-shot refresh_games on first paint.
Plus: vfx env-var test race. toplevel_enabled_defaults_off_... and
capture_toplevel_is_gated_when_disabled both touch
ENBOXER_ENABLE_TOPLEVEL and cargo runs unit tests in parallel, so
the gated test intermittently saw the var set by its sibling (the
per-function `static` in session.rs does not serialise across
functions). Added a module-level ENV_LOCK in vfx::tests and
guarded both tests. Verified with three consecutive full runs.
Also: clippy unnecessary_cast in main_strip, and two rustdoc
warnings (raw <pid> and Arc<GbmDevice> read as HTML tags).
cargo test 103/103 (x3); clippy --all-targets -D warnings clean;
cargo doc --no-deps clean.
174 lines
4.7 KiB
YAML
174 lines
4.7 KiB
YAML
# Copy to ~/.config/enboxer/profile.yaml and edit.
|
|
# Keys use Mod+Key (Alt+G, Shift+F3). Letters are case-insensitive.
|
|
|
|
name: team
|
|
client: wow-retail
|
|
slots: 2
|
|
|
|
# Windows are matched by process tree (round-4 Item 3): the daemon
|
|
# spawns the game and matches the window whose pid is in that
|
|
# process tree. No class/title regex anymore.
|
|
|
|
# Every mapped hotkey is intercepted (round-4 Item 6 removed the
|
|
# `passthrough` skip-list).
|
|
|
|
# maps = only keys listed under `maps` (rest stay on the front window)
|
|
# mirror = clone keys to the other clients
|
|
# off = no intercept; the front window gets everything
|
|
mode_default: maps
|
|
|
|
# Optional: limit which keys mirror-mode clones. Empty = letters, digits, F-keys, etc.
|
|
repeater:
|
|
enabled: false
|
|
keys: []
|
|
|
|
game_binds:
|
|
# Interact with Target is a built-in WoW keybind (Key Bindings > Targeting >
|
|
# Interact Target). Bind it on every account to the same key; enBoxer just
|
|
# routes the keystroke. Alt+J was requested explicitly.
|
|
interact: "Alt+J"
|
|
# /console is not keybindable; CTM on / off must be macros.
|
|
ctm_on: "Shift+F3"
|
|
ctm_off: "Shift+F4"
|
|
# Per-character macro: the slot's character name is filled in by
|
|
# Character.assist_key / Character.follow_key, so swap-to-slot-N retargets
|
|
# the bind without re-editing YAML.
|
|
assist: "Shift+F2"
|
|
follow: "Shift+F1"
|
|
# Optional, class-dependent (Hunter / Warlock / DK / Demon Hunter).
|
|
# Built-in keybind Targets > Pet Actions > Attack.
|
|
# pet_attack: "F"
|
|
# Optional "try again" after a missed interact. Targets > Target Last Target.
|
|
# target_last: "Ctrl+L"
|
|
|
|
interact:
|
|
# standard: CTM on → IWT → wait → CTM off
|
|
# auto: CTM on → IWT (CTM stays on)
|
|
# hold: CTM on → IWT on press; CTM off on release
|
|
style: standard
|
|
walk_delay_ms: 2500
|
|
|
|
session_hotkeys:
|
|
mode_cycle: "Shift+Alt+M"
|
|
swap_next: "Ctrl+grave"
|
|
swap_prev: "Ctrl+Shift+grave"
|
|
focus_next: "Ctrl+Shift+N"
|
|
focus_prev: "Ctrl+Shift+P"
|
|
focus_main: "Ctrl+F1"
|
|
reset_all: "Ctrl+Shift+R"
|
|
stay_on_top: "Ctrl+Shift+T"
|
|
mouse_follow: "Ctrl+Shift+F"
|
|
mouse_broadcast: "Ctrl+Shift+B"
|
|
|
|
characters:
|
|
- slot: 1
|
|
name: Main
|
|
assist_key: "Shift+F2"
|
|
follow_key: "Shift+F1"
|
|
- slot: 2
|
|
name: Alt
|
|
assist_key: "F9"
|
|
follow_key: "F10"
|
|
|
|
groups:
|
|
alts:
|
|
slots: [2]
|
|
|
|
maps:
|
|
- name: bar_1
|
|
hotkey: "1"
|
|
steps:
|
|
- bind: assist
|
|
target: others
|
|
- key: "1"
|
|
target: all
|
|
|
|
- name: bar_2
|
|
hotkey: "2"
|
|
steps:
|
|
- bind: assist
|
|
target: others
|
|
- key: "2"
|
|
target: all
|
|
|
|
- name: follow_me
|
|
hotkey: "Alt+F"
|
|
steps:
|
|
- bind: follow
|
|
target: others
|
|
|
|
- name: assist_me
|
|
hotkey: "Alt+A"
|
|
steps:
|
|
- bind: assist
|
|
target: others
|
|
|
|
- name: loot
|
|
# ISBoxer Mapped Key analog: one user keypress fires the entire interact
|
|
# chain (CTM on -> Interact with Target -> wait walk_delay_ms -> CTM off),
|
|
# driven by profile.interact (style + walk_delay_ms). The follower has
|
|
# walk_delay_ms to actually walk to the target before CTM turns off.
|
|
hotkey: "Alt+G"
|
|
steps:
|
|
- bind: assist
|
|
target: others
|
|
- bind: smart_interact # full chain (use "interact" for a single Alt+J send)
|
|
target: others
|
|
- name: loot_manual
|
|
# Same idea as `loot` but composed by hand. Pick this form if you want to
|
|
# do anything fancy between the CTM toggle and the interact (e.g. a delay
|
|
# specific to a slow class, or a different key for each step).
|
|
hotkey: "Ctrl+Alt+G"
|
|
hold: false
|
|
steps:
|
|
- bind: assist
|
|
target: others
|
|
- bind: ctm_on
|
|
target: others
|
|
- bind: interact # single Alt+J send (NOT the smart shortcut)
|
|
target: others
|
|
- delay_ms: 5000
|
|
- bind: ctm_off
|
|
target: others
|
|
|
|
|
|
- name: interact_hold
|
|
hotkey: "Alt+H"
|
|
hold: true
|
|
steps:
|
|
- bind: ctm_on
|
|
target: others
|
|
- bind: interact # single Alt+J send (NOT the smart shortcut)
|
|
target: others
|
|
release_steps:
|
|
- bind: ctm_off
|
|
target: others
|
|
|
|
- name: rez_cycle
|
|
# Each press picks the next slot in order (1..=N, then wraps). State
|
|
# lives on the engine, keyed by this map name, so a second `rr`
|
|
# map keeps its own cursor.
|
|
hotkey: "Alt+R"
|
|
steps:
|
|
- key: "F8"
|
|
target: round_robin
|
|
|
|
# Window layout (pixels). Generate from the Layout page, then Save and Apply.
|
|
layout:
|
|
preset: main_strip
|
|
one_row: true
|
|
main_at_bottom: false
|
|
auto_apply: false
|
|
monitor: ""
|
|
slots: []
|
|
|
|
# Viewer sits on the current primary. Hover + pass_through sends keys/clicks to source_slot only.
|
|
video_fx:
|
|
- name: alt_party
|
|
enabled: false
|
|
source_slot: 2
|
|
source: { x: 0.0, y: 0.0, w: 0.40, h: 0.40 }
|
|
viewer: { x: 0.02, y: 0.02, w: 0.28, h: 0.28 }
|
|
pass_through: true
|
|
fps: 12
|