diff --git a/docs/ADDON_COMPAT.md b/docs/ADDON_COMPAT.md index adb12f13..1c244818 100644 --- a/docs/ADDON_COMPAT.md +++ b/docs/ADDON_COMPAT.md @@ -2190,32 +2190,73 @@ settings — the window size and max zoom that his map is actually stuck at — because loading saved variables would also mean writing them back at exit, over a real player's file. Both are why this instrument narrows the question rather than closing it. -## Open: the map's Continent and Zone pickers are blank on the first open — with the addons loaded +## The map's Continent and Zone pickers were blank on the first open of a session Found in grom's recording rather than reported: over Dun Morogh both dropdowns carry no text and Zoom Out is dead; later in the same clip, over Elwynn, both read correctly. Reproduced offline: ``` addon_harness … --probe OpenMapClassic --eval 'ToggleWorldMap()' --tick … - after open1: [nil] - after open2: [Eastern Kingdoms] zone=[Alah'Thalas] + before open: zoneDD registered=nil + right after open: zoneDD registered=1 + after open1: continent=[nil] + after open2: continent=[Eastern Kingdoms] zone=[Alah'Thalas] ``` -Blank on the first open, correct from the second, and a `WORLD_MAP_UPDATE` fired by hand after the -first open fills both — so the mechanism is clear: the realm's `WorldMapFrame.xml` fills them from -exactly one place, the Zone dropdown's `` on `WORLD_MAP_UPDATE` (:321), and that dropdown -registers the event in its own `` (:318 — the realm commented the `OnLoad` out and moved it -there) while `WorldMapFrame`'s `` fires the event through `SetMapToCurrentZone()` (:711). A -parent's OnShow runs before its children's, so the event arrives one step early. +The realm's `WorldMapFrame.xml` fills them from exactly one place: the Zone dropdown's `` +on `WORLD_MAP_UPDATE` (:321), which re-runs both pickers' initialisers and then +`WorldMap_UpdateContinentDropDownText`/`...ZoneDropDownText`. That dropdown registers the event in +its own `` (:318 — the realm commented the `OnLoad` out and moved it there), while +`WorldMapFrame`'s `` fires it through `SetMapToCurrentZone()` (:711). **A parent's OnShow +runs before its children's**, so a purely inline event is dispatched into a gap where its only +listener does not exist yet — which the `IsEventRegistered` pair above measures directly. -**What is not established is that this is ours.** The same open on the whole shipped interface with -*no* addons fills both pickers on the first try — measured, as a test that passed with and without -a candidate fix, which is what sent that fix back. So something in OpenMapClassic or one of its -dependencies changes the order, and the engine-side change that looked obvious (queueing a second -`WORLD_MAP_UPDATE` behind the inline one) buys nothing measurable and costs a second -`WorldMapFrame_Update` per call — the cost `ui_script/lifecycle.rs:107` already warns about. It is -not in the tree. +`SetMapToCurrentZone` now queues a second `WORLD_MAP_UPDATE` on the deferred lane as well as firing +the inline one. The inline fire stays: it is what repaints the detail tiles inside the OnShow rather +than a frame later (the world-map flash). Only this verb doubles up, and only this verb needs to — +`SetMapZoom` is a click on a map that is already open. -**Next step, written down so it is not re-derived:** bisect the probe — the stock interface alone -is clean, `--probe OpenMapClassic` is not, and that probe loads only that addon and its -dependencies. Whatever re-shows or re-parents those dropdowns is in that short list. +**The first attempt at this was thrown away, and why is the useful part.** It was pinned by a test +that opened the real map on the whole shipped interface and asserted the pickers filled — and that +test passed with *and* without the fix, because the stock interface's own ordering happens to be +fine and the symptom needs the addons. A test that cannot fail is not evidence. The pin that +replaced it asserts the engine half directly: a handler that registers *after* `SetMapToCurrentZone` +returns still receives the event. It answers 0 without the change and 1 with it. + +## pfUI and OpenMapClassic were both managing the map window + +pfUI's `modules/map.lua` is a window manager for the world map, not a skin: on +`PLAYER_ENTERING_WORLD` it makes `WorldMapFrame` movable, drags it, scales it on ctrl-wheel, fades +it on shift-wheel, re-points it to CENTER, sizes it to `WorldMapButton` plus chrome, and saves all +of it through its own `LoadMovable`/`SaveMovable`. OpenMapClassic does the same job with its own +title bar, grips and saved size. + +Both write to the same frame, and OpenMap wins without meaning to: its `Hold` post-hooks on +`SetSize`/`SetWidth`/`SetHeight`/`SetScale`/`SetPoint` call `Apply`, which puts its own saved size, +scale and place straight back. Measured on grom's install, with his saved variables: + +``` +before: frame 913x662 scale 1.00 (OpenMap's saved pair) +pfUI asks for: 1017x723 scale 0.70 +after: frame 1017x723 scale 0.70 (and the pickers fill on the first open) +``` + +So pfUI's map settings did nothing for a player running both, and the window ended up a size +neither addon chose — which is also why the pfUI control strip ("Switch to current zone", "Reveal +Unexplored Areas", both pfUI's) sat outside the window in the recording: it is anchored around a +frame pfUI never got to size. + +Fixed in the port, not the engine: OpenMap stands down from the window when pfUI's map module is +active, exactly as it already does for Move Any (`Map/Window.lua`'s `theirWindow`, which was +`moveAny`). The guard mirrors pfUI's own — it declines when Cartographer or MetaMap is loaded — so +the two agree about who is in charge rather than each deciding alone. pfUI moves, scales and +remembers the window; OpenMap keeps the art and the view; OpenMap's size slider greys out, the same +feedback Move Any already gives. + +**On whether to build this map into the client instead.** No: the addon's own art already draws +correctly here (see the capture above), and it is 13,118 lines of its own Lua, 2,257 lines of +generated data tables, 10,657 lines of bundled Ace3 and 67 MB of baked art across 211 files. A +native copy would buy no pixel this client does not already draw, would freeze at today's version, +and would break the integrations that exist *because* it is an addon — Questie and TomTom reach it +through `OpenMapAPI`. The work that pays is the other direction: every host-side gap it exposes, +like `GetCursorPosition`, is one that was breaking every other addon too.