diff --git a/crates/benilla-app/assets/ui/MapCanvas.lua b/crates/benilla-app/assets/ui/MapCanvas.lua index 24dc0795..75566eca 100644 --- a/crates/benilla-app/assets/ui/MapCanvas.lua +++ b/crates/benilla-app/assets/ui/MapCanvas.lua @@ -737,19 +737,32 @@ local DETAIL_TILE, DETAIL_TILES = 256, 12 -- Base geometry per overlay texture, as `WorldMapFrame_Update` wrote it: [texture] = {x,y,w,h}. local overlayBase = {} --- `w`,`h` are the size the detail frame is ABOUT to have, passed by the caller that just set it. --- Reading the frame instead would answer the old size: the detail frame is `SetAllPoints` to the --- canvas, so its own size is derived, and a derived size does not resolve until the layout pass --- — measured, a child answered `0x0` immediately after its parent was resized. Without them the --- frame's current size is read, which is right for a caller that is not resizing it (the overlay --- capture after a repaint). +-- Scale the stock map art to whatever size the detail frame currently has. `w`,`h` are a +-- fallback only, for the one caller that has just set a size the layout cannot answer yet. local function ScaleDetailArt(w, h) local d = WorldMapDetailFrame if not d then return end - w = w or d:GetWidth() - h = h or d:GetHeight() + -- The detail frame's OWN size is the authority, because the tiles are its children and it is + -- not always the canvas's shape: 1.12's windowed mode re-anchors AND rescales it out from + -- under the canvas (`WorldMapFrame_Minimize` sets `WORLDMAP_WINDOWED_SCALE` on it and insets + -- it to TOPLEFT 15,-33), so the canvas's own size stops describing the frame the art lives + -- in. Measured in grom's session: `detail 1431x954 scale 0.56` inside `WorldMapCanvas + -- 1002x668 scale 0.80` — the same screen area, a different number of units. + -- + -- Scaled by the canvas's number instead, every tile came out 1.43x too small: the art + -- covered 1024x768 of a 1431x954 frame and the rest was bare parchment. His own art trace + -- caught both states 1.4 s apart, tiles 366 then 256, with the detail frame unchanged. + -- + -- `GetLeft` first: the size is derived, and without forcing the layout to settle a read taken + -- straight after a resize answers the size from before it. The caller's `w`,`h` remain the + -- fallback for the one case that cannot be measured at all. + d:GetLeft() + local dw, dh = d:GetWidth(), d:GetHeight() + if dw and dh and dw > 0 and dh > 0 then + w, h = dw, dh + end if not w or not h or w <= 0 or h <= 0 then return end diff --git a/crates/benilla-app/src/local_state.rs b/crates/benilla-app/src/local_state.rs index dbf4b07d..e7cd6d70 100644 --- a/crates/benilla-app/src/local_state.rs +++ b/crates/benilla-app/src/local_state.rs @@ -116,7 +116,11 @@ pub(crate) fn saved_variables_path() -> Option { /// of its UI shutdown (`0x490bd0`). An addon absent from the file is enabled. pub(crate) fn addons_state_path(realm: &str, character: &str) -> Option { let key = format!("{}-{}", file_token(realm), file_token(character)); - home().map(|h| h.join("addons").join(format!("{key}.txt"))) + // Through `saved_home`, so `$WOW_CAPTURE_SAVED` reproduces which addons the player has turned + // OFF as well as how the rest are configured. Without it a capture of their interface loads + // every addon in the folder, which is a different interface again — and the difference is + // exactly what a "I turned it off and it is still wrong" report turns on. + saved_home().map(|h| h.join("addons").join(format!("{key}.txt"))) } /// [`home`] for the saved-variable readers, opened back up for a capture by diff --git a/docs/ADDON_COMPAT.md b/docs/ADDON_COMPAT.md index 7a627946..b94f41d3 100644 --- a/docs/ADDON_COMPAT.md +++ b/docs/ADDON_COMPAT.md @@ -2484,3 +2484,57 @@ The four info panels moved onto the same page at the same time, the bottom-right (`pfUI.panel.right`, over the right chat frame) included. Those have had a fixed two-second autohide on pfUI's Panel page for years; the Auto Fade page drives the same frames on the user's own timeout, and hands one back rather than switching it off when the Panel page still wants it. + +## The map art was scaled by the canvas while living in the detail frame + +"Textures are not where they should be", and still wrong with the map addon switched off — which +is what made it ours. His own session log had both states, 1.4 seconds apart, same map, same frame: + +``` +251.4s detail 1431x954 tiles 366x366 at 387, 752, 1118, 1484 (1431/1002 = 1.428, correct) +252.8s detail 1431x954 tiles 256x256 at 387, 643, 899, 1155 (the XML's raw size) +``` + +The stock art is twelve 256x256 tiles laid 4x3 in a `WorldMapDetailFrame` the realm's XML declares +as 1002x668 — they overflow it by 22x100 on purpose, and that is faithful. `MapCanvas.lua`'s +`ScaleDetailArt` rescales them whenever the frame is not that size. + +It was being told the **canvas's** size, by the one caller that knew a size at all +(`OnCanvasSizeChanged`), on the assumption that the detail frame is `SetAllPoints` to the canvas. +1.12's own windowed mode breaks that assumption: `WorldMapFrame_Minimize` sets +`WORLDMAP_WINDOWED_SCALE` (0.7) on `WorldMapDetailFrame` and on `WorldMapButton`, and insets the +frame to `TOPLEFT 15,-33`. The same screen area is then a different number of units in each — +grom's trace reads `detail 1431x954 scale 0.56` inside `WorldMapCanvas 1002x668 scale 0.80`. + +Scaled by the canvas's number, every tile came out 1.43x too small: the art covered 1024x768 of a +1431x954 frame and the rest showed bare parchment, with the exploration overlays scaled to match +and landing nowhere near their terrain. + +**The detail frame's own size is the authority** — the tiles are its children — so that is what is +read now, with `GetLeft()` first to settle the layout, because the size is derived and an unforced +read answers the size from before the last change. The caller's `w`,`h` stay as the fallback for +the case that cannot be measured at all. + +Reproduced and controlled in the harness, with the windowed scale applied as the stock code +applies it: + +``` +fix: detail 1416x921 scale 0.49 | canvas 1002 scale 0.70 | tile 362, should be 362 -> OK +control: detail 1416x921 scale 0.49 | canvas 1002 scale 0.70 | tile 256, should be 362 -> WRONG +``` + +The control's 256 is the number his log recorded. + +**A dead end worth recording**, because it looked right twice: the first fix cached the last size +the canvas passed and preferred it over reading the frame. That is backwards — the cached canvas +size is the wrong quantity, not a stale copy of the right one. The second tried converting canvas +units to detail units by the effective-scale ratio; it came out 366 against a true 362, because +`Minimize` also insets the frame, so the two are not related by scale alone. Only the frame's own +measured size is right. + +## A capture now honours which addons the player turned OFF + +`$WOW_CAPTURE_SAVED` reaches the enable-state file as well as the saved variables, so a capture +reproduces the addon set the player actually has. The report that needed it was "I turned the map +addon off to test and it is still wrong" — without it a capture loads every addon in the folder, +which cannot answer that at all.