Quite simple. The Blizzard UI has a secure frame, and I want to hide it permanently. For an insecure frame, this would simply be a matter of
f:Hide()
f.Show = f.Hide
and call it a day. And it still works in my situation, to an extent - the frame stays hidden, but if the Blizzard UI attempts to Show or (other protected action) that frame in combat, it complains about being tainted.
So, is this possible?
If not, my goal is have my own replacement for the secure frame. Could I simply play with frame levels and have my frame "cover up" the original?
It does matter, secure scripts can access the secure frame and end up being tainted. A possible solution is really to find out which events cause the frame to be shown, and unregister those events.
This won't work as you expect it to. This adds a post-hook (the original OnEvent still executes), plus you can't pass nil as the function in this function.
As has been pointed out, your best bet is to prevent the triggers that show the frame. Failing that, move it offscreen and protect it from being moved back.
It does matter, secure scripts can access the secure frame and end up being tainted.
Right, but if you're not using anything related the secure frame, including scripts that affect it, and just want to get rid of it, then the taint doesn't matter. :p
Why would f.Show = f.Hide taint? Both functions are secure, so long as you didn't try to do the hiding in combat...
It taints because insecure code (i.e non-blizzard code) did the assignment.
The execution path of the code went into addon code, the execution path becomes tainted. All assignments performed during a tainted execution path flag the assigned variable as tainted - even Blizzard variables and functions - unless the assigned value is nil.
Additional Note:
Also, in this particular case, f.Show doesn't actually exist in the table, :Show() is accessed via a metatable. f.Show = f.Hide actually creates a ["Show"] entry in the table. This doesn't negate the fact that any assignments performed during a tainted execution path still marks the assigned variable as tainted.
local securehandler = CreateFrame("Frame", nil, nil, "SecureHandlerBaseTemplate")
securehandler:WrapScript(<frame>, "OnShow", [[self:Hide()]])
good>
I'd love to have this work, but it simply fails, as far as I can tell - substituting PetPaperDollFrameCompanionFrame for "<frame>". I think I'm being greatly hindered here by the fact that I don't really "get" Secure Handlers, despite having read over Iriel's guide several times. =/
In the mean time, I've started on shoving the frame offscreen and rebuilding the necessary UI bits to integrate my addon, but it's a pain in the ass.
Alright... the PetPaperDollFrameCompanionFrame is implicitly protected, due to its twelve children, the CompanionButtonN's. So, I can't wrap a script on that, I suppose. Should my approach be to wrap and hide each of the twelve buttons, and hide their parent within that script as well?
EDIT: Answered my own question... I think. The following appears to be working. My new questions are: Is this the best way? Are there side-effects I'm not seeing?
for i=1,12 do
SecureHandlerWrapScript(_G["CompanionButton"..i], "OnShow", _G["CompanionButton"..i], [[ self:Hide() self:GetParent():Hide() ]])
end
Gah, I've found an intermittent bug and I can't figure this out. I'm still using the same code to hide the CompanionButtons and the PetPaperDollFrameCompanionFrame:
for i=1,12 do
SecureHandlerWrapScript(_G["CompanionButton"..i], "OnShow", _G["CompanionButton"..i],
[[ self:Hide() self:GetParent():Hide() ]])
end
I run this code once, when the addon loads. The addon also hooks the following code onto the "Pet", "Companions", and "Mounts" tab buttons:
-- "Pet" button
PetPaperDollFrameTab1:HookScript("OnClick", function(self)
FUR:Hide(); -- FUR is the frame that I use for listing companions/mounts
end)
-- "Companions" button
PetPaperDollFrameTab2:HookScript("OnClick", function(self)
COMPANIONTYPE = "CRITTER"
sortbutton:Disable()
scrollbar:SetMinMaxValues(0, math.max(0, GetNumCompanions(COMPANIONTYPE) - NUMROWS))
scrollbar:SetValue(0)
Show(); -- This just does a bit of background work before calling FUR:Show()
end)
-- "Mounts" button
PetPaperDollFrameTab3:HookScript("OnClick", function(self)
COMPANIONTYPE = "MOUNT"
sortbutton:Enable()
scrollbar:SetMinMaxValues(0, math.max(0, GetNumCompanions(COMPANIONTYPE) - NUMROWS))
scrollbar:SetValue(0)
Show();
end)
Now, the reason this has taken so long to notice is that it only happens rarely, after repeated switching. If I sit around and alternately click the three tabs long enough, when I get back to one of "my" tabs (Companions or Mounts) I'll have the PetPaperDollFrameCompanionFrame clearly visible underneath my UI.
With the hooked script hiding that frame as soon as the CompanionButtons show up, how is that possible?
Very relevant edit: On further experimentation, the Blizzard UI shows up after I've clicked on the tabs precisely twelve times. Seeing as this is the same as the number of CompanionButtons, this doesn't seem like a meaningless coincidence.
The first time I click on on either the Pets or Mounts tab button (thus bringing up my display via the hooked scripts above), the script I wrapped around CompanionButton1 fires. The second time I click, the script on #2 fires, and so on. Only one of those will fire per click, and after twelve clicks, none fire.
I cannot explain this, and I suspect that's due to a severe lack of understanding on my part. Would someone be so kind as to attempt an explanation of what a "header" and a "handler" are, or to try to convey some sense of the structure behind it all? I've read Iriel's Field Guide many times, but I think I'm missing some fundamental knowledge or familiarity, because it just doesn't make sense to me.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
and call it a day. And it still works in my situation, to an extent - the frame stays hidden, but if the Blizzard UI attempts to Show or (other protected action) that frame in combat, it complains about being tainted.
So, is this possible?
If not, my goal is have my own replacement for the secure frame. Could I simply play with frame levels and have my frame "cover up" the original?
and/or
This won't work as you expect it to. This adds a post-hook (the original OnEvent still executes), plus you can't pass nil as the function in this function.
This is what you're after.
You can also nil it without tainting anything, but quite unnecessary.
<frame>:SetScript("OnEvent", nil)
Right, but if you're not using anything related the secure frame, including scripts that affect it, and just want to get rid of it, then the taint doesn't matter. :p
It taints because insecure code (i.e non-blizzard code) did the assignment.
The execution path of the code went into addon code, the execution path becomes tainted. All assignments performed during a tainted execution path flag the assigned variable as tainted - even Blizzard variables and functions - unless the assigned value is nil.
Additional Note:
Also, in this particular case, f.Show doesn't actually exist in the table, :Show() is accessed via a metatable. f.Show = f.Hide actually creates a ["Show"] entry in the table. This doesn't negate the fact that any assignments performed during a tainted execution path still marks the assigned variable as tainted.
good?
I'd love to have this work, but it simply fails, as far as I can tell - substituting PetPaperDollFrameCompanionFrame for "<frame>". I think I'm being greatly hindered here by the fact that I don't really "get" Secure Handlers, despite having read over Iriel's guide several times. =/
In the mean time, I've started on shoving the frame offscreen and rebuilding the necessary UI bits to integrate my addon, but it's a pain in the ass.
wouldn't that do it?
EDIT: Answered my own question... I think. The following appears to be working. My new questions are: Is this the best way? Are there side-effects I'm not seeing?
I run this code once, when the addon loads. The addon also hooks the following code onto the "Pet", "Companions", and "Mounts" tab buttons:
Now, the reason this has taken so long to notice is that it only happens rarely, after repeated switching. If I sit around and alternately click the three tabs long enough, when I get back to one of "my" tabs (Companions or Mounts) I'll have the PetPaperDollFrameCompanionFrame clearly visible underneath my UI.
With the hooked script hiding that frame as soon as the CompanionButtons show up, how is that possible?
Very relevant edit: On further experimentation, the Blizzard UI shows up after I've clicked on the tabs precisely twelve times. Seeing as this is the same as the number of CompanionButtons, this doesn't seem like a meaningless coincidence.
I cannot explain this, and I suspect that's due to a severe lack of understanding on my part. Would someone be so kind as to attempt an explanation of what a "header" and a "handler" are, or to try to convey some sense of the structure behind it all? I've read Iriel's Field Guide many times, but I think I'm missing some fundamental knowledge or familiarity, because it just doesn't make sense to me.