From 2dbec4b8d6cc7c8b87d7ba18eea57193a8f12328 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Sat, 1 Aug 2026 18:12:28 -0500 Subject: [PATCH] Drive unit-frame clicks via secure attributes Replace the Lua OnClick dispatch (OnClick/ClickAction/RightClickAction) with secure frame attributes: default type1=target / type2=menu, and EnableClickCast now writes type/spell/macrotext/menu/target/focus attributes per button+modifier instead of caching a clickactions table read at click time. Drops the now-dead clickactions table and buttons list. Also set a "unit" attribute on each frame (at creation and re-synced in UpdateVisibility to the live token, so a party shown on the raid grid reports partyN, not raidN) so the hovered unit resolves from the frame. Match the target/focus/menu click keywords exactly rather than by prefix, so a spell whose name starts with "focus"/"target"/"menu" (e.g. Focus Magic) casts instead of being swallowed as the keyword action. --- api/unitframes.lua | 121 ++++++++------------------------------------- 1 file changed, 20 insertions(+), 101 deletions(-) diff --git a/api/unitframes.lua b/api/unitframes.lua index c857e8eb..e1d775cc 100644 --- a/api/unitframes.lua +++ b/api/unitframes.lua @@ -1174,28 +1174,6 @@ function pfUI.uf.OnUpdate() end end -function pfUI.uf.OnClick() - pfUI.uf:ClickAction(arg1) -end - -function pfUI.uf:RightClickAction(unit) - if unit == "player" then - ToggleDropDownMenu(1, nil, PlayerFrameDropDown, "cursor") - elseif unit == "target" then - ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor") - elseif unit == "pet" then - ToggleDropDownMenu(1, nil, PetFrameDropDown, "cursor") - elseif unit == "party" or strfind(unit, "party%d") then - ToggleDropDownMenu(1, nil, getglobal("PartyMemberFrame" .. this.id .. "DropDown"), "cursor") - elseif unit == "raid" or strfind(unit, "raid%d") then - local name = this.lastUnit - local unitstr = this.label .. this.id - FriendsDropDown.displayMode = "MENU" - FriendsDropDown.initialize = function() UnitPopup_ShowMenu(_G[UIDROPDOWNMENU_OPEN_MENU], "PARTY", unitstr, name, id) end - ToggleDropDownMenu(1, nil, FriendsDropDown, "cursor") - end -end - function pfUI.uf:EnableEvents() local f = self @@ -1234,7 +1212,8 @@ end function pfUI.uf:EnableScripts() local f = self - f:SetScript("OnClick", pfUI.uf.OnClick) + f:SetAttribute("type1", "target") + f:SetAttribute("type2", "menu") f:SetScript("OnShow", pfUI.uf.OnShow) f:SetScript("OnEvent", pfUI.uf.OnEvent) @@ -1396,7 +1375,6 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick) if f.label ~= "" then f:SetAttribute("unit", f.label .. f.id) - f:SetAttribute("type1", "target") end -- register frame for clique @@ -2085,14 +2063,6 @@ function pfUI.uf:RefreshUnit(unit, component) end end -local buttons = { - [1] = "LeftButton", - [2] = "RightButton", - [3] = "MiddleButton", - [4] = "Button4", - [5] = "Button5", -} - local modifiers = { [""] = "", ["alt"] = "_alt", @@ -2102,82 +2072,31 @@ local modifiers = { function pfUI.uf:EnableClickCast() if self.config.clickcast ~= "1" then return end - for bid, button in pairs(buttons) do + for bid = 1, 5 do -- LeftButton, RightButton, MiddleButton, Button4, Button5 for modifier, mconf in pairs(modifiers) do local bconf = bid == 1 and "" or bid - if pfUI_config.unitframes["clickcast"..bconf..mconf] ~= "" then - -- fill clickaction table - self.clickactions = self.clickactions or {} - self.clickactions[modifier..button] = pfUI_config.unitframes["clickcast"..bconf..mconf] + local action = pfUI_config.unitframes["clickcast"..bconf..mconf] + if action and action ~= "" then + local prefix = modifier ~= "" and (modifier .. "-") or "" + local low = string.lower(action) + if low == "menu" then + self:SetAttribute(prefix .. "type" .. bid, "menu") + elseif low == "target" then + self:SetAttribute(prefix .. "type" .. bid, "target") + elseif low == "focus" then + self:SetAttribute(prefix .. "type" .. bid, "focus") + elseif string.find(action, "^/") then + self:SetAttribute(prefix .. "type" .. bid, "macro") + self:SetAttribute(prefix .. "macrotext" .. bid, action) + else + self:SetAttribute(prefix .. "type" .. bid, "spell") + self:SetAttribute(prefix .. "spell" .. bid, action) + end end end end end -function pfUI.uf:ClickAction(button) - local label = this.label or "" - local id = this.id or "" - local unitstr = label .. id - local showmenu = button == "RightButton" and true or nil - if SpellIsTargeting() and button == "RightButton" then - SpellStopTargeting() - return - end - - if SpellIsTargeting() and button == "LeftButton" then - SpellTargetUnit(unitstr) - elseif CursorHasItem() then - DropItemOnUnit(unitstr) - end - - -- run click casting if enabled - local modstring = "" - modstring = IsAltKeyDown() and modstring.."alt" or modstring - modstring = IsControlKeyDown() and modstring.."ctrl" or modstring - modstring = IsShiftKeyDown() and modstring.."shift" or modstring - modstring = modstring..button - if this.clickactions and this.clickactions[modstring] then - local action_lower = string.lower(this.clickactions[modstring]) - if string.find(action_lower, "^menu") then - -- show menu - showmenu = true - elseif string.find(action_lower, "^target") then - -- target unit - showmenu = nil - else - -- run click cast action - local is_macro = string.find(this.clickactions[modstring], "^%/(.+)") - - local tswitch = UnitIsUnit(unitstr, "target") - - if is_macro then - RunMacroText(this.clickactions[modstring]) - else - CastSpellByName(this.clickactions[modstring]) - end - - if not tswitch then TargetLastTarget() end - - return - end - end - - -- dropdown menus - if showmenu then - pfUI.uf:RightClickAction(label) - return - end - - -- drop food on petframe - if label == "pet" and CursorHasItem() then - local playerClass = UnitClassBase("player") - if playerClass == "HUNTER" then - DropItemOnUnit("pet") - return - end - end -end - function pfUI.uf:AddIcon(frame, pos, icon, timeleft, stacks, start, duration) local showtime = frame.config.indicator_time == "1" and true or nil local showstacks = frame.config.indicator_stacks == "1" and true or nil