action-bar hover stops re-deriving, and multisampling asks the GPU

- hovering the action bars re-derived the whole layout graph and hovering bags did not: `GameTooltip:SetOwner(owner, "ANCHOR_NONE")` dropped the tooltip's anchors through the conservative whole-graph derive, and with `UberTooltips` at its shipped default every action-bar button routes through that arm while a bag slot anchors `ANCHOR_RIGHT` and never does — the arm now retargets to the empty target set, and derive frames fall from 15.9 % of hovered frames to 0.2 %
- `gxMultisample` clamps to what the GPU actually offers: Apple GPUs stop at 4x, so a typed 8 was a wgpu validation panic on frame one — the clamp intersects the supported counts of every format the client multisamples into and steps the request down the way the reference's device-init retry loop does, with a warning that says so
- the Multisampling dropdown lands on the Graphics page with the device's own stops, built from the same enumeration that clamps a typed value on the reference's three bindings (`GetMultisampleFormats`, `GetCurrentMultisampleFormat`, `SetMultisampleFormat`) — a fixed Off/2x/4x/8x ladder would put a crash on the menu of every GPU that stops at 4
- capture hardening: a run whose `$WOW_WIN` the display clamped is refused in ~2 s instead of producing a wrong-sized shot to diff, a capture never reads the OS pointer (a cursor resting over the window arms a hover and a tooltip that a cursor an inch to the left does not), and the stall sampler writes into `benilla-config` instead of a hand-built `~/Library/Logs` path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-27 15:13:27 +07:00
co-authored by Claude Fable 5
parent 17a47acd71
commit bf7201f4d3
18 changed files with 820 additions and 33 deletions
+30
View File
@@ -78,6 +78,31 @@ pub(crate) struct PointerOverUi(pub(crate) bool);
#[derive(Resource, Default)]
pub(crate) struct SyntheticPointer(pub(crate) bool);
/// **A capture never reads the OS pointer** — set for the whole life of a `$WOW_CAPTURE` /
/// `$WOW_CAPTURE_UI` run, and never cleared.
///
/// [`input::feed_ui_input`] treats this exactly like [`SyntheticPointer`]: the mouse half of the
/// pass is skipped entirely, touching nothing. The keyboard half is untouched.
///
/// **Why it is not just `SyntheticPointer`.** They are different statements. That one means "a
/// probe is driving a gesture *right now*", and the drag probe clears it when its gesture ends
/// (`capture::probes::act`) — so borrowing it would re-expose the real cursor for the rest of the
/// run, which is the opposite of the guarantee wanted here.
///
/// **Why it exists at all.** The mouse feed reads `window.cursor_position()`, so a UI capture's
/// pixels depended on where the person at the keyboard had left their mouse: a cursor resting over
/// the window arms a hover and a tooltip that a cursor an inch to the left does not. The old
/// defence was an assumption written in a comment — *"probes park the cursor outside"* — with
/// nothing enforcing it. On 2026-08-26 a `ui-tooltip` A/B came back with an MAE of 5.275 against
/// 0.020 for every other UI scenario; that particular anomaly turned out to be a rebuilt-between-
/// legs mistake, and three attempts to reproduce a cursor-driven one all failed, because
/// `CGWarpMouseCursorPosition` does not synthesise the events winit needs. So the hazard was left
/// on the record as **suspected, unproven** — and this closes it by construction instead, which
/// costs nothing and does not require ever winning that argument. A capture that cannot read the
/// pointer cannot be perturbed by it.
#[derive(Resource, Default)]
pub(crate) struct CapturePointerPinned(pub(crate) bool);
/// The egui dev overlay's half of the pointer arbitration, written each egui pass by the debug
/// panel's `track_pointer_over_ui`. **Defined here, with the arbiter that reads it** (decision
/// 1174 finishing 0026): the type has to exist in a build with no dev overlays compiled in, and
@@ -297,6 +322,11 @@ impl Plugin for UiScriptPlugin {
.init_resource::<UiCostWanted>()
.init_resource::<PointerOverUi>()
.init_resource::<SyntheticPointer>()
// Not `init_resource`: the value IS the answer, read once from the env at build.
.insert_resource(CapturePointerPinned(
std::env::var_os("WOW_CAPTURE").is_some()
|| std::env::var_os("WOW_CAPTURE_UI").is_some(),
))
.init_resource::<EguiPointerOver>()
.init_resource::<InspectMode>()
.init_resource::<PlayerUiHover>()