From 225412405323f8407df877bf3598fecffa3fa530 Mon Sep 17 00:00:00 2001 From: Dmytro Kharchenko Date: Tue, 1 Sep 2026 05:42:31 +0000 Subject: [PATCH] Lay every frame group out ahead of a first in-combat show Solo/party/raid frames only applied their layout while the player was in that group type. Since F.UpdateLayout defers itself until combat ends, a frame group that had never been active since login - most commonly the party frame after a reload - was shown by its visibility driver with no sizes, anchors or header attributes when the group changed in combat, and stayed blank until combat ended. Once it had been laid out once, the same in-combat change worked, which is why this only reproduced the first time. Each frame group now lays itself out for the layout its own layoutAutoSwitch entry names (F.GetGroupTypeLayout) whenever it is not the active group type: full updates use that layout, partial updates from the Layouts tab apply when the edited layout is that one. The raid frame's combineGroups check reads the layout being applied instead of the current one. Picking a different layout for a non-active group type in the autoswitch dropdowns re-lays that frame group out right away. Classic only, like the visibility-driver change it builds on: the Retail branch of the group frames keeps its old behavior and never reaches this. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011YngV4VgYFwrPdgvWYVz7p --- Core_Cata.lua | 9 +++++++++ Core_Mists.lua | 9 +++++++++ Core_Vanilla.lua | 9 +++++++++ Core_Wrath.lua | 9 +++++++++ Modules/Layouts/Layouts.lua | 4 ++++ RaidFrames/Groups/PartyFrame.lua | 15 ++++++++++++++- RaidFrames/Groups/RaidFrame.lua | 22 ++++++++++++++++++---- RaidFrames/Groups/SoloFrame.lua | 15 ++++++++++++++- 8 files changed, 86 insertions(+), 6 deletions(-) diff --git a/Core_Cata.lua b/Core_Cata.lua index efa81a56..0ae7f9c6 100644 --- a/Core_Cata.lua +++ b/Core_Cata.lua @@ -192,6 +192,15 @@ function F.IsGroupTypeHidden(layoutGroupType) return layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] == "hide" end +--! The layout a frame group has to be laid out for, from the same mapping: nil when that entry is "hide" +--! (or unknown), so a frame group can lay itself out ahead of time for a group type the player is not in. +function F.GetGroupTypeLayout(layoutGroupType) + local layout = layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] + if layout and layout ~= "hide" and CellDB["layouts"][layout] then + return layout + end +end + local bgMaxPlayers = { [2197] = 40, -- 科尔拉克的复仇 } diff --git a/Core_Mists.lua b/Core_Mists.lua index 4a91d8d1..a9b9d70e 100644 --- a/Core_Mists.lua +++ b/Core_Mists.lua @@ -212,6 +212,15 @@ function F.IsGroupTypeHidden(layoutGroupType) return layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] == "hide" end +--! The layout a frame group has to be laid out for, from the same mapping: nil when that entry is "hide" +--! (or unknown), so a frame group can lay itself out ahead of time for a group type the player is not in. +function F.GetGroupTypeLayout(layoutGroupType) + local layout = layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] + if layout and layout ~= "hide" and CellDB["layouts"][layout] then + return layout + end +end + local bgMaxPlayers = { [2197] = 40, -- 科尔拉克的复仇 } diff --git a/Core_Vanilla.lua b/Core_Vanilla.lua index 9290bd8b..b7c6aaef 100644 --- a/Core_Vanilla.lua +++ b/Core_Vanilla.lua @@ -197,6 +197,15 @@ function F.IsGroupTypeHidden(layoutGroupType) return layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] == "hide" end +--! The layout a frame group has to be laid out for, from the same mapping: nil when that entry is "hide" +--! (or unknown), so a frame group can lay itself out ahead of time for a group type the player is not in. +function F.GetGroupTypeLayout(layoutGroupType) + local layout = layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] + if layout and layout ~= "hide" and CellDB["layouts"][layout] then + return layout + end +end + -- layout auto switch local instanceType local function PreUpdateLayout() diff --git a/Core_Wrath.lua b/Core_Wrath.lua index c4b3b949..3d884b51 100644 --- a/Core_Wrath.lua +++ b/Core_Wrath.lua @@ -192,6 +192,15 @@ function F.IsGroupTypeHidden(layoutGroupType) return layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] == "hide" end +--! The layout a frame group has to be laid out for, from the same mapping: nil when that entry is "hide" +--! (or unknown), so a frame group can lay itself out ahead of time for a group type the player is not in. +function F.GetGroupTypeLayout(layoutGroupType) + local layout = layoutGroupType and Cell.vars.layoutAutoSwitch and Cell.vars.layoutAutoSwitch[layoutGroupType] + if layout and layout ~= "hide" and CellDB["layouts"][layout] then + return layout + end +end + local bgMaxPlayers = { [2197] = 40, -- 科尔拉克的复仇 } diff --git a/Modules/Layouts/Layouts.lua b/Modules/Layouts/Layouts.lua index cb007610..a60b931a 100644 --- a/Modules/Layouts/Layouts.lua +++ b/Modules/Layouts/Layouts.lua @@ -1831,6 +1831,10 @@ local function GetDropdownItems(indices, groupType) -- LoadLayoutDB(Cell.vars.currentLayout) UpdateButtonStates() -- UpdateEnabledLayoutText() + elseif Cell.vars.layoutGroupType then + --! frame groups are laid out ahead of time for the group types the player is not in + --! (see F.GetGroupTypeLayout), so let them pick up the new assignment + F.UpdateLayout(Cell.vars.layoutGroupType, true) end end, }) diff --git a/RaidFrames/Groups/PartyFrame.lua b/RaidFrames/Groups/PartyFrame.lua index 66646fcf..1801fe2a 100644 --- a/RaidFrames/Groups/PartyFrame.lua +++ b/RaidFrames/Groups/PartyFrame.lua @@ -116,7 +116,20 @@ local function PartyFrame_UpdateLayout(layout, which) RegisterAttributeDriver(partyFrame, "state-visibility", "[@raid1,exists] hide;[@party1,exists] show;[group:party] show;hide") end - if Cell.vars.groupType ~= "party" then return end + -- Layout: applied for every frame group, not only the active one, so that the first show of a group + -- type since login can happen in combat. F.UpdateLayout defers itself until combat ends, so a party frame + -- that had never been active came up with no sizes, anchors or header attributes when the group changed + -- in combat, and stayed blank until combat ended. See F.GetGroupTypeLayout. + if Cell.vars.groupType ~= "party" then + local ownLayout = F.GetGroupTypeLayout(Cell.vars.partyLayoutGroupType) + if not ownLayout then return end + if which then + -- partial update from the Layouts tab: only relevant when the edited layout is the one used here + if layout ~= ownLayout then return end + else + layout = ownLayout + end + end end -- update diff --git a/RaidFrames/Groups/RaidFrame.lua b/RaidFrames/Groups/RaidFrame.lua index 3bfcab2a..3aab04d0 100644 --- a/RaidFrames/Groups/RaidFrame.lua +++ b/RaidFrames/Groups/RaidFrame.lua @@ -279,8 +279,9 @@ function F.GetRaidFramePoints(layout) return point, anchorPoint, groupAnchorPoint, P.Scale(unitSpacing), P.Scale(groupSpacing), P.Scale(unitSpacingX), P.Scale(unitSpacingY), verticalSpacing, horizontalSpacing, headerPoint, headerColumnAnchorPoint end -local function UpdateHeadersShowRaidAttribute() - if Cell.vars.currentLayoutTable["main"]["combineGroups"] then +local function UpdateHeadersShowRaidAttribute(layout) + -- NOTE: layout table passed in, the raid frame can be laid out for a layout that is not the current one + if layout["main"]["combineGroups"] then combinedHeader:SetAttribute("showRaid", true) for _, header in ipairs(separatedHeaders) do header:SetAttribute("showRaid", nil) @@ -366,7 +367,20 @@ local function RaidFrame_UpdateLayout(layout, which) RegisterAttributeDriver(raidFrame, "state-visibility", "[@raid1,exists] show;hide") end - if Cell.vars.groupType ~= "raid" then return end + -- Layout: applied for every frame group, not only the active one, so that the first show of a group + -- type since login can happen in combat. F.UpdateLayout defers itself until combat ends, so a raid frame + -- that had never been active came up with no sizes, anchors or header attributes when the group changed + -- in combat, and stayed blank until combat ended. See F.GetGroupTypeLayout. + if Cell.vars.groupType ~= "raid" then + local ownLayout = F.GetGroupTypeLayout(Cell.vars.raidLayoutGroupType) + if not ownLayout then return end + if which then + -- partial update from the Layouts tab: only relevant when the edited layout is the one used here + if layout ~= ownLayout then return end + else + layout = ownLayout + end + end end -- update @@ -414,7 +428,7 @@ local function RaidFrame_UpdateLayout(layout, which) end if not which or which == "header" then - UpdateHeadersShowRaidAttribute() + UpdateHeadersShowRaidAttribute(layout) end if layout["main"]["combineGroups"] then diff --git a/RaidFrames/Groups/SoloFrame.lua b/RaidFrames/Groups/SoloFrame.lua index 4d3e8a6e..c0a7f730 100644 --- a/RaidFrames/Groups/SoloFrame.lua +++ b/RaidFrames/Groups/SoloFrame.lua @@ -44,7 +44,20 @@ local function SoloFrame_UpdateLayout(layout, which) RegisterAttributeDriver(soloFrame, "state-visibility", "[@raid1,exists] hide;[@party1,exists] hide;[group] hide;show") end - if Cell.vars.groupType ~= "solo" then return end + -- Layout: applied for every frame group, not only the active one, so that the first show of a group + -- type since login can happen in combat. F.UpdateLayout defers itself until combat ends, so a solo frame + -- that had never been active came up with no sizes, anchors or header attributes when the group changed + -- in combat, and stayed blank until combat ended. See F.GetGroupTypeLayout. + if Cell.vars.groupType ~= "solo" then + local ownLayout = F.GetGroupTypeLayout(Cell.vars.soloLayoutGroupType) + if not ownLayout then return end + if which then + -- partial update from the Layouts tab: only relevant when the edited layout is the one used here + if layout ~= ownLayout then return end + else + layout = ownLayout + end + end end -- update