From a40cc4a905e5f1d234e71bb8bdea0112a5dfdea5 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 27 Aug 2026 15:13:58 +0700 Subject: [PATCH] the hover tax is pinned and cut, and a spell-less macro is a button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - a tooltip change costs ~1.3 ms — five whole-interface recomputes, each working as designed: the quad re-convert at 474 µs, the Lua tick at 287, the layout resolve at 200, bevy's `Assets` tax at ~270 and the mesh rebuild at 146 — pinned with new hover probes (a jitter dial, a `WOW_PROBE_HOVER_DUTY` duty cycle so run drift cancels, an `AssetChanged` tax meter), and the layout preamble's two whole-roster scans become lists maintained at the writer (52–83 µs → 1–11) - the splice compared this frame's entries against last frame's by index, so one inserted highlight shifted the 160 entries behind it and read as "everything changed"; it now aligns on `z` — an identity, not a position — and a `Text` entry that writes only quads became spliceable, so a tooltip change re-converts 22 entries instead of 520 (`convert` +439 µs → +107), with `WOW_UI_SPLICE_VERIFY` running the full conversion behind every spliced frame: 0 mismatches over 1,078 - a spell-less macro is a usable action button, not the 0.4 grey — the reference's usable compute has a dedicated leg answering usable for the bound-spell zero, cross-checked at the bytes in the reference's disassembly — and the button's Name line is written unconditionally from `GetActionText` as the reference does, so the macro's name sits under its icon and a `/cast` of a spell the character does not know now greys, which is also 1.12's behaviour (B340) - a capture bounds its run in wall-clock seconds, because a frame cap is no cap at the ~1 fps a starved `nextDrawable` leaves — 1800 frames is thirty minutes there — and the teardown backstop runs on every run as a liveness guarantee, carrying the exit code the run asked for; the Multisampling row reads Off / 2x / 4x, since "1x" contradicts the no-multisampling byte both of the reference's enumerators normalise to and the bit-depth prefix was identical on every row Co-Authored-By: Claude Fable 5 --- crates/benilla-app/assets/ui/ActionBar.xml | 22 +- crates/benilla-app/assets/ui/OptionsFrame.xml | 37 +- crates/benilla-app/src/capture/mod.rs | 188 +++-- crates/benilla-app/src/capture/probes/act.rs | 83 +- crates/benilla-app/src/hover_log.rs | 17 +- crates/benilla-app/src/perf/census.rs | 37 + crates/benilla-app/src/perf/mod.rs | 10 + crates/benilla-app/src/perf/stall.rs | 64 +- crates/benilla-app/src/ui_action/feed.rs | 15 +- .../benilla-app/src/ui_action/feed_tests.rs | 41 + crates/benilla-app/src/ui_action/state.rs | 160 +++- crates/benilla-app/src/ui_macro/mod.rs | 32 +- crates/benilla-app/src/ui_macro/run.rs | 136 +++- crates/benilla-app/src/ui_pass.rs | 4 +- .../src/ui_script/action_bar_tests.rs | 70 ++ .../benilla-app/src/ui_script/extract/mod.rs | 722 +++++++++++++++--- crates/benilla-app/src/ui_script/mod.rs | 36 + .../src/ui_script/options_tests.rs | 11 +- crates/benilla-ui/src/script/layout.rs | 10 +- crates/benilla-ui/src/script/model.rs | 8 + .../src/script/object/events_regions.rs | 18 +- .../src/script/tests/size_changed.rs | 51 ++ crates/benilla-ui/src/script/tooltip/mod.rs | 25 +- crates/benilla-ui/src/script/tooltip_unit.rs | 16 +- crates/benilla-ui/src/widget/mod.rs | 17 + crates/benilla-ui/src/widget/tests.rs | 26 + 26 files changed, 1599 insertions(+), 257 deletions(-) diff --git a/crates/benilla-app/assets/ui/ActionBar.xml b/crates/benilla-app/assets/ui/ActionBar.xml index 995e30aa..e906ee57 100644 --- a/crates/benilla-app/assets/ui/ActionBar.xml +++ b/crates/benilla-app/assets/ui/ActionBar.xml @@ -443,6 +443,7 @@ button.flash = getglobal(n .. "Flash") button.border = getglobal(n .. "Border") button.cooldown = getglobal(n .. "Cooldown") + button.name = getglobal(n .. "Name") button.flashing = button.flashing or 0 button.flashtime = button.flashtime or 0 -- The grid count, same posture: a foreign button reaching ActionButton_HideGrid with @@ -521,6 +522,7 @@ button.flash = getglobal(button:GetName() .. "Flash") button.border = getglobal(button:GetName() .. "Border") button.cooldown = getglobal(button:GetName() .. "Cooldown") + button.name = getglobal(button:GetName() .. "Name") -- Ref ActionButton_OnLoad:104-106: the flash/range state the OnUpdate loop drives. button.flashing = 0 button.flashtime = 0 @@ -944,6 +946,15 @@ else button.border:Hide() end + -- Ref ActionButton_Update:236-238, "Update Macro Text": the Name line under the icon, + -- written on EVERY update, occupied or not — `GetActionText` answers a MACRO slot's + -- macro name and nil for anything else, and a nil clears the line, so an emptied or + -- re-filled slot loses the old name through this same write. Guarded only because an + -- adopted foreign button may inherit a template that declares no `$parentName`. + -- (B340: the line was declared in the template and never set — decision 1636.) + if button.name then + button.name:SetText(GetActionText(action)) + end end function BenillaActionBar_OnLoad(frame) @@ -1610,7 +1621,9 @@ widget playing the same machine); NormalTexture = the 66x66 UI-Quickslot2 ring centered at (0,-1) (l.74-85); PushedTexture UI-Quickslot-Depress (l.86); HighlightTexture ButtonHilight-Square ADD (l.87); CheckedTexture CheckButtonHilight ADD (l.88 — the - IsCurrentAction/IsAutoRepeatAction ring). Only Name (macros) stays OUT. + IsCurrentAction/IsAutoRepeatAction ring); Name (the macro-name line, l.34-46) on ARTWORK, + set from `GetActionText` at the tail of every update as the ref's `ActionButton_Update` + does (decision 1636). --> + button's bottom edge. `BenillaActionButton_Update` writes it from + `GetActionText` on every update (a MACRO slot's macro name, nil — cleared — + for any other kind); it is also part of the template's published contract, so + an addon indexing `