From 963ad21297fee043f821969d73210dbd64d8a3bf Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Mon, 22 Jun 2026 00:35:19 -0500 Subject: [PATCH] Show resolved icon for question-mark macros in the macro list Macros with no chosen icon (e.g. "#showtooltip Shoot") display Blizzard's default question mark in the macro UI. After each MacroFrame_Update, swap that placeholder for the icon the action bar would show, resolved from the macro's #showtooltip/first action via GetMacroByIndex. - Only replaces icons that are currently the question mark, so user-chosen icons are never touched. - Covers both the list buttons (MacroButtonNIcon) and the selected-macro detail icon. - Purely cosmetic: never changes the saved icon; Blizzard repaints the default on the next refresh if resolution fails or the macro changes. - Installed in MacroErrorUI's existing hook path (gated on Blizzard_MacroUI load and the SuperMacro guard). --- Extensions/MacroErrorUI.lua | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Extensions/MacroErrorUI.lua b/Extensions/MacroErrorUI.lua index e030a08..a98851a 100644 --- a/Extensions/MacroErrorUI.lua +++ b/Extensions/MacroErrorUI.lua @@ -1274,6 +1274,56 @@ end -- Hook Installation -- ============================================================================ +-- ============================================================================ +-- Dynamic macro-list icons +-- Blizzard shows the default question-mark icon for macros with no chosen icon +-- (e.g. "#showtooltip Shoot"). Replace it with the icon the action bar would +-- show -- resolved from the macro's #showtooltip/first action -- but ONLY when +-- the saved icon is the question mark, so user-chosen icons are never touched. +-- Purely cosmetic: Blizzard repaints from GetMacroInfo on the next update, so +-- if resolution fails or the macro changes, the default simply returns. +-- ============================================================================ + +local QUESTION_MARK = string.lower(CleveRoids.unknownTexture or "Interface\\Icons\\INV_Misc_QuestionMark") + +local function IsQuestionMark(iconTexture) + local tex = iconTexture and iconTexture:GetTexture() + return type(tex) == "string" and string.lower(tex) == QUESTION_MARK +end + +-- Resolved tooltip texture for a Blizzard macro index, or nil when it resolves +-- to nothing better than the question mark (no #showtooltip, unresolved spell). +local function ResolveMacroIcon(macroIndex) + if not macroIndex or macroIndex < 1 then return nil end + local ok, macro = pcall(CleveRoids.GetMacroByIndex, macroIndex) + if not ok or not macro or not macro.actions or not macro.actions.tooltip then return nil end + local tex = macro.actions.tooltip.texture + if type(tex) == "string" and string.lower(tex) ~= QUESTION_MARK then + return tex + end + return nil +end + +local function FixMacroListIcons() + if not MacroFrame or not MacroFrame:IsVisible() then return end + + local base = MacroFrame.macroBase or 0 + for i = 1, (MAX_MACROS or 18) do + local icon = getglobal("MacroButton" .. i .. "Icon") + if icon and IsQuestionMark(icon) then + local tex = ResolveMacroIcon(base + i) + if tex then icon:SetTexture(tex) end + end + end + + -- Large icon for the currently-selected macro (details pane). + if MacroFrame.selectedMacro and MacroFrameSelectedMacroButtonIcon + and IsQuestionMark(MacroFrameSelectedMacroButtonIcon) then + local tex = ResolveMacroIcon(MacroFrame.selectedMacro) + if tex then MacroFrameSelectedMacroButtonIcon:SetTexture(tex) end + end +end + local function InstallHooks() if hooked then return end if not MacroFrameText or not MacroFrame then return end @@ -1325,6 +1375,15 @@ local function InstallHooks() end end) + -- After every Blizzard macro-list refresh, swap question-mark icons for the + -- dynamically-resolved ones. Post-hook so Blizzard has already set the + -- default texture we test against. + if hooksecurefunc and type(MacroFrame_Update) == "function" then + hooksecurefunc("MacroFrame_Update", function() + pcall(FixMacroListIcons) + end) + end + hooked = true end