Neuron

Neuron

98.2k Downloads

Stealth bar is staying active even after toon leaves stealth

raysmith59 opened this issue ยท 15 comments

commented

Reminder: my stances/stealth bar is separate from my main action bar so I have a second set of buttons using 1-8, etc, set as higher priority when active (which, unless I'm currently stealthed, it shouldn't be).

I haven't played my rogue much lately so not sure if this is a new issue or not but when I start combat in stealth my stealth bar is active as expected, however when stealth breaks the stealth icons disappear but the buttons stay active so when I use hotkeys, they're activating on the blank stealth bar buttons rather than reverting back to the action bar as they should. I can't use stealth on my rogue when in combat because of this so it's relatively important to me to get this fixed.

commented

This is still happening and is preventing me from starting combat in stealth. My rogue is a possible main going into SL so it would be good if this could be addressed soon.

commented

Hrm I want to make fixing this a priority. So you're saying that the empty buttons are stealing priority from your main buttons once stealth breaks. Is this because the bar isn't hiding as it should be? The priority should only take over when the bar is shown, and when it is hidden the priority should revert back to the normal bar.

So in essence, the bug is that the stealth bar isn't going hidden, thus freeing up the keybinds for your main bar correct?

commented

Ok so I have some bad news. I genuinely don't know if I can fix this issue.

Basically it comes down to this, the fact that the "priority" trick works for you is because the button is being hidden. And, I don't mean "hidden" in the normal language sense, I mean hidden in the game code sense, as in the frame is having :Hide() invoked. When that button is hidden with :Hide() it physically is gone, so to speak, so the binding reverts to the other button because the priority button is actually legitimately gone (as opposed to just being invisible). This works perfectly out-of-combat because out-of-combat I can freely use :Hide() and :Show() functions on a button; however, these functions are illegal to use in combat, and result in a Lua error if tried.

So what's happening is that when you are in combat the :Hide() function is never called (because I have that call wrapped in a if-then statement that makes sure you aren't in combat before trying). Thus the button never gets properly hidden, and the keybind stays active and never relinquishes.

Unfortunately, this isn't a bug and it's actually programmed exactly as it should be. In fact, for every other bar type (Zone Ability, Extra Action, Exit, etc, etc) I have move away from using :Hide() and :Show() entirely due to this limitation and instead am just using :SetAlpha(0) or :SetAlpha(1) respectively to imitate the same effect without the combat lockdown limitation. At one point I had switched over the ActionButton code to also make use of :SetAlpha(), but reverted it back to :Hide() and :Show() because you made the case for your interesting keybind situation. However, we're now running into the combat situation as you've found out, which I didn't think of months back when we last spoke about this.

Honestly, I genuinely don't know if there's a solution for you. My hands are tied with the WoW API. I believe you're the only one who uses keybinds in this particular way, and while this is clearly not what you want to hear, I truly believe your best bet is to just keep the key bound to a single button, and make use of the stealth state on that bar. Which sucks. The last thing I want is to try to have you change your UI for no reason, but with a new expac happening maybe you can rearrange your bars to facilitate this. :-/

commented

If you make macros with the [stealth] macro conditional, Neuron does change the icon properly depending on the conditional state. Some time during MoP, I started just using macro conditionals instead of bar states with Ion (predecessor of Neuron) and it worked perfectly. So, there is hope for a workaround that works well.

commented

The stealth bar state is just a fancy way of providing [stealth] conditionals for all buttons on a bar simultaneously lol. Under the hood it works out to be the same. Doing a manual [stealth] conditional allows you to do it per-button though, which can be nice too.

commented

Going back to your first recent response, no, not quite, and hopefully that makes it fixable. In this one specific case (and only this one, far as I can recall), the bar is hiding correctly but the hidden bar priority keybinds are retaining priority even though the bar isn't showing. So, if for instance I had the exact same buttons on both bars, I wouldn't even notice the issue if it wasn't for the missing activation animation on the main bar. Any buttons that are mapped on the stealth bar continue to be active hotkeys, any missing hotkeys on the stealth bar work correctly on the main action bar. In this entire scenario, the bar grid never shows so it shouldn't run into the :Hide() combat issue you mention above. It seems that the change of state somehow isn't freeing up the priority keybinds.

Basically, this issue is almost the complete opposite of the other one I've reported. :)

Spitballing a bit, there's probably a more elegant solution to this since it seems to be a one-off (maybe just a missing scenario conditional somewhere?) , but it strikes me that a wrapper around the priority keybinds could work, something along the lines of:

if keypressed then
if max priority keybind spellbind is not NULL then activate
if max-1 priority keybind spellbind is not NULL then activate
etc until it activates or runs out of priority keybinds
end

Basically have it cycle through all the keybinds from max to 1. I'm asssuming the keybind priority list is stored somewhere.

Again, though, that seems like a pretty major change for a very specific issue so I think the answer probably lies elsewhere. Where in the code are the state changes? I can take a look and maybe play around with the code a bit or add in some diagnostic code for my own testing.

commented

The bar/button is disappearing correctly (or at least appears to be hiding correctly) but that's a different thing. There's a huge difference between not being visible and actually being hidden. "Hidden" is a state that a frame that can take that has much larger implications than just not being visible. The buttons themselves aren't being hidden fully. In order to free up the keybind a full-blown :Hide() must be called, because as long as the button is shown (even if it is invisible for other reasons or the contents are empty) that button owns that keybind.

Unfortunately your wrapper idea won't work due to the games SecureFrame implementation. It isn't Neuron's code that is controlling the priority of keybinds nor is it Neuron that is executing anything when the keybind is pressed. Neuron is nicely asking the SecureFrame API to broker these transactions for us. The game is extremely protective about addons and how they interact with in-game abilities, and in WoW 2.0 they introduced the idea of Secure Frames and taint. This means that how a macro is or isn't executed and how a keybind is or isn't working is largely outside of our control except for very specific API interfaces that Blizzard allows us to use, each of which only is usable out of combat.

So, in essence, when a frame is shown and has a keybind attached to it (in the case of a checkbutton which is what all Neuron Action Buttons are) the game is what is controlling the keybind priority based on how Neuron asked it to do so at startup. The only way to get a frame to release a keybind is to

  1. tell it to release manually using the secure frame interface (which can only happen out of combat)
  2. destroy the frame (which can only happen out of combat)
  3. :Hide() the frame (which can only happen out of combat)

This is why the releasing of the keybind works out of combat, because we are able to hide it, but not in combat where the :Hide() function is never called. The contents of the buttons clear just fine because those are tied to the state change, but that is different from the button itself.

You can find all the code for this in Neuron > Objects > ACTIONBUTTON. The function that handles the showing/hiding of button objects is UpdateObjectVisibility() on line ~93 (depending on which version you're looking at)

commented

The stealth bar state is just a fancy way of providing [stealth] conditionals for all buttons on a bar simultaneously lol. Under the hood it works out to be the same. Doing a manual [stealth] conditional allows you to do it per-button though, which can be nice too.

If that was the case, this wouldn't be an issue. On my rogue, the stealth states of my buttons do not stay active after leaving stealth, even in combat, and I suspect this is because I use [stealth] conditionals on all the buttons I want to switch during stealth.

commented

The stealth bar state is just a fancy way of providing [stealth] conditionals for all buttons on a bar simultaneously lol. Under the hood it works out to be the same. Doing a manual [stealth] conditional allows you to do it per-button though, which can be nice too.

If that was the case, this wouldn't be an issue. On my rogue, the stealth states of my buttons do not stay active after leaving stealth, even in combat, and I suspect this is because I use [stealth] conditionals on all the buttons I want to switch during stealth.

I believe you are misunderstanding his issue. The issue isn't that the stealth state isn't switching appropriately, it's that he has two separate bars - a main action bar and a bar he uses solely for stealth. He uses the same keybinds on both of these bars, using the keybind "priority" to set higher precedent for the stealth bar keybinds than the main bar keybinds. The idea is that when he is in a stealth state the stealth bar buttons will "come alive" and take over the keybinds, but outside of stealth the keybinds return to the buttons on the other bar. For this to work, he needs to :Hide() the buttons on the stealth bar to free up the keybinds so that his main action bar (where he has those same keys redundantly bound) will take over control of those key presses. If the stealth bar's buttons stay shown then they keep control of the keybinds and they aren't relinquished to the main action bar.

States and state changes apply only to the contents of a button, not the button object itself. The contents of his stealth bar are indeed changing to empty as they should when he leaves stealth, however the buttons themselves are remaining shown, hence his issue.

commented

That function at line 93 only seems to activate if out of combat, where's the code to "disappear" the bar when going out of stealth when in combat?

Yes I think I mentioned that earlier that the code to :Hide() and :Show() are protected by an if-then check for in-combat status, to not do so would result in a 100% chance of getting a Lua error when entering combat. I know this from experience, but for science you can try for yourself.

The code to "disappear" the bar is going to be in part of ACTIONBUTTON.lua where we create and set the object handlers and watchers. We have to pre-declare these code snippets we want executed on state change/key press/etc using :SetAttribute() calls and passing that code as a string. The particular variable of interest is the showGrid attribute. There is code to hide the buttons appearance (but not the button itself) if the contents of the button for a given state is empty and the showGrid flag is set. Though note, WE ARE NOT EXECUTING THE CODE SNIPPETS. We pre-loaded the code snippets using the SecureActionButton interfaces, but at runtime it's the SecureActionButton system that is responsible for executing the resultant actions. We are not allowed to perform the actions directly on these buttons or we get Lua errors blocking us.

Blizzard added this to protect the integrity of the game from add-ons being able to execute button pushes and whatnot directly. There used to be add-ons in Vanilla that would literally play the game for a person, hence why in 2.0 they added the SecureActionButton system to act as a barrier to prevent add-ons from having direct control of action buttons, particularly in combat, while still having a bit of control if we ask nicely and use the means provided to us by the SecureActionButton system and follow the rules.

https://wowwiki.fandom.com/wiki/SecureActionButtonTemplate

This is why I'm still nearly certain that this issues were facing isn't one we can skirt around. My hands are tied in that I cannot free up a keybind or :Hide() a frame in combat. And one of those two is what needs to happen for your use case to work. The issue is the "in-combat" part that has me in a bind. Out of combat this system you have set up works perfectly.

commented

That function at line 93 only seems to activate if out of combat, where's the code to "disappear" the bar when going out of stealth when in combat?

commented

What I'm saying about the workaround is that it doesn't need to call :Hide() at all to change the functionality of the button in combat if all the functionality is in the same macro. It just needs to update the icon and cooldown to the correct icon and cooldown for the part of the macro that will be activated depending on the current conditional state. The game will take care of handling the [stealth] conditional and since the keybind doesn't change, no keybind needs to be released.

For example, with macro /use [stealth]Ambush;Backstab, Neuron only needs to change the cooldown and icon, and the secure action button handles the keybind and execution of the macro itself as usual.

What I mean to say is that there's a workaround that allows the functionality desired. We don't have to act like it's impossible to have buttons with different states depending on stealth state. Sure, maybe an incorrect setup where an entire bar is destroyed and keybinds switched mid-combat wouldn't work, but that's not what should be done for this to work, and it's not this:

a fancy way of providing [stealth] conditionals for all buttons on a bar simultaneously

What I'm suggesting is for raysmith59 to try using 1 bar with macro conditionals in that bar's macros, and separate buttons for binding the same binds but with modifier keys. It works beautifully.

Further work toward making button swapping based on conditional state can be considered later, but for now, my contribution to this discussion is meant to be that raysmith59 is not stuck unable to play rogue with the exact set of keybinds and states desired per button. That exact configuration is possible if configured using conditionals within macros on the buttons of 1 bar.

commented

"Stealth states apply only to the contents of a button, not the button object itself. The contents of his stealth bar are indeed changing to empty as they should when he leaves stealth, however the buttons themselves are remaining shown, hence his issue."

That's the thing, though, the buttons themselves aren't remaining shown, or at least not in a way that I can see. The only reason I'm pushing this is that at some point in the not that distant past, this functionality worked. I've had the separate stealth (and override/etc) bar for years and it's only recentlyish (I think at or near the time where the grid being visible caused the keybinds to activate even with empty buttons, an issue that still exists last time I checked) that this became an issue. I also think that the keybinds go away when the bar is switching back from an override/etc state, pretty sure at some point in the past 6 months or more I had one of those bars go away while I was in combat and I'd have noticed if my action bar hotkeys weren't working. Not sure how I could confirm that easily but would it be useful information if this issue was literally only caused when switching from stealth and not from the other conditionals?

"What I'm suggesting is for raysmith59 to try using 1 bar with macro conditionals in that bar's macros, and separate buttons for binding the same binds but with modifier keys. It works beautifully."

For the record, I just can't use modifier keys. Personal limitation, it is what it is. I realize my in-game life would be far superior if I could, most of my oddball configs (that have historically worked, to be clear :) ) are me trying to work around that limitation.

In terms of stealth conditionals, if I end up raiding my rogue (or feral dr.... BWHAHAHAHA, never mind) and this still isn't working I'll either do that or just make my action bar the stealth bar as well, both of those would work around the issue but still wouldn't get me what I want which is to have access to the action bar buttons while in an altered state, sometimes I want to hit a button that isn't on my stealth bar while stealthed, that's the main reason I broke it out originally but not the only one. Yes, it's possible to work around that too but I'd ideally just like to get things back to how they were before it broke.

Hell... considering the SL delay I may go back into the version archives and see if I can figure out exactly when it broke, hopefully they go back far enough. That'd probably help a lot. Leave this with me for now.

commented

What I'm suggesting is for raysmith59 to try using 1 bar with macro conditionals in that bar's macros, and separate buttons for binding the same binds but with modifier keys. It works beautifully.

For the record, I just can't use modifier keys. Personal limitation, it is what it is.

I think you misunderstood me. I only mentioned modifier keys as a bonus. Those would be completely separate buttons, and would not be part of the suggested workaround. Try reading this line without the confusing bonus instead:

What I'm suggesting is for raysmith59 to try using 1 bar with macro conditionals in that bar's macros. It works beautifully.

I was hoping that would be how it was interpreted and the bonus was considered a bonus, but I was wrong.

Aside:

sometimes I want to hit a button that isn't on my stealth bar while stealthed

If you want to activate abilities while in stealth that aren't in your stealth conditional bar, you can do that with the no-bar-states workaround. Just have another macro on a different button that is exclusively for that ability. This all works without bar states. My entire Neuron setup on all classes avoids bar states completely because they're not actually necessary. Macro conditionals with unlimited macros work very well.

commented

Ok, after doing a metric shit ton of reading and trial and error, I have discovered that you can use :Show() and :Hide() commands in-combat for a given button if you do so exclusively through the SecureActionButton interface, which makes sense. For it to work, you have to have all conditionals set ahead of time, so there's no room for on-the-fly manipulation to the show/hide state, but given our conditions are pretty simple if the button should be shown or hidden (A. is there a macro on this button? and B. is ShowGrid set?) I was able to derive some logic that seems to work 100% of the time as far as I can tell.

Please test MASTER thoroughly @raysmith59. This particular feature exists pretty much solely for your benefit, so I expect you to do some thorough QA on it for me ;-) (I'm teasing lol)