NTFS load order, a title-sorted AddOns list, and tooltips at the cursor

- addons load in the order NTFS lists a folder, case-insensitive with an underscore before the letters, the order the vanilla corpus was written against and the one that decides which addon provides a shared library (2178)
- GetNumAddOns and the index form of every AddOn verb walk a title-sorted list that hides the Blizzard addons the server says to hide, and the character-select AddOns list is in title order (2175)
- SetPoint and SetAllPoints raise the reference's own errors for a frame name that does not exist or an omitted relative frame instead of quietly anchoring to the parent, and an explicit nil means the screen root (2176)
- a tooltip owned with ANCHOR_CURSOR follows the mouse, which pfUI's tooltip, xpbar and chat modules, pfQuest's browser and TipBuddy ask for; an omitted or unknown anchor is ANCHOR_LEFT (2176)
- a $parent name handed to CreateFrame, CreateTexture or CreateFontString expands as it does in XML, so FonzAppraiser's thirty dropdowns and pfQuest's search icon get the names they asked for (2176)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-11 21:03:49 +07:00
co-authored by Claude Fable 5.1
parent 5af3a15d0e
commit eebbcc050f
53 changed files with 1978 additions and 541 deletions
@@ -664,7 +664,9 @@ fn a_hover_sweep_across_owners_costs_no_graph_derivation() {
/// do not use it. With `UberTooltips` at its shipped default of `"1"`, every action button routes
/// through `GameTooltip_SetDefaultAnchor` (stock `ActionButton_SetTooltip`, and the stance/pet/bonus bars the
/// same), which is `SetOwner(owner, "ANCHOR_NONE")` followed by an explicit `SetPoint` — a
/// completely different arm of the same verb, and the one that DROPS the tooltip's anchors.
/// completely different arm of the same verb, and the one that DROPS the tooltip's anchors
/// (`0x52fe90`'s mode-7 leg reaches `0x52fec2 call 0x767ed0` like every mode but PRESERVE — 2176
/// re-confirmed that at the bytes after 2142 predicted the opposite).
///
/// That drop took the conservative touch, so it re-derived the whole graph on every button the
/// cursor crossed — and on nothing else, which is why it survived two rounds of fixing and a
@@ -721,9 +723,10 @@ fn an_action_bar_hover_sweep_costs_no_graph_derivation() {
let derives = s.layout_derivations() - derives_before;
assert_eq!(
derives, 0,
"24 action-bar hovers derived the layout graph {derives} times. `SetOwner`'s ANCHOR_NONE \
arm drops the tooltip's anchors, which is a retarget to the EMPTY target set and names \
its node like any other (decision 1630, extending 1625)."
"24 action-bar hovers derived the layout graph {derives} times. The `ClearAllPoints()` on \
`GameTooltip_SetDefaultAnchor`'s next line is a retarget to the EMPTY target set and must \
name its node like any other (decision 1630, extending 1625; 2176 moved the emptying \
itself off `SetOwner`'s ANCHOR_NONE arm, which the reference leaves alone)."
);
}