map: the art was scaled by the canvas while living in the detail frame
Grom's report was "textures are not where they should be", and still wrong with OpenMapClassic switched off — which is what made it ours rather than the addon's. His own session log had both states 1.4 s apart, same map, same frame: detail 1431x954 with tiles 366x366 (correct, 1431/1002 = 1.428), then the same frame with tiles back at the XML's raw 256x256. `ScaleDetailArt` was being handed the CANVAS's size by `OnCanvasSizeChanged`, on the assumption that the detail frame is `SetAllPoints` to the canvas. 1.12's own windowed mode breaks that: `WorldMapFrame_Minimize` puts `WORLDMAP_WINDOWED_SCALE` (0.7) on `WorldMapDetailFrame` and `WorldMapButton` and insets the frame to TOPLEFT 15,-33, so the same screen area is a different number of units in each — his 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, the rest bare parchment, and the exploration overlays scaled to match landed nowhere near their terrain. The detail frame's own size is the authority, since the tiles are its children. `GetLeft()` first to settle the layout, because that 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 what cannot be measured. Reproduced and controlled in the harness with the windowed scale applied as the stock code applies it: tile 362 where 362 is wanted, against the control's 256 — the number his log recorded. Two earlier attempts are written up in docs/ADDON_COMPAT.md as dead ends, because both looked right: caching the canvas size prefers the wrong quantity, and converting it by the effective-scale ratio gives 366 against a true 362, since Minimize also insets the frame. `$WOW_CAPTURE_SAVED` now reaches the enable-state file too, so a capture reproduces which addons the player has turned off — without which "I turned it off and it is still wrong" cannot be answered offline at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -116,7 +116,11 @@ pub(crate) fn saved_variables_path() -> Option<PathBuf> {
|
||||
/// of its UI shutdown (`0x490bd0`). An addon absent from the file is enabled.
|
||||
pub(crate) fn addons_state_path(realm: &str, character: &str) -> Option<PathBuf> {
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user