diff --git a/Bartender4/CoAAuraConditionals.lua b/Bartender4/CoAAuraConditionals.lua index 646fc60..a6fec89 100644 --- a/Bartender4/CoAAuraConditionals.lua +++ b/Bartender4/CoAAuraConditionals.lua @@ -91,11 +91,31 @@ end -- spec respec, etc.) so freshly-resolvable names take effect without -- a /reload. Skipped during combat lockdown — RegisterStateDriver is -- secure and the SetAttribute calls inside UpdateStates would taint. +-- +-- Triggers: UPDATE_SHAPESHIFT_FORMS (the form set actually changed) +-- and PLAYER_REGEN_ENABLED (drain a refresh queued during combat). +-- PLAYER_ENTERING_WORLD is deliberately NOT a trigger — Bartender's +-- own init handles the initial state, and firing UpdateStates on every +-- zone risked re-entering secure paths while Bartender was mid-flux, +-- producing "prevented the call of SecureStateDriverManager:SetAttribute". local refresh = CreateFrame("Frame") refresh:RegisterEvent("UPDATE_SHAPESHIFT_FORMS") -refresh:RegisterEvent("PLAYER_ENTERING_WORLD") refresh:RegisterEvent("PLAYER_REGEN_ENABLED") + +local lastFormSignature local pendingRefresh = false + +local function currentFormSignature() + if type(GetNumShapeshiftForms) ~= "function" then return "" end + local n = GetNumShapeshiftForms() or 0 + local parts = {} + for i = 1, n do + local _, fname = GetShapeshiftFormInfo(i) + parts[#parts + 1] = fname or "" + end + return table.concat(parts, "|") +end + refresh:SetScript("OnEvent", function(self, event) if InCombatLockdown and InCombatLockdown() then pendingRefresh = true @@ -103,6 +123,14 @@ refresh:SetScript("OnEvent", function(self, event) end if event == "PLAYER_REGEN_ENABLED" and not pendingRefresh then return end pendingRefresh = false + + -- Skip the refresh entirely if the form set hasn't changed since + -- last run. Avoids redundant RegisterStateDriver churn on routine + -- UPDATE_SHAPESHIFT_FORMS spam. + local sig = currentFormSignature() + if sig == lastFormSignature then return end + lastFormSignature = sig + local mod = Bartender4 and Bartender4.GetModule and Bartender4:GetModule("ActionBars", true) if not mod or not mod.actionbars then return end for _, bar in pairs(mod.actionbars) do