Merge pull request #86 from KameleonUK/main
Fixes tooltip errors in other addons that also modify the tooltip
This commit is contained in:
@@ -3,3 +3,5 @@
|
|||||||
.idea
|
.idea
|
||||||
NUL
|
NUL
|
||||||
temp
|
temp
|
||||||
|
Tooltip_OG.lua
|
||||||
|
ItemButton_OG.lua
|
||||||
+22
-6
@@ -22,6 +22,8 @@ local QUIET_DELAY = 0.5 -- seconds of silence after a *_CLOSED event before aut
|
|||||||
local running = false
|
local running = false
|
||||||
local silentRun = false
|
local silentRun = false
|
||||||
local pendingToken = 0 -- bumped on every auto-trigger and on LOOT_OPENED to cancel stale timers
|
local pendingToken = 0 -- bumped on every auto-trigger and on LOOT_OPENED to cancel stale timers
|
||||||
|
local waitingForLoot = false
|
||||||
|
local OpenNext -- forward declaration; defined after OnClamLootClosed
|
||||||
|
|
||||||
-- Returns true if any blocking window (loot/mail/trade/merchant/bank/auction)
|
-- Returns true if any blocking window (loot/mail/trade/merchant/bank/auction)
|
||||||
-- is currently open. We don't want to UseContainerItem while these are active --
|
-- is currently open. We don't want to UseContainerItem while these are active --
|
||||||
@@ -65,22 +67,33 @@ end
|
|||||||
local function StopRun(reason)
|
local function StopRun(reason)
|
||||||
if not running then return end
|
if not running then return end
|
||||||
running = false
|
running = false
|
||||||
-- Only drop the per-run UI_ERROR_MESSAGE listener; the persistent auto-
|
|
||||||
-- trigger events stay registered.
|
|
||||||
addon.Modules.Events:UnregisterOwner("ClamOpener_Run")
|
addon.Modules.Events:UnregisterOwner("ClamOpener_Run")
|
||||||
|
addon.Modules.Events:UnregisterOwner("ClamOpener_LootWait")
|
||||||
|
waitingForLoot = false
|
||||||
if reason and not silentRun then
|
if reason and not silentRun then
|
||||||
addon:Print(reason)
|
addon:Print(reason)
|
||||||
end
|
end
|
||||||
silentRun = false
|
silentRun = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function OpenNext()
|
-- waitingForLoot: set between UseContainerItem and the LOOT_CLOSED that confirms
|
||||||
|
-- the clam loot window has fully closed, preventing any concurrent UseContainerItem.
|
||||||
|
local function OnClamLootClosed()
|
||||||
|
-- Unregister this one-shot listener immediately.
|
||||||
|
addon.Modules.Events:UnregisterOwner("ClamOpener_LootWait")
|
||||||
|
waitingForLoot = false
|
||||||
if not running then return end
|
if not running then return end
|
||||||
|
-- Small delay to let the client fully settle before the next open.
|
||||||
|
Guda_ScheduleTimer(OPEN_DELAY, OpenNext)
|
||||||
|
end
|
||||||
|
|
||||||
|
OpenNext = function()
|
||||||
|
if not running then return end
|
||||||
|
if waitingForLoot then return end
|
||||||
|
|
||||||
-- Never use a clam while something else is in-flight: cursor busy,
|
-- Never use a clam while something else is in-flight: cursor busy,
|
||||||
-- a blocking window open, or a server-side loot still active. Any of
|
-- a blocking window open, or a server-side loot still active. Any of
|
||||||
-- these + UseContainerItem races the client loot state machine and
|
-- these + UseContainerItem races the open window or get queued and lost.
|
||||||
-- can soft-lock the loot UI ("too far away" greyed-out items).
|
|
||||||
if CursorHasItem()
|
if CursorHasItem()
|
||||||
or IsBlockingWindowOpen()
|
or IsBlockingWindowOpen()
|
||||||
or (GetNumLootItems and GetNumLootItems() > 0) then
|
or (GetNumLootItems and GetNumLootItems() > 0) then
|
||||||
@@ -94,8 +107,11 @@ local function OpenNext()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Arm the one-shot LOOT_CLOSED listener before calling UseContainerItem
|
||||||
|
-- so we cannot miss the event even if it fires in the same frame.
|
||||||
|
waitingForLoot = true
|
||||||
|
addon.Modules.Events:Register("LOOT_CLOSED", OnClamLootClosed, "ClamOpener_LootWait")
|
||||||
UseContainerItem(bagID, slotID)
|
UseContainerItem(bagID, slotID)
|
||||||
Guda_ScheduleTimer(OPEN_DELAY, OpenNext)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Stop on UI_ERROR_MESSAGE (e.g. inventory full). UseContainerItem fires this
|
-- Stop on UI_ERROR_MESSAGE (e.g. inventory full). UseContainerItem fires this
|
||||||
|
|||||||
+7
-8
@@ -483,15 +483,14 @@ function Tooltip:Initialize()
|
|||||||
local oldSetHyperlink = GameTooltip.SetHyperlink
|
local oldSetHyperlink = GameTooltip.SetHyperlink
|
||||||
function GameTooltip:SetHyperlink(link)
|
function GameTooltip:SetHyperlink(link)
|
||||||
return WithDeferredMoney(self, function()
|
return WithDeferredMoney(self, function()
|
||||||
|
-- The native Blizzard SetHyperlink only accepts a bare "item:ID:e:e:e" string.
|
||||||
|
-- Any addon that captured the native before Guda loaded (e.g. AtlasLoot) will
|
||||||
|
-- call it directly with whatever we pass here, so we MUST strip the color codes
|
||||||
|
-- and |H...|h wrapper before forwarding. Passing the full colored link causes
|
||||||
|
-- "unknown link type" in those addons.
|
||||||
local _, _, inner = string.find(link or "", "|H(.+)|h")
|
local _, _, inner = string.find(link or "", "|H(.+)|h")
|
||||||
local forwarded = link
|
local forwarded = inner or link
|
||||||
local itemLinkForCounts = link
|
local itemLinkForCounts = inner or link
|
||||||
if inner then
|
|
||||||
forwarded = inner
|
|
||||||
if strfind(inner, "^item:") then
|
|
||||||
itemLinkForCounts = inner
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local ret = oldSetHyperlink(self, forwarded)
|
local ret = oldSetHyperlink(self, forwarded)
|
||||||
if itemLinkForCounts and strfind(itemLinkForCounts, "item:") then
|
if itemLinkForCounts and strfind(itemLinkForCounts, "item:") then
|
||||||
Tooltip:AddInventoryInfo(self, itemLinkForCounts)
|
Tooltip:AddInventoryInfo(self, itemLinkForCounts)
|
||||||
|
|||||||
+25
-5
@@ -263,6 +263,19 @@ local function IsInCategoryView(isBank)
|
|||||||
return (addon.Modules.DB:GetSetting(key) or "single") == "category"
|
return (addon.Modules.DB:GetSetting(key) or "single") == "category"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set a tooltip from an item link, passing the BARE "item:ID:e:e:e" form rather
|
||||||
|
-- than the full colored link. The 1.12 native GameTooltip:SetHyperlink only
|
||||||
|
-- accepts the bare form; passing a full |cff..|Hitem:..|h[Name]|h|r link can
|
||||||
|
-- reach a bare-only native further down a re-hooked SetHyperlink chain (e.g. when
|
||||||
|
-- AtlasLoot / WoWTranslate / SuperCleverRoidMacros have re-hooked in an order that
|
||||||
|
-- bypasses Guda's own stripping hook) and throw "unknown link type" in that addon.
|
||||||
|
-- Always route Guda-originated SetHyperlink calls through this helper.
|
||||||
|
local function GudaSetTooltipHyperlink(tooltip, link)
|
||||||
|
if not link then return end
|
||||||
|
local _, _, bare = string.find(link, "|H(item:[^|]+)|h")
|
||||||
|
tooltip:SetHyperlink(bare or link)
|
||||||
|
end
|
||||||
|
|
||||||
-- Auto-clear cursor tracking when cursor is truly empty, and notify BagFrame
|
-- Auto-clear cursor tracking when cursor is truly empty, and notify BagFrame
|
||||||
-- of drag-state transitions. In 1.12 CURSOR_UPDATE is unreliable for item
|
-- of drag-state transitions. In 1.12 CURSOR_UPDATE is unreliable for item
|
||||||
-- pickups, so we also poll CursorHasItem() on a throttled OnUpdate —
|
-- pickups, so we also poll CursorHasItem() on a throttled OnUpdate —
|
||||||
@@ -2449,7 +2462,7 @@ function Guda_ItemButton_OnEnter(self)
|
|||||||
-- Read-only / other character mailbox OR current character mailbox when closed
|
-- Read-only / other character mailbox OR current character mailbox when closed
|
||||||
GameTooltip.GudaViewedCharacter = self.otherChar or currentPlayerName
|
GameTooltip.GudaViewedCharacter = self.otherChar or currentPlayerName
|
||||||
if self.itemData.link then
|
if self.itemData.link then
|
||||||
GameTooltip:SetHyperlink(self.itemData.link)
|
GudaSetTooltipHyperlink(GameTooltip, self.itemData.link)
|
||||||
else
|
else
|
||||||
GameTooltip:SetHyperlink("item:" .. self.itemData.itemID .. ":0:0:0")
|
GameTooltip:SetHyperlink("item:" .. self.itemData.itemID .. ":0:0:0")
|
||||||
end
|
end
|
||||||
@@ -2504,7 +2517,7 @@ function Guda_ItemButton_OnEnter(self)
|
|||||||
elseif self.otherChar or self.isReadOnly then
|
elseif self.otherChar or self.isReadOnly then
|
||||||
GameTooltip.GudaViewedCharacter = self.otherChar
|
GameTooltip.GudaViewedCharacter = self.otherChar
|
||||||
if self.itemData and self.itemData.link then
|
if self.itemData and self.itemData.link then
|
||||||
local ok = pcall(GameTooltip.SetHyperlink, GameTooltip, self.itemData.link)
|
local ok = pcall(GudaSetTooltipHyperlink, GameTooltip, self.itemData.link)
|
||||||
if not ok then
|
if not ok then
|
||||||
GameTooltip:Hide()
|
GameTooltip:Hide()
|
||||||
return
|
return
|
||||||
@@ -2521,13 +2534,20 @@ function Guda_ItemButton_OnEnter(self)
|
|||||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||||
elseif self.itemData and self.itemData.link then
|
elseif self.itemData and self.itemData.link then
|
||||||
-- Bank is closed - use cached link
|
-- Bank is closed - use cached link
|
||||||
GameTooltip:SetHyperlink(self.itemData.link)
|
GudaSetTooltipHyperlink(GameTooltip, self.itemData.link)
|
||||||
end
|
end
|
||||||
elseif self.bagID == -2 then
|
elseif self.bagID == -2 then
|
||||||
-- Keyring: SetBagItem might be unreliable for -2 in some 1.12.1 environments, fallback to hyperlink if needed
|
-- Keyring (bag -2): in 1.12 the native SetBagItem builds the keyring tooltip
|
||||||
|
-- by internally calling SetHyperlink with the FULL colored link
|
||||||
|
-- (|cff..|Hitem:..|h[Name]|h|r). When other addons (AtlasLoot, WoWTranslate)
|
||||||
|
-- have re-hooked SetHyperlink in an order that bypasses Guda's stripping, that
|
||||||
|
-- full link reaches a hook whose captured original is the raw Blizzard
|
||||||
|
-- SetHyperlink — which only accepts the BARE "item:ID:0:0:0" form and otherwise
|
||||||
|
-- throws "unknown link type". We avoid that internal path entirely by calling
|
||||||
|
-- SetHyperlink ourselves with the bare form (GudaSetTooltipHyperlink extracts it).
|
||||||
local link = GetContainerItemLink(self.bagID, self.slotID)
|
local link = GetContainerItemLink(self.bagID, self.slotID)
|
||||||
if link then
|
if link then
|
||||||
GameTooltip:SetHyperlink(link)
|
GudaSetTooltipHyperlink(GameTooltip, link)
|
||||||
else
|
else
|
||||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user