From 7e91cea29fe5242f80eabb192bbded4f6b3a08f9 Mon Sep 17 00:00:00 2001 From: James Whitehead II Date: Sat, 16 Oct 2010 17:27:43 +0100 Subject: [PATCH] Enabled frame unregistration Addons that are registering using ClickCastFrames should run ClickCastFrames[frame] = nil or ClickCastFrames[frame] = false. Addons that are using the group header, and are registering using the secure snippet method should do the following: local header = self:GetFrameref("clickcast_header") header:SetAttribute("clickcast_button", button) header:RunAttribute("clickcast_unregister") This code expect to be run on the header, but needs access to the button. This can probably be passed into your header via a frame reference, i.e: MyGroupHeader:SetFrameRef("foo", MyGroupHeaderUnitButton1) MyGroupHeader:Execute[[ local button = self:GetFrameRef("foo"); local header = self:GetFrameRef("clickcast_header") header:SetAttribute("clickcast_button", button) header:RunAttribute("clickcast_unregister") ]] --- Clique.lua | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/Clique.lua b/Clique.lua index cb2a9ba..eb9f894 100755 --- a/Clique.lua +++ b/Clique.lua @@ -71,13 +71,17 @@ function addon:Initialize() ]]) self:UpdateBlacklist() - -- OnEnter bootstrap script for group-header frames + -- This snippet is executed from the SecureHandlerEnterLeaveTemplate + -- _onenter and _onleave attributes. The 'self' attribute will contain + -- the unit frame itself. self.header:SetAttribute("clickcast_onenter", [===[ local header = self:GetParent():GetFrameRef("clickcast_header") header:RunFor(self, header:GetAttribute("setup_onenter")) ]===]) - -- OnLeave bootstrap script for group-header frames + -- This snippet is executed from the SecureHandlerEnterLeaveTemplate + -- _onenter and _onleave attributes. The 'self' attribute will contain + -- the unit frame itself. self.header:SetAttribute("clickcast_onleave", [===[ local header = self:GetParent():GetFrameRef("clickcast_header") header:RunFor(self, header:GetAttribute("setup_onleave")) @@ -86,17 +90,49 @@ function addon:Initialize() local setup, remove = self:GetClickAttributes() self.header:SetAttribute("setup_clicks", setup) self.header:SetAttribute("remove_clicks", remove) - self.header:SetAttribute("clickcast_register", ([===[ + + -- This snippet is executed from within the initialConfigFunction secure + -- snippet. The unit frame button is passed in the 'clickcast_button' + -- attribute, which can only be accomplished in a restricted environment. + self.header:SetAttribute("clickcast_register", [===[ local button = self:GetAttribute("clickcast_button") + + -- Export this frame so we can display it in the insecure environment + self:SetAttribute("export_register", button) + button:SetAttribute("clickcast_onenter", self:GetAttribute("clickcast_onenter")) button:SetAttribute("clickcast_onleave", self:GetAttribute("clickcast_onleave")) ccframes[button] = true self:RunFor(button, self:GetAttribute("setup_clicks")) - ]===]):format(self.attr_setup_clicks)) + ]===]) + + -- This snippet is executed from the Clique:UnregisterFrame() function, or + -- possibly from some other restricted environment. The unit frame is passed + -- in the 'clickcast_button' attribute, which can only be accomplished + -- in a restricted environment. + self.header:SetAttribute("clickcast_unregister", [===[ + local button = self:GetAttribute("clickcast_button") + + -- Export this frame so it can be removed from the blacklist editor + self:SetAttribute("export_unregister", button) + -- Remove any click and binding attributes that have already been set + self:RunFor(button, self:GetAttribute("clickcast_onleave")) + self:RunFor(button, self:GetAttribute("remove_clicks")) + + button:SetAttribute("clickcast_onenter", nil) + button:SetAttribute("clickcast_onleave", nil) + ccframes[button] = nil + ]===]) + + -- We need to track frame registrations so we can display secure frames in + -- the frame blacklist editor. This is done via the 'export_register' and + -- 'export_unregister' attributes. self.header:SetScript("OnAttributeChanged", function(frame, name, value) - if name == "clickcast_button" and type(value) ~= nil then + if name == "export_register" and type(value) ~= nil then self.hccframes[value] = true + elseif name == "export_unregister" and type(value) ~= nil then + self.hccframes[value] = nil end end) @@ -112,7 +148,7 @@ function addon:Initialize() local oldClickCastFrames = ClickCastFrames ClickCastFrames = setmetatable({}, {__newindex = function(t, k, v) - if v == nil then + if v == nil or v == false then self:UnregisterFrame(k) else self:RegisterFrame(k, v) @@ -140,15 +176,14 @@ function addon:Initialize() addon:UpdateEverything() end --- This function may be called during combat. When that is the case, the +-- These tables are a queue for frame registration/unregistration +addon.regqueue = {} +addon.unregqueue = {} + +-- these function may be called during combat. When that is the case, the -- request must be queued until combat ends, and then we can attempt to -- register those frames. This is mainly due to integration with the -- Blizzard raid frames, which we cannot 'register' while in combat. --- --- TODO: There may be a way, with a handle to the blizzard headers to --- find these new frames within a secure snippet, but I'm not sure how --- that would be possible -addon.regqueue = {} function addon:RegisterFrame(button) if InCombatLockdown() then table.insert(self.regqueue, button) @@ -172,6 +207,27 @@ function addon:RegisterFrame(button) self.header:Execute(self.header:GetAttribute("setup_clicks"), button) end +function addon:UnregisterFrame(button) + if InCombatLockdown() then + table.insert(self.unregqueue, button) + return + end + + -- Clear any click/bind attributes + self.header:SetFrameRef("cliquesetup_button", button) + self.header:Execute([[ + local button = self:GetFrameRef("cliquesetup_button") + self:RunFor(button, self:GetAttribute("setup_onleave")) + self:RunAttribute("remove_clicks") + ]]) + + self.ccframes[button] = nil + + -- Unwrap the OnEnter/OnLeave scripts, if they were set + addon.header:UnwrapScript(button, "OnEnter") + addon.header:UnwrapScript(button, "OnLeave") +end + function addon:Enable() -- Make the options window a pushable panel window UIPanelWindows["CliqueConfig"] = { -- 1.7.9.5