Shift modifer bind not properly working with
dabadoo opened this issue ยท 21 comments
Here's an update: I have this fixed for all versions WOTLK, Retail and classic era. Just running regressions on the new code now to be sure. Will check-in and release in about a day or two.
@nfet
Quick test on SoD Classic.
At first it seemed to work. Pressing Shift-H worked on keydown.
I tried moving and spamming random buttons for a bit and suddenly it no longer works. I press shift-H and now it doesn't activate until key up.
Even bigger issue: The moment I press shift down the entire game freezes for a second then unfreezes again. Releasing shift doesn't cause any issue.
Some more info but don't know how useful it will be:
- Logged on a level 1 char and disabled all addons except this one. No issues with pressing shift.
- Changed to my main profile. Started freezing when pressing shift.
- Changed back to the default profile and the issue was gone.
That is so sad. I have archived that version (2024.3.7) from curseforge for now while I investigate. I will try and reproduce with a clean profile then with an existing profile.
Thank you for verifying. You are sincerely appreciated.
Also for the standard WoW Action Button behavior, I just wanted to confirm that you are getting the same standard behavior. The following details is what I experience in WoW actionbars.
Here's an example screenshot for visual aid
For this purpose, let's say I have priest class with Renew on Blizzard Actionbar1 slot 1 (keyboard shortcut 1).
1. "Lock Action Bars" is checked
Keypress Behavior
- When 1 is pressed, Renew will trigger on keydown (EDIT: If all addons are disabled, this will trigger on keyup). ActionbarPlus changed this behavior.)
- When the modifier key and 1 (i.e. SHIFT + 1) is held down, then the actionbutton triggers on keyup. This is because it also trigger the "unlock actionbar" feature so that the spell won't trigger on mouse drag.
Mouse Click Behavior
- When clicking the WoW action button, Renew always triggers on mouseup. This is different from ActionbarPlus, where Renew will trigger on mousedown unless the modifier key is pressed, where it then triggers on keyup.
2. "Lock Action Bars" is not checked (disabled)
Keypress Behavior
- When 1 is pressed, Renew will now trigger on keyup. This is so that the action will not trigger on mouse drag.
Mouse Click Behavior
- Same as Keypress Behavior, triggers on keyup
ActionbarPlus action buttons behavior
ABP will esssentially behave (should behave) the same way except it will trigger on mousedown when an action is pressed. This is what I'm aiming for anyways. Also, for retail, it doesn't support the "lock and hold down" action.
I think for this part, it's conditional. Please see my recent message on the button behavior.
If the "modifier key" + key is pressed, then action triggers on key-up. Holding the modifier key triggers the "unlock actionbar" so that the action can be clicked and dragged.
I disabled all the addons and the blizzard actionbars always triggers on keyup/mouseup. The side-effect of having actionbarplus enabled is that the mouse click triggers on keydown :-).
Expected Behavior:
Action button triggers "On Keydown" without delay
Also, I disabled all the addons except the debug addons and I couldn't reproduce the freeze on an existing actionbarplus profile. The "Addon Usage" addon reported only CPU usage of 1.5. This doesn't really take ABP off the hook but I will keep investigating.
I'm able to repro this on Retail:
Repro steps:
- Bind and action "Shift + key" and "Control + key" (same key)
- Drag and drop a spell into the same action slot
- Press Control + key (works as expected)
- Press Shift + key (I have to press 1+ consecutively) for it to trigger
4a. On a real spell, it may instantly work afterwards
4b. On a macro like/cast <spell>
, it consistently behaves bad (2+ consecutive clicks) for it to triggerExpected Behavior:
Action button triggers "On Keydown" without delay
For this part this is the correct behavior if "shift" is the assigned modifier key.
I press shift-H and now it doesn't activate until key up.
Some more info but don't know how useful it will be:
- Logged on a level 1 char and disabled all addons except this one. No issues with pressing shift.
- Changed to my main profile. Started freezing when pressing shift.
- Changed back to the default profile and the issue was gone.
Please let me know if this version is OK to be up on CurseForge, otherwise I will have to revert to the old behavior. I like this change now because it is consistent with all versions of WoW, but I don't want to risk potential bad freezing experience to others. Thank you again.
Here's the priest macro I tested with on SoD:
Keybind: ]
shift + ] or ctrl + ] is not keybinded, just ] (right square bracket)
/cast [harm] Shadow Word: Pain; [mod:ctrl] Lesser Heal; [mod:shift] Penance; Renew
Just note to self here. Upon initial investigation Addon Usage did not show any CPU or memory spike. For this reason, I need more details on how to repro, so I made version 2024.3.7 active again on Curse Forge in the hope that someone will run into this issue and get another detail on this.
The work around is that the user/player can revert to the older version.
Tested using version 2024.3.7
- "Lock Action Bars" is checked
Keypress Behavior
When 1 is pressed, Renew will trigger on keydown (EDIT: If all addons are disabled, this will trigger on keyup). ActionbarPlus changed this behavior.)
When the modifier key and 1 (i.e. SHIFT + 1) is held down, then the actionbutton triggers on keyup. This is because it also trigger the "unlock actionbar" feature so that the spell won't trigger on mouse drag.
For me when I disable all addons, use default blizzard actionbars and have locked them with shift key enabled to drag.
- When 2 is pressed Lesser Heal triggers on keydown
- When the modifier key and 2 (i.e. SHIFT + 2) is held down my actionbutton still triggers on keydown.
I tried deleting my account#1 config-cache and got same results as my previous testing.
I tried testing the behaivior again with only this addon enabled and Lesser heal placed on default actionbars.
- When 2 is pressed Lesser Heal triggers on keydown
- When the modifier key and 2 (i.e. SHIFT + 2) is held down my actionbutton now triggers on keyup.
I did some test with addonusage enabled and commented on my findings.
https://imgur.com/a/5qsG9DZ
Would it help if I gave you my profile?
https://pastebin.com/x7i2c5gu
The name of the profile causing issues is the "MyDefault" The binded macro I've been using, placed on the addon, is Shift-H for the macro "/use Supercharged Chronoboon Displacer\n/use Chronoboon Displacer\n"
Give this new version a try (Edit: 2024.3.10) when you can. I'll add more details on the fix in a bit.
Edit: 2024.3.10
https://legacy.curseforge.com/wow/addons/actionbarplus/files/
Thanks for the Addon Usage details and images. This will get me far. Seems like ABP is not playing nice with others. No need to get your profile for now. I'll will try to repro.
Cheers,
OK, I found a solution that makes all version (EDIT: all version of WoW) happy. Just running regressions now. Should be released by today.
Testing on SoD. Macro is not working when Shift-H pressed down.
The Freeze issue is much better. No longer getting second long freezes but there still seems to be some observable stuttering every time I press shift.
Spamming shift and nothing else still makes the addon shoot up in memory and cpu usage.
The cpu and mem are at the acceptable range. I will keep optimizing. But for the rest of the issues I am out of options at this point. I will have to get back to this sometime in the future. I apologize for the inconvenience.
I'm able to repro this on Retail:
Repro steps:
- Bind and action "Shift + key" and "Control + key" (same key)
- Drag and drop a spell into the same action slot
- Press Control + key (works as expected)
- Press Shift + key (I have to press 1+ consecutively) for it to trigger
4a. On a real spell, it may instantly work afterwards
4b. On a macro like/cast <spell>
, it consistently behaves bad (2+ consecutive clicks) for it to trigger
Expected Behavior:
Action button triggers "On Keydown" without delay
Some more testing:
Pressing a bind that's NOT a shift bind will still sometimes not work while pressing shift and the bind.
Example: I press F to Nature's Swiftness. On blizzard bars, if I held shift while pressing F, it would still use my F bind since nothing else is bound to it. Keydown works without issue.
When having bound F on a ABP bar it still works whether or not I hold shift while pressing F, BUT it doesn't always trigger on keyDown as it should.
I can make changes that fixes my keybinds to work with shift on keydown but then shift-clicking to move breaks and starts using items on Keydown when trying to drag with mouse.
So far it seems like I've managed to find a solution that makes it work very similair to the blizzard actionbars.
Keybinds trigger on down portion, as they should, no matter the modifer. Mouse clicking icons trigger on the up portion.
0 issues with accidentally using CDs/Consumables when moving action buttons around so far.
Hovering over an icon and pressing the relevant keybind on your keyboard unfortunately still triggers on the up portion instead of the down portion.
I can't really see how this would be a big issue for most players. Why hover over the bind and then choose to press the keybind?
This is the code for ButtonUI.lua. I made it together with chatgpt since I don't really understand much. So if there is something silly in here... I won't be able to explain why ๐
`
--[[-----------------------------------------------------------------------------
WoW Vars
-------------------------------------------------------------------------------]]
local GetCursorInfo, ClearCursor, CreateFrame, UIParent = GetCursorInfo, ClearCursor, CreateFrame, UIParent
local InCombatLockdown, GameFontHighlightSmallOutline = InCombatLockdown, GameFontHighlightSmallOutline
local C_Timer, C_PetJournal = C_Timer, C_PetJournal
--[[-----------------------------------------------------------------------------
LUA Vars
-------------------------------------------------------------------------------]]
local tostring, format, strlower, tinsert = tostring, string.format, string.lower, table.insert
--[[-----------------------------------------------------------------------------
Local Vars
-------------------------------------------------------------------------------]]
--- @type Namespace
local _, ns = ...
local pformat = ns.pformat
local O, GC, M, LibStub = ns.O, ns.O.GlobalConstants, ns.M, ns.O.LibStub
local AO = O.AceLibFactory:A()
local AceEvent, AceGUI, AceHook = AO.AceEvent, AO.AceGUI, AO.AceHook
local String = O.String
local A, P, PH = O.Assert, O.Profile, O.PickupHandler
local WMX, ButtonMX = O.WidgetMixin, O.ButtonMixin
local E, WAttr = GC.E, GC.WidgetAttributes
local IsBlank = String.IsBlank
local AssertThatMethodArgIsNotNil = A.AssertThatMethodArgIsNotNil
--[[-----------------------------------------------------------------------------
New Instance
-------------------------------------------------------------------------------]]
--- @Class ButtonUIWidgetBuilder : WidgetMixin
local _B = LibStub:NewLibrary(M.ButtonUIWidgetBuilder)
--- @Class ButtonUILib
local _L = LibStub:NewLibrary(M.ButtonUI, 1)
local p = O.LogFactory:NewLogger(M.ButtonUI)
--- @return ButtonUIWidgetBuilder
function _L:WidgetBuilder() return _B end
--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
--- @param cursorInfo CursorInfo
local function IsValidDragSource(cursorInfo)
--p:log("IsValidDragSource| CursorInfo=%s", cursorInfo)
if not cursorInfo or IsBlank(cursorInfo.type) then
-- This can happen if a chat tab or others is dragged into
-- the action bar.
--p:log(20, 'Received drag event with invalid cursor info. Skipping...')w
return false
end
return O.ReceiveDragEventHandler:IsSupportedCursorType(cursorInfo)
end
---TODO: See the following implementation to mimic keydown
--- - https://wowpedia.fandom.com/wiki/CVar_ActionButtonUseKeyDown
--- - https://www.wowinterface.com/forums/showthread.php?t=58768
--- @param widget ButtonUIWidget
--- @param down boolean true if the press is KeyDown
local function RegisterForClicks(widget, event, down)
local useKeyDown = GetCVarBool("ActionButtonUseKeyDown")
local btn = widget.button()
if E.ON_LEAVE == event then
if useKeyDown then
btn:RegisterForClicks('AnyDown')
else
btn:RegisterForClicks('AnyUp')
end
elseif E.ON_ENTER == event then
if useKeyDown then
--- Note: Macro will not trigger on first click if Drag Key is used in 'mod:<key>' in macros
--- Macros should not use mod:<key> on the same drag key
btn:RegisterForClicks('AnyUp')
else
btn:RegisterForClicks('AnyUp')
end
elseif E.MODIFIER_STATE_CHANGED == event or 'PreClick' == event or 'PostClick' == event then
if useKeyDown then
if down then
btn:RegisterForClicks('AnyDown') -- Register for down press for all keybound action buttons
else
btn:RegisterForClicks('AnyUp') -- Register for up press for all keybound action buttons
end
else
btn:RegisterForClicks('AnyUp')
end
end
end
--- @param btn ButtonUI
--- @param key string The key clicked
--- @param down boolean true if the press is KeyDown
local function OnPreClick(btn, key, down)
local w = btn.widget
w:SendMessage(GC.M.OnButtonPreClick, w)
if w:IsBattlePet() and C_PetJournal then
w:SendMessage(GC.M.OnButtonClickBattlePet, w)
return
elseif w:IsEquipmentSet() then
w:SendMessage(GC.M.OnButtonClickEquipmentSet, w)
return
else
w:UpdateRangeIndicator()
end
-- This prevents the button from being clicked
-- on sequential drag-and-drops (one after another)
if PH:IsPickingUpSomething(btn) then btn:SetAttribute("type", "empty") end
RegisterForClicks(w, 'PreClick', down)
end
--- @param btn ButtonUI
--- @param key string The key clicked
--- @param down boolean true if the press is KeyDown
local function OnPostClick(btn, key, down)
local w = btn.widget
w:SendMessage(GC.M.OnButtonPostClick, w)
---@param handlerFn ButtonHandlerFunction
local function CallbackFn(handlerFn) O.ActionbarPlusAPI:UpdateM6Macros(handlerFn) end
w:SendMessage(GC.M.OnButtonPostClickExt, ns.M.ButtonUI, CallbackFn)
-- This prevents the button from being clicked
-- on sequential drag-and-drops (one after another)
RegisterForClicks(w, 'PreClick', down)
end
--- @param btnUI ButtonUI
local function OnDragStart(btnUI)
if InCombatLockdown() then return end
--- @type ButtonUIWidget
local w = btnUI.widget
if w:IsEmpty() then return end
if InCombatLockdown() or not WMX:IsDragKeyDown() then return end
w:Reset()
p:log(20, 'DragStarted| Actionbar-Info: %s', pformat(btnUI.widget:GetActionbarInfo()))
PH:Pickup(btnUI.widget)
w:SetButtonAsEmpty()
w:ShowEmptyGrid()
w:ShowKeybindText(true)
w:Fire('OnDragStart')
end
--- Used with button:RegisterForDrag('LeftButton')
--- @param btnUI ButtonUI
local function OnReceiveDrag(btnUI)
if InCombatLockdown() then return end
AssertThatMethodArgIsNotNil(btnUI, 'btnUI', 'OnReceiveDrag(btnUI)')
local cursorUtil = ns:CreateCursorUtil()
if not cursorUtil:IsValid() then
p:log(20, 'OnReceiveDrag| CursorInfo: %s isValid: false', pformat:B()(cursorUtil:GetCursor()))
return false
else
p:log(20, 'OnReceiveDrag| CursorInfo: %s', pformat:B()(cursorUtil:GetCursor()))
end
ClearCursor()
--- @type ReceiveDragEventHandler
O.ReceiveDragEventHandler:Handle(btnUI, cursorUtil)
btnUI.widget:Fire('OnReceiveDrag')
end
---Triggered by SetCallback('event', fn)
--- @param widget ButtonUIWidget
local function OnReceiveDragCallback(widget) widget:UpdateStateDelayed(0.01) end
--- @param button Frame The action button frame
--- @return boolean true if the mouse is over the action button, false otherwise
local function IsMouseOverActionButton(button)
local mouseX, mouseY = GetCursorPosition()
local scale = UIParent:GetEffectiveScale()
local buttonX, buttonY = button:GetCenter()
if not buttonX or not buttonY then
return false
end
local buttonWidth = button:GetWidth()
local buttonHeight = button:GetHeight()
buttonX = buttonX * scale
buttonY = buttonY * scale
return mouseX >= (buttonX - buttonWidth / 2) and mouseX <= (buttonX + buttonWidth / 2)
and mouseY >= (buttonY - buttonHeight / 2) and mouseY <= (buttonY + buttonHeight / 2)
end
--- @param widget ButtonUIWidget
--- @param event string
--- @param mouseButtonPressed string LMOUSECLICK, etc...
--- @param down boolean 1 or true if the press is KeyDown
local function OnModifierStateChanged(widget, event, mouseButtonPressed, down)
if IsMouseOverActionButton(widget.button()) then
-- If the mouse is over the action button, ignore modifier key presses
RegisterForClicks(widget, E.MODIFIER_STATE_CHANGED)
else
-- If the mouse is not over the action button, handle modifier key presses
RegisterForClicks(widget, E.MODIFIER_STATE_CHANGED, down)
if widget:IsMacro() then
if mouseButtonPressed == "LeftButton" and IsModifierKeyDown() then
widget:RegisterForClicks('AnyDown') -- Register for down press for left mouse button when modifiers are active
else
widget:UpdateMacroState()
end
end
end
end
--- @param widget ButtonUIWidget
local function OnBeforeEnter(widget)
RegisterForClicks(widget, E.ON_ENTER)
widget:RegisterEvent(E.MODIFIER_STATE_CHANGED, OnModifierStateChanged, widget)
-- handle stuff before event
--- @param down boolean true if the press is KeyDown
--widget:RegisterEvent(E.MODIFIER_STATE_CHANGED, function(w, event, key, down)
-- RegisterForClicks(w, E.MODIFIER_STATE_CHANGED, down)
--end, widget)
end
--- @param widget ButtonUIWidget
local function OnBeforeLeave(widget)
--RegisterMacroEvent(widget)
if not widget:IsMacro() then
--widget:RegisterEvent(E.MODIFIER_STATE_CHANGED, OnModifierStateChanged, widget)
widget:UnregisterEvent(E.MODIFIER_STATE_CHANGED)
end
RegisterForClicks(widget, E.ON_LEAVE)
end
--- @param btn ButtonUI
local function OnEnter(btn)
OnBeforeEnter(btn.widget)
---Receiver will get a func(widget, event) {}
btn.widget:Fire(E.ON_ENTER)
end
--- @param btn ButtonUI
local function OnLeave(btn)
OnBeforeLeave(btn.widget)
---Receiver will get a func(widget, event) {}
btn.widget:Fire(E.ON_LEAVE)
end
local function OnClick_SecureHookScript(btn, mouseButton, down)
--p:log(20, 'SecureHookScript| Actionbar: %s', pformat(btn.widget:GetActionbarInfo()))
btn:RegisterForClicks(WMX:IsDragKeyDown() and 'AnyUp' or 'AnyDown')
if not PH:IsPickingUpSomething() then return end
OnReceiveDrag(btn)
end
--- @param widget ButtonUIWidget
--- @param event string Event string
local function OnUpdateButtonCooldown(widget, event)
if widget:IsNotUpdatable() then return end
widget:UpdateCooldown()
local cd = widget:GetCooldownInfo();
if (cd == nil or cd.icon == nil) then return end
widget:SetCooldownTextures(cd.icon)
end
--- @param widget ButtonUIWidget
--- @param event string Event string
local function OnSpellUpdateUsable(widget, event)
if widget:IsNotUpdatable() then return end
widget:UpdateRangeIndicator()
widget:UpdateUsable()
widget:UpdateGlow()
end
--- @param widget ButtonUIWidget
--- @param event string
local function OnPlayerControlLost(widget, event, ...)
if not widget:IsHideWhenTaxi() then return end
C_Timer.After(1, function()
local playerOnTaxi = UnitOnTaxi(GC.UnitId.player)
p:log(10, 'Player on Taxi: %s [%s]', playerOnTaxi, GetTime())
if playerOnTaxi ~= true then return end
WMX:ShowActionbarsDelayed(false, 1)
end)
end
--- @param widget ButtonUIWidget
--- @param event string
local function OnPlayerControlGained(widget, event, ...)
if not widget:IsHideWhenTaxi() then return end
WMX:ShowActionbarsDelayed(true, 2)
end
--- @see "UnitDocumentation.lua"
--- @param widget ButtonUIWidget
--- @param event string
local function OnPlayerTargetChanged(widget, event)
if widget:IsNotUpdatable() then return end
widget:UpdateRangeIndicator()
end
--- @see "UnitDocumentation.lua"
--- @param widget ButtonUIWidget
--- @param event string
local function OnPlayerTargetChangedDelayed(widget, event)
C_Timer.After(0.1, function() OnPlayerTargetChanged(widget, event) end)
end
---@param widget ButtonUIWidget
local function OnPlayerStoppedMoving(widget, event)
--if widget:IsNotUpdatable() then return end
--p:log('moving-stopped[%s]: %s', widget:GN(), GetTime())
OnPlayerTargetChangedDelayed(widget, event)
end
--[[-----------------------------------------------------------------------------
Support Functions
-------------------------------------------------------------------------------]]
--- @param widget ButtonUIWidget
--- @param name string The widget name.
local function RegisterWidget(widget, name)
assert(widget ~= nil)
assert(name ~= nil)
local WidgetBase = AceGUI.WidgetBase
widget.userdata = {}
widget.events = {}
local mt = {
__tostring = function() return name end,
__index = WidgetBase
}
setmetatable(widget, mt)
end
--- @param button ButtonUI
local function RegisterScripts(button)
AceHook:SecureHookScript(button, 'OnClick', OnClick_SecureHookScript)
button:SetScript("PreClick", OnPreClick)
button:SetScript("PostClick", OnPostClick)
button:SetScript('OnDragStart', OnDragStart)
button:SetScript('OnReceiveDrag', OnReceiveDrag)
button:SetScript(E.ON_ENTER, OnEnter)
button:SetScript(E.ON_LEAVE, OnLeave)
end
--- @param widget ButtonUIWidget
local function RegisterSpellUpdateUsable(widget)
if not ns:IsVanilla() then
widget:RegisterEvent(E.SPELL_UPDATE_USABLE, OnSpellUpdateUsable, widget)
else
-- In Vanilla, SPELL_UPDATE_USABLE does not fire very often
widget:RegisterBucketEvent({ E.SPELL_UPDATE_USABLE, E.ACTIONBAR_UPDATE_USABLE }, 0.1, function(units)
OnSpellUpdateUsable(widget)
end);
end
end
--- see: Interface_[Vanilla|TBC|etc.]/FrameXML/Constants.lua
--- ClassicExpansionAtLeast(LE_EXPANSION_CLASSIC)
--- ClassicExpansionAtLeast(LE_EXPANSION_BURNING_CRUSADE)
--- @param widget ButtonUIWidget
local function RegisterUpdateRangeIndicatorOnSpellCast(widget)
if not GC.F.ENABLE_RANGE_INDICATOR_UPDATE_ON_SPELLCAST then return end
local bucketEvents = { E.UNIT_SPELLCAST_SENT, E.UNIT_SPELLCAST_FAILED }
widget:RegisterBucketEvent(bucketEvents, 0.5, function(units)
if not units.player then return end
if widget:IsHidden() or O.API:HasTarget() ~= true then return end
local spell, ranged = widget:GetEffectiveRangedSpellName()
if ranged == false then return end
widget:UpdateRangeIndicatorBySpell(spell)
end, widget)
end
--- @param widget ButtonUIWidget
local function RegisterCallbacks(widget)
-- TODO Next: Tracks changing spells such as Covenant abilities in Shadowlands.
widget:RegisterEvent(E.SPELL_UPDATE_COOLDOWN, OnUpdateButtonCooldown, widget)
widget:RegisterEvent(E.PLAYER_CONTROL_LOST, OnPlayerControlLost, widget)
widget:RegisterEvent(E.PLAYER_CONTROL_GAINED, OnPlayerControlGained, widget)
widget:RegisterEvent(E.MODIFIER_STATE_CHANGED, OnModifierStateChanged, widget)
widget:RegisterEvent(E.PLAYER_STOPPED_MOVING, OnPlayerStoppedMoving, widget)
RegisterSpellUpdateUsable(widget)
RegisterUpdateRangeIndicatorOnSpellCast(widget)
-- Callbacks (fired via Ace Events)
widget:SetCallback(E.ON_RECEIVE_DRAG, OnReceiveDragCallback)
--- @param w ButtonUIWidget
widget:SetCallback("OnEnter", function(w)
if InCombatLockdown() then return end
if not GetCursorInfo() then return end
w:SetHighlightEmptyButtonEnabled(true)
end)
widget:SetCallback("OnLeave", function(w)
if InCombatLockdown() then return end
if not GetCursorInfo() then return end
w:SetHighlightEmptyButtonEnabled(false)
end)
end
--[[-----------------------------------------------------------------------------
Builder Methods
-------------------------------------------------------------------------------]]
---Creates a new ButtonUI
--- @param dragFrameWidget FrameWidget The drag frame this button is attached to
--- @param rowNum number The row number
--- @param colNum number The column number
--- @param btnIndex number The button index number
--- @return ButtonUIWidget
function _B:Create(dragFrameWidget, rowNum, colNum, btnIndex)
local btnName = GC:ButtonName(dragFrameWidget.index, btnIndex)
--- @class __ButtonUI
local button = CreateFrame("Button", btnName, UIParent, GC.C.SECURE_ACTION_BUTTON_TEMPLATE)
--- @alias ButtonUI __ButtonUI|_Button
--local button = CreateFrame("Button", btnName, UIParent, "SecureActionButtonTemplate,SecureHandlerBaseTemplate")
button.text = WMX:CreateFontString(button)
button.indexText = WMX:CreateIndexTextFontString(button)
button.keybindText = WMX:CreateKeybindTextFontString(button)
button.nameText = WMX:CreateNameTextFontString(button)
RegisterScripts(button)
-- todo next: add ActionButtonUseKeyDown to options UI; add to abp_info
-- iterate through all buttons and call #RegisterForClicks()
-- /run SetCVar("ActionButtonUseKeyDown", 1)
-- /run SetCVar("ActionButtonUseKeyDown", 0)
-- /dump GetCVarBool("ActionButtonUseKeyDown")
button:RegisterForDrag("LeftButton", "RightButton");
button:RegisterForClicks("AnyDown", "AnyUp");
--- see: Interface/AddOns/Blizzard_APIDocumentationGenerated/CooldownFrameAPIDocumentation.lua
--- @class CooldownFrame : _CooldownFrame
local cooldown = CreateFrame("Cooldown", btnName .. 'Cooldown', button, "CooldownFrameTemplate")
cooldown:SetAllPoints(button)
cooldown:SetSwipeColor(1, 1, 1)
cooldown:SetCountdownFont(GameFontHighlightSmallOutline:GetFont())
cooldown:SetDrawEdge(true)
cooldown:SetEdgeScale(0.0)
cooldown:SetHideCountdownNumbers(false)
cooldown:SetUseCircularEdge(false)
cooldown:SetPoint('CENTER')
--- @alias ButtonUIWidget __ButtonUIWidget | BaseLibraryObject_WithAceEvent
--- @class __ButtonUIWidget : ButtonMixin
local __widget = {
--- @type fun() : ActionbarPlus
addon = function() return ABP end,
--- @type number
index = btnIndex,
--- @type number
frameIndex = dragFrameWidget:GetIndex(),
--- @type string
buttonName = btnName,
--- @type fun() : FrameWidget
dragFrame = function() return dragFrameWidget end,
--- @type fun() : ButtonUI
button = function() return button end,
--- @type fun() : CooldownFrame
cooldown = function() return cooldown end,
--- @type table
cooldownInfo = nil,
---Don't make this 'LOW'. ElvUI AFK Disables it after coming back from AFK
--- @type string
frameStrata = dragFrameWidget.frameStrata or 'MEDIUM',
frameLevel = (dragFrameWidget.frameLevel + 100) or 100,
--- @type number
buttonPadding = 1,
placement = { rowNum = rowNum, colNum = colNum },
}
--- @type ButtonUIWidget
local widget = __widget
button.widget, cooldown.widget = widget, widget
AceEvent:Embed(widget)
ns:AceBucketEmbed(widget)
ButtonMX:Mixin(widget)
RegisterWidget(widget, btnName .. '::Widget')
RegisterCallbacks(widget)
widget:InitWidget()
return widget
end
`
Hi There,
Please give this another try and see if it is fixed on #344.
Tried latest version but the issue still persist. @kapresoft