feat+fix(blizzskin): skin the BNet friend online/offline toast and fix a taint issue - #1915
Merged
EllesmereGaming merged 2 commits intoSep 2, 2026
Conversation
BNToastFrame was the last visible popup with no EUI skin, still carrying its
gold BACKDROP_TOAST_12_12 frame and Blizzard's font while every comparable
element (loot toasts, loot rolls, group invites, ready check) already runs
through the window skin engine.
New window pack "bnettoast", wired the usual six ways: enable key
reskinBNetToast, its own style-seed batch so existing accounts inherit their
majority style, an options card under Blizzard Window Skins, a reset entry and
the profile allowlist. Chrome only: shell, border, close button, house font on
the four text lines, house panel on the broadcast tooltip. The toast-type icon
stays native, since it is a SetTexCoord crop out of one sheet that
WSkin.SquareIcon would overwrite, and the flair glow is cleared rather than
alpha'd because it carries its own alpha animation.
WSkin.Shell no longer hooks SetSize/SetWidth/SetHeight with hooksecurefunc.
That form is a field write onto a Blizzard frame whose field Blizzard reads
back, and BNToastMixin:ShowToast calls SetHeight in the very chain whose
OnClick opens a Battle.net whisper - the hazard EllesmereUIChat already
documents for SetPoint on this frame. A HookScript("OnSizeChanged") replaces
all three, which also covers anchor-driven resizes the setter hooks never saw.
The Character Sheet, Inspect Sheet and Group Finder build their own shell and adopt it through WSkin.AdoptShell rather than going through WSkin.Shell, so the window engine's conversion did not reach the copy of UpdateBgTexCoords each of them carries. All three still hooked SetSize/SetWidth/SetHeight with hooksecurefunc, which is the field write onto a Blizzard frame the engine just stopped doing. PVEFrame is the most taint-sensitive of the three. The same three copies were also missing the engine's secrecy test, and the zero check they run instead is itself a comparison that throws on a secret size. Switching to OnSizeChanged widens when that function runs, so the guard is added here rather than left for later.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a Blizzard window skin for the Battle.net toast -- the popup that appears when a friend comes online or goes offline, and for broadcasts and club invites. It was the last visible popup with no EllesmereUI skin, still carrying its gold
BACKDROP_TOAST_12_12frame and Blizzard's default font while every comparable element (loot toasts, loot rolls, group invites, ready check) already runs through the window skin engine.It appears as a new "Friend Notifications" card under Blizz UI Enhanced > Blizzard Window Skins with the usual EllesmereUI / Modern / Blizz Default choice. Existing accounts do not simply get it switched on: a new style-seed batch gives the toast whichever style the user already runs most of their windows with, "off" included.
The skin is chrome only -- house shell and border in place of the backdrop, house close button, the UI font on the four text lines, and a house panel on the hover tooltip that a truncated broadcast shows. Text colors stay Blizzard's, since
ShowToastsets them per toast type. The toast-type icon is left native: it is aSetTexCoordcrop out of one sheet, re-picked per type, so squaring it would overwrite those coordinates. The flair glow is cleared rather than alpha'd out, because it carries its own alpha animation that would otherwise animate straight over the write. Position is untouched and stays with the existing Unlock Mode element in the chat module.Also in this PR: a taint fix that reaches every skinned window
WSkin.Shellkept its backdrop crop current withhooksecurefunc(frame, "SetSize"/"SetWidth"/"SetHeight", ...), which assigns a wrapper onto the Blizzard frame's own table -- a field write that Blizzard then reads back from its own code, against the rule the window engine's own header states. That is not academic for this window:BNToastMixin:ShowToastcallsSetHeightimmediately before showing the alert, andBNToastMixin:OnClickrunsChatFrameUtil.SendBNetTell(accountInfo.accountName)-- the same chain, with a secret string in it. It is the hazard the chat module already documents forSetPointon this very frame.All three hooks are replaced by one
HookScript("OnSizeChanged"), which is C-side and writes nothing, and which additionally fires for anchor-driven resizes the setter hooks never saw. The Character Sheet, Inspect Sheet and Group Finder carry their own copy of that shell code and adopt it viaWSkin.AdoptShell, so they are converted in the same way -- PVEFrame being the most taint-sensitive of the three. Those three copies were also missing the engine'sissecretvaluetest, and the zero check they run instead is itself a comparison that throws on a secret size; since the switch widens when that function runs, the guard is added there too. After this, no shell code hooks a Blizzard frame's size setters.How was it tested?
Tested in game on live.
Screenshots
Checklist
HookScript/hooksecurefunconly, neverSetScripton Blizzard frames