fix(compat): guard retail-only InterfaceOptions globals and Settings.* API

AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua: the Constructor
parented its frame to the global InterfaceOptionsFramePanelContainer, which
is nil at AceGUI widget-construction time on the CoA reworked FrameXML.
Guard with 'local _parent = InterfaceOptionsFramePanelContainer or UIParent'
and pass _parent to CreateFrame so addons that register a Blizzard Interface
Options panel don't error out during load.

AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua: :AddToBlizOptions
used the Dragonflight+ Settings.* API (GetCategory, RegisterCanvasLayoutCategory,
RegisterCanvasLayoutSubcategory, RegisterAddOnCategory). The Settings table
doesn't exist on the 3.3.5-based CoA client, so every AceConfig-driven options
panel errored the moment it was registered. Wrap the whole Settings.* block in
'if Settings and Settings.GetCategory then ... else ... end' and fall back to
the WotLK-era InterfaceOptions_AddCategory(group.frame) after stamping the
category name via group:SetName(name or appName, parent).

Both retail and CoA paths now work; behaviour on retail is unchanged. luac -p
passes on both files. README CoA-compat patches table updated (entries 2 and 3).

This bundle is the source-of-truth for the Exiles/coa-* forks; the propagation
to bartender / quartz / shadowedunitframes / ai-voiceover / etc. bundled Ace
copies is handled separately.
This commit is contained in:
2026-05-24 17:38:30 +02:00
parent d422ad36b8
commit 3ec2009f54
3 changed files with 37 additions and 22 deletions
@@ -2014,28 +2014,37 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
group:SetCallback("OnHide", ClearBlizPanel) group:SetCallback("OnHide", ClearBlizPanel)
local categoryName = name or appName local categoryName = name or appName
if parent then -- CoA-compat: the Settings.* API (GetCategory / RegisterCanvasLayoutCategory /
local parentID = BlizOptionsIDMap[parent] or parent -- RegisterCanvasLayoutSubcategory / RegisterAddOnCategory) is a retail-only
local category = Settings.GetCategory(parentID) -- (Dragonflight+) replacement for the WotLK-era InterfaceOptions_AddCategory.
if not category then -- On the 3.3.5-based CoA client Settings is nil, so fall back to the legacy API.
error(("The parent category '%s' was not found"):format(parent), 2) if Settings and Settings.GetCategory then
end if parent then
local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName) local parentID = BlizOptionsIDMap[parent] or parent
group:SetName(subcategory.ID, parentID) local category = Settings.GetCategory(parentID)
else if not category then
if BlizOptionsIDMap[categoryName] then error(("The parent category '%s' was not found"):format(parent), 2)
error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2) end
end local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName)
group:SetName(subcategory.ID, parentID)
else
if BlizOptionsIDMap[categoryName] then
error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2)
end
local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName) local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName)
if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then
-- override the ID so the name can be used in Settings.OpenToCategory -- override the ID so the name can be used in Settings.OpenToCategory
-- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible -- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible
category.ID = categoryName category.ID = categoryName
end
group:SetName(category.ID)
BlizOptionsIDMap[categoryName] = category.ID
Settings.RegisterAddOnCategory(category)
end end
group:SetName(category.ID) else
BlizOptionsIDMap[categoryName] = category.ID group:SetName(name or appName, parent)
Settings.RegisterAddOnCategory(category) InterfaceOptions_AddCategory(group.frame)
end end
return group.frame, group.frame.name return group.frame, group.frame.name
@@ -99,7 +99,11 @@ local methods = {
Constructor Constructor
-------------------------------------------------------------------------------]] -------------------------------------------------------------------------------]]
local function Constructor() local function Constructor()
local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer) -- CoA-compat: InterfaceOptionsFramePanelContainer is a global from the stock 3.3.5
-- Interface Options frame; on the CoA reworked FrameXML it can be nil at the time
-- AceGUI widgets are constructed. Fall back to UIParent so CreateFrame doesn't blow up.
local _parent = InterfaceOptionsFramePanelContainer or UIParent
local frame = CreateFrame("Frame", nil, _parent)
frame:Hide() frame:Hide()
-- support functions for the Blizzard Interface Options -- support functions for the Blizzard Interface Options
+3 -1
View File
@@ -4,7 +4,7 @@ Canonical [Ace3](https://www.wowace.com/projects/ace3) bundle for the CoA Guild
Lifted from upstream [WoWUIDev/Ace3](https://github.com/WoWUIDev/Ace3) at commit Lifted from upstream [WoWUIDev/Ace3](https://github.com/WoWUIDev/Ace3) at commit
[`52e5f2c`](https://github.com/WoWUIDev/Ace3/commit/52e5f2c7101b6edb02b48ea232bdda2df09d2960) [`52e5f2c`](https://github.com/WoWUIDev/Ace3/commit/52e5f2c7101b6edb02b48ea232bdda2df09d2960)
(2026-05-17), with a single CoA-compat patch on top (see below). Every fork in the `Exiles` (2026-05-17), with a small stack of CoA-compat patches on top (see below). Every fork in the `Exiles`
org should converge on this bundle so the runtime LibStub resolution is predictable and addons org should converge on this bundle so the runtime LibStub resolution is predictable and addons
can't quietly regress when one of them is disabled. can't quietly regress when one of them is disabled.
@@ -13,6 +13,8 @@ can't quietly regress when one of them is disabled.
| # | Issue | Fix | | # | Issue | Fix |
|---|-------|-----| |---|-------|-----|
| 1 | Upstream Ace3 calls `Texture:Set*Texture(<FileDataID>)` with numeric FileDataIDs in 42 places across `AceGUI-3.0/widgets/*` and `AceConfigDialog-3.0`. FileDataIDs are a retail-only API (post WoD/Legion). On the WoW 3.3.5-based CoA client, `SetTexture` only accepts string paths — passing a number silently fails and the engine renders a red placeholder. Symptom: solid-red squares where color swatches / checkboxes / window chrome should be. | Each FDID call was substituted with the string path that already lived in the trailing comment, e.g. `colorSwatch:SetTexture(130939)``colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")`. | | 1 | Upstream Ace3 calls `Texture:Set*Texture(<FileDataID>)` with numeric FileDataIDs in 42 places across `AceGUI-3.0/widgets/*` and `AceConfigDialog-3.0`. FileDataIDs are a retail-only API (post WoD/Legion). On the WoW 3.3.5-based CoA client, `SetTexture` only accepts string paths — passing a number silently fails and the engine renders a red placeholder. Symptom: solid-red squares where color swatches / checkboxes / window chrome should be. | Each FDID call was substituted with the string path that already lived in the trailing comment, e.g. `colorSwatch:SetTexture(130939)``colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")`. |
| 2 | `AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua` Constructor parents its frame to the global `InterfaceOptionsFramePanelContainer`. On the CoA reworked FrameXML that global is nil at AceGUI widget-construction time, and `CreateFrame("Frame", nil, nil)` is fine, but downstream code that calls `:SetPoint` against the parent / `:Show` it via the options tree relies on a real parent. Symptom: every addon that registers a Blizzard Interface Options panel via AceConfigDialog errors during load. | Guard at line 102: `local _parent = InterfaceOptionsFramePanelContainer or UIParent` and pass `_parent` to `CreateFrame`. Widget behaviour is unchanged on retail; on CoA the panel parents to `UIParent` so the rest of the widget works. |
| 3 | `AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua` `:AddToBlizOptions` uses the Dragonflight+ `Settings.*` API (`Settings.GetCategory`, `Settings.RegisterCanvasLayoutCategory`, `Settings.RegisterCanvasLayoutSubcategory`, `Settings.RegisterAddOnCategory`). The `Settings` table doesn't exist on the 3.3.5-based CoA client, so every AceConfig-driven options panel errors out the moment it's registered. | Wrap the whole `Settings.*` block in `if Settings and Settings.GetCategory then … else … end`. The `else` branch falls back to the WotLK-era `InterfaceOptions_AddCategory(group.frame)` after stamping the category name via `group:SetName(name or appName, parent)`. |
## Versions ## Versions