02-06-15, 12:41 PM | #1 |
Need help with SecureHandlers
I took over maintenance of the addon AutoBar ages ago and there's a bug I have not managed to figure out. For those who don't know AutoBar creates a bar of buttons. When you hover over the buttons a popup of buttons appears. So there is a Hearth button, hovering over it shows a popup of any Hearth objects you have, Mage ports (if you're a mage), etc. All of this works well.
When you move the cursor off of the popup, the popup should close. 99% of the time, it does however when you move the pointer really quickly sometimes it stays open. The original author claimed this was a Blizzard bug where fast movement sometimes failed to fire the leave event. I have no reason to believe he was mistaken, but I also have no proof that it is correct. His fix was to set an _ontimer snippet to check for the cursor over the frame, and if it had moved, hide the frame. But it doesn't work, and as far as I recall never did. I believe all of the relevant code is in a single file which is here: http://pastebin.com/8Gn329dh To help zero in on the issue, the snippet is called "popupNaziSnippet". It's defined on line 163, and attached to the _ontimer attribute on line 564. I've tried putting print statements in the snippet and even introducing syntax errors, and the lack of feedback makes me believe that the code is just not called. I believe that it is setup to re-trigger itself properly every second to recheck but the initial call is not happening. I'll be honest, while I've made progress on getting my head around this secure stuff, parts of it still feel like black magic to me so I could be completely wrong about a lot of this. It's a lot of code to look at and it's a bit of a mess, so I appreciate any help you can give me. |
|
02-06-15, 01:05 PM | #2 |
I am just guessing without looking into your code:
As far as I understand your description the layout is like Code:
-------------- | | | |-----| | | | | | | |-----| | | | | |-----| | | | | | | |-----| | | | | |-----| | | | | | | |-----| | | | -------------- I am guessing that the addon assumes that, if the cursor is over a button, it is obligatory to enter/leave the bar frame as the buttons are completely "surrounded" by the bar. Furthermore I'm ssuming that the addon hides the bar if the bar frames OnLeave triggers. As you wrote this will work if the cursor moves slowly - meaning the cursor moves from the button to the bar to the background (UIParent or whatever the bar is over). But, as the onenter/onleave events are only validated once per rendered frame it could happen (on very fast cursor movement) that the cursor is moved from the buttons bounds OUT of the bars bounds within a single rendered frame - completly skipping the bar frame. In this case the cursor never is over the bar frame and there are no OnEnter/OnLeave events for the bar frame. A solution could be to test on each buttons OnLeave if the cursor is over anything except a button or the bar and if this is the case (cursor was moved from a button straight out of the bar bounds) to hide the bar. Last edited by Duugu : 02-06-15 at 01:16 PM. |
|
02-08-15, 08:27 PM | #3 |
As I see, there is no '_ontimer' script handler, I don't think it would work. And there is no need to check the "OnLeave".
Take some code from your code Lua Code:
So, when your mouse enter the frame, show the popupHeader, and when mouse moved away from the popupHeader and the frame, hide the popupHeader. You can use the SecureHoverDriver to do the dirty work. Lua Code:
The SecureHoverDriver would check the popupHeader:GetRect() and frame:GetRect(), so no matter the mouse is on the popupHeader or it's buttons. |
|
02-09-15, 05:00 PM | #4 |
It looks like that's not the case. The "bar" doesn't not appear to enclose the buttons, they are just attached at one end so this doesn't seem like it's the issue.
|
|
02-09-15, 05:05 PM | #5 | |
So as a quick hack, I tried calling GetChildren to add them to the tracking as well, but that doesn't work; I get an error about directly creating a table in the restricted environment. |
||
02-09-15, 05:30 PM | #6 |
As far as I know you can create a table in the restricted enviroment with newtable():
a = newtable() |
|
02-09-15, 05:44 PM | #7 | |
Unfortunately, it doesn't help. I am able to iterate through the child buttons and add them to be watched, but if I move the mouse really fast, the popup is still stuck open. |
||
02-09-15, 08:03 PM | #8 |
The SecureHoverDriver will check whether the mouse is in the area by the time, so if the OnEnter wrapper is called, move mouse away, with a little sec, it'd be closed. It doesn't matter how quick you move the mouse away.
|
|
02-09-15, 08:27 PM | #9 | |
Lua Code:
And I'm able to get the popups to stick open when moving quickly. Maybe there's something else that's interfering with the proper behaviour? |
||
02-09-15, 08:48 PM | #10 |
Quite sure you need to assign the hover stuff inside the OnShow not inside the OnEnter. In the OnEnter you tell the frame to show but you can only set the hover after is is being shown. And will need to heritage from "SecureHandlerShowHideTemplate"
Last edited by Banknorris : 02-09-15 at 09:01 PM. |
|
02-10-15, 06:01 AM | #11 |
I think I know why, I faced the problem before in my IGAS_UI.
When one frame is RegisterAutoHide, the SecureHoverDriver would first check if the mouse is in it, and if not, it'll wait the mouse move in and be checked, then start the time counting. So, add the popupHeader to auto hide, but your mouse never move into it, would cause the popupHead can't be hidden. I use a little trick on it, for your example : Lua Code:
Since the mouse is in the frame, just auto hide the frame, the SecureHoverDriver'd handle it very well. Now, it's the trick, when the SecureHoverDriver hide the frame, it'd change the 'statehidden' attribute to true, then we can handle it like : Lua Code:
When the frame is hide, just show it again and hide the popupHeader. The code would cause the frame can't be hidden, just use some bool flag to control it since they are all running in the popupHandler's env. Last edited by kurapica.igas : 02-10-15 at 06:18 AM. |
|
02-16-15, 02:57 AM | #12 |
Here is the best solution so far from kurapica.igas. It's a big improvement over what I had, so I'm posting it in case it helps anyone else. It's not perfect though. After a fair bit of testing I was able to get the popups to still stick open. I'm wondering if it's possible to get a perfect solution.
When the button's OnEnter is fired, the SecureHoverDriver OnUpdate is fired the same time, since the button and it's popupHeader is registered, the SecureHoverDriver know it's time to start watching. Here's is the full solution : 1. Under the Lua Code:
Add Lua Code:
Lua Code:
1. start auto hide when the frame is shown, so the SecureHoverDriver can watch it. 3. mouse enter the frame, trigger the popupHeader show, can use popupMap to track it, so we know when the frame is hidden, it's used to hide the popupHeader. So when you hide the frame directly, the popupMap won't block you. 4. mouse move away the frame and the event is triggered, so just hide the popupHeader, and start whole a new auto hide workflow. 5. If the SecureHoverDriver hide the frame and the popupMap is true, hide the popupHeader and show the frame, with the OnShow wrap script, the new auto hide workflow will started. So, this is the final solution, but be aware, since the frames are always be registered to the SecureHoverDriver, the driver would check them for every OnUpdate, not much. Just test it by yourself. |
|
WoWInterface » Developer Discussions » Lua/XML Help » Need help with SecureHandlers |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|