From 0666b73b24f0a8182bcb59d8373768942654bdc0 Mon Sep 17 00:00:00 2001 From: 1dkfa <37644682+1dkfa@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:58:03 +0000 Subject: [PATCH] Fix bindings not working on raid frames (#5) This commit fixes an issue where using bindings on raid frames were not working at all. The root cause of the issue was that raid frames were not included, nor updated to the internal table of supported frames. Since raid frames, specifically the compact raid frames, are dynamic and added to the UI on-demand, active raid frames must be re-collected again every time there's a change in the group's or raid's roster (incl. pets). To implement this, I created a handler that collects active raid frames and maintains the addon's internal `self.ccframes` table by always keeping the default frames while refreshing the active raid frames and pruning the staled ones. The created handler reacts to messages returned by the following events: * `PLAYER_ENTERING_WORLD` * `RAID_ROSTER_UPDATE` * `PARTY_MEMBERS_CHANGED` * `UNIT_PET` * `CVAR_UPDATE` --- Clique/Clique.lua | 131 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/Clique/Clique.lua b/Clique/Clique.lua index e1b0002..3f9031d 100644 --- a/Clique/Clique.lua +++ b/Clique/Clique.lua @@ -1,7 +1,9 @@ --[[--------------------------------------------------------------------------------- Clique by Cladhaire -----------------------------------------------------------------------------------]] Clique = { - Locals = {} +----------------------------------------------------------------------------------]] + +Clique = { + Locals = {}, } assert(DongleStub, string.format("Clique requires DongleStub.")) @@ -32,6 +34,26 @@ function Clique:Enable() char = { switchSpec = false, downClick = false + }, + frames = { + PlayerFrame, + PetFrame, + PartyMemberFrame1, + PartyMemberFrame2, + PartyMemberFrame3, + PartyMemberFrame4, + PartyMemberFrame1PetFrame, + PartyMemberFrame2PetFrame, + PartyMemberFrame3PetFrame, + PartyMemberFrame4PetFrame, + TargetFrame, + TargetFrameToT, + FocusFrame, + FocusFrameToT, + Boss1TargetFrame, + Boss2TargetFrame, + Boss3TargetFrame, + Boss4TargetFrame, } } @@ -73,6 +95,12 @@ function Clique:Enable() self:RegisterEvent("ASCENSION_CA_SPECIALIZATION_ACTIVE_ID_CHANGED") self:RegisterEvent("ADDON_LOADED") + self:RegisterEvent("PLAYER_ENTERING_WORLD") + self:RegisterEvent("RAID_ROSTER_UPDATE") + self:RegisterEvent("PARTY_MEMBERS_CHANGED") + self:RegisterEvent("UNIT_PET") + self:RegisterEvent("CVAR_UPDATE") + -- Change to correct profile based on talent spec if self.db.char.switchSpec then self.silentProfile = true @@ -129,10 +157,7 @@ function Clique:Enable() end function Clique:EnableFrames() - local tbl = {PlayerFrame, PetFrame, PartyMemberFrame1, PartyMemberFrame2, PartyMemberFrame3, PartyMemberFrame4, - PartyMemberFrame1PetFrame, PartyMemberFrame2PetFrame, PartyMemberFrame3PetFrame, - PartyMemberFrame4PetFrame, TargetFrame, TargetFrameToT, FocusFrame, FocusFrameToT, Boss1TargetFrame, - Boss2TargetFrame, Boss3TargetFrame, Boss4TargetFrame} + local tbl = self.defaults.frames for i, frame in pairs(tbl) do rawset(self.ccframes, frame, true) @@ -766,3 +791,97 @@ function Clique:ADDON_LOADED(event, addon) self:EnableArenaFrames() end end + +-- Check whether the user is in a raid group or has raid-style party frames (CompactRaidFrames) enabled +function Clique:IsInRaidOrHasRaidFramesEnabled() + return IsInRaid() or GetCVarBool("useCompactPartyFrames") +end + +-- Remove stale frames from `self.ccframes` that are no longer valid. +-- +-- Ensures we only store the default frames and currently active raid frames. +function Clique:CleanStaleCCFrames(frames) + local validFrames = {} + + -- add default frames + for _, f in ipairs(self.defaults.frames) do + validFrames[f] = true + end + + -- add provided frames (e.g. dynamic raid frames) + for _, f in ipairs(frames) do + validFrames[f] = true + end + + -- prune stale frames that are no longer valid + for f in pairs(self.ccframes) do + if not validFrames[f] then + self.ccframes[f] = nil + end + end +end + +-- Enumerate and return currently active raid frames +-- +-- NOTE: CompactRaidFrames, or rather all raid frames in general – for either a +-- player or their pets – should be defined in the following format: +-- CompactRaidFrame{index} e.g. CompactRaidFrame1. +function Clique:GetActiveRaidFrames() + local frames = {} + + local frame = EnumerateFrames() + while frame do + local name = frame:GetName() + -- include only raid frames starting with `CompactRaidFrame` and ending with + -- a digit while having a valid unit value (ensures the frame belongs to a + -- player) + if name and name:find("^CompactRaidFrame%d+$") and frame.unit then + table.insert(frames, frame) + end + + frame = EnumerateFrames(frame) + end + + return frames +end + +-- Collect currently active raid frames, prune stale ones and re-register valid +-- ones +function Clique:EnableRaidFrames() + local raidFrames = self:GetActiveRaidFrames() + self:CleanStaleCCFrames(raidFrames) + for _, f in ipairs(raidFrames) do + self:RegisterFrame(f) + end +end + +-- Shared event handler for syncing dynamic raid/party frame changes +-- +-- NOTE: CompactRaidFrames, or rather all raid frames in general, are dynamic and are added to the +-- UIParent's "frame tree" on-demand, which requires hooking into multiple +-- different events that gets fired when the party or raid group roster changes. +-- Pets or CVar -related events need special handling and thus are separated. +local function HandleRaidFrameSync(self, event, unit) + if not self:IsInRaidOrHasRaidFramesEnabled() then return end + + if event == "UNIT_PET" then + -- only refresh if the pet belongs to player/party/raid + if unit == "player" or unit:match("^party%d+$") or unit:match("^raid%d+$") then + self:EnableRaidFrames() + end + elseif event == "CVAR_UPDATE" then + -- sync raid frames when toggling the interface option on/off + if unit == "USE_RAID_STYLE_PARTY_FRAMES" then + self:EnableRaidFrames() + end + else + self:EnableRaidFrames() + end +end + +-- Bind handler to events +Clique.PLAYER_ENTERING_WORLD = HandleRaidFrameSync +Clique.RAID_ROSTER_UPDATE = HandleRaidFrameSync +Clique.PARTY_MEMBERS_CHANGED = HandleRaidFrameSync +Clique.UNIT_PET = HandleRaidFrameSync +Clique.CVAR_UPDATE = HandleRaidFrameSync