Kill first-render flicker on Talent/Vanity Blizzard-frame skins
The 0.5s ScheduleRepeatingTimer poll that caught these frames couldn't catch them before their first-ever :Show() this session, since they're created on-demand the instant the player opens them -- native art got one frame of paint before the poll's next tick could skin it. Switched to a generic ADDON_LOADED listener instead: it fires synchronously (before control returns to whatever opens the frame) the moment the owning addon finishes loading, so skinning now lands before the frame is ever shown. Confirmed in-game via an ADDON_LOADED probe on the talent frame's addon before implementing. Also fixes a regression this introduced: TalentFrame's CropBackground was caching the background texture's "original" tex coords on its first-ever call for later crop math. That first call now happens pre-Show, before Blizzard's own code sets the texture's real art-tile region, so it was permanently baking in the XML-template default (full 0..1) as the baseline. Moved the crop to run only from OnShow, where the real coords are already set.
This commit is contained in:
+17
-5
@@ -851,7 +851,12 @@ local function SkinFrame(frame)
|
||||
|
||||
SkinCloseButton(frame)
|
||||
SkinBottomBar()
|
||||
CropBackground()
|
||||
-- Not CropBackground() here: this runs pre-Show now (see InitializeTalentFrame),
|
||||
-- before Blizzard's own code sets the background texture's real art-tile
|
||||
-- coords -- it's still XML-template default (full 0..1) at this point. Crop
|
||||
-- caches "original" coords on first call and never recaptures, so cropping
|
||||
-- here would permanently bake in the wrong baseline. OnShow (below) is the
|
||||
-- only place this is safe to run.
|
||||
SkinChildren(frame, 1)
|
||||
SkinTabs()
|
||||
SkinSpecChoices()
|
||||
@@ -870,10 +875,17 @@ function CoA:InitializeTalentFrame()
|
||||
if not E.private.skins.blizzard.enable then return end
|
||||
if TryHook() then return end
|
||||
|
||||
self.talentFrameTimer = self:ScheduleRepeatingTimer(function()
|
||||
-- Frame is created on-demand by its owning addon (e.g. Ascension_CoATalents),
|
||||
-- the instant the player first opens it -- a poll can't catch that before the
|
||||
-- native art gets a paint. ADDON_LOADED fires (synchronously, before control
|
||||
-- returns to whatever code calls :Show()) the moment that addon finishes
|
||||
-- loading, so skinning here lands before the first-ever :Show(), killing the
|
||||
-- one-frame flicker a poll-based catch can't avoid. Confirmed in-game.
|
||||
local loader = CreateFrame("Frame")
|
||||
loader:RegisterEvent("ADDON_LOADED")
|
||||
loader:SetScript("OnEvent", function(self)
|
||||
if TryHook() then
|
||||
self:CancelTimer(self.talentFrameTimer)
|
||||
self.talentFrameTimer = nil
|
||||
self:UnregisterEvent("ADDON_LOADED")
|
||||
end
|
||||
end, 0.5)
|
||||
end)
|
||||
end
|
||||
|
||||
+11
-4
@@ -163,10 +163,17 @@ function CoA:InitializeVanityFrame()
|
||||
if not E.private.skins.blizzard.enable then return end
|
||||
if TryHook() then return end
|
||||
|
||||
self.vanityFrameTimer = self:ScheduleRepeatingTimer(function()
|
||||
-- Frame is created on-demand by its owning addon, the instant the player
|
||||
-- first opens it -- a poll can't catch that before native art gets a
|
||||
-- paint. ADDON_LOADED fires (synchronously, before control returns to
|
||||
-- whatever code calls :Show()) the moment that addon finishes loading, so
|
||||
-- skinning here lands before the first-ever :Show(). Confirmed in-game on
|
||||
-- the talent frame's identical pattern; see TalentFrame.lua.
|
||||
local loader = CreateFrame("Frame")
|
||||
loader:RegisterEvent("ADDON_LOADED")
|
||||
loader:SetScript("OnEvent", function(self)
|
||||
if TryHook() then
|
||||
self:CancelTimer(self.vanityFrameTimer)
|
||||
self.vanityFrameTimer = nil
|
||||
self:UnregisterEvent("ADDON_LOADED")
|
||||
end
|
||||
end, 0.5)
|
||||
end)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user