From 1d9d71347698e28d8dfeea54b067704d4e5ba2e3 Mon Sep 17 00:00:00 2001 From: Relationship <139162359+Relationship-OctoWoW@users.noreply.github.com> Date: Sun, 12 Jul 2026 12:44:17 +0100 Subject: [PATCH] Add files via upload --- RelationshipsPVP.lua | 79 +++++++++++++++++++++++++++++++------------- RelationshipsPVP.toc | 2 +- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/RelationshipsPVP.lua b/RelationshipsPVP.lua index 344d63f..44e8334 100644 --- a/RelationshipsPVP.lua +++ b/RelationshipsPVP.lua @@ -380,41 +380,71 @@ end --------------------------------------------------------------- -- Auto-close the Blizzard PvP panels if they pop up as a side effect -- of the arena / BG queueing calls. +-- NOTE: We deliberately do NOT call HideUIPanel() here. HideUIPanel on a +-- frame that Blizzard's UI panel system has slotted into a left/center +-- slot triggers a slot reflow, which is what caused Character / Friends / +-- Spellbook panels to jump to the middle of the screen after the PvP +-- panel was opened. Directly calling :Hide() bypasses the slot manager +-- entirely; the slot suppression below (SuppressUIPanelWindows) ensures +-- Blizzard never registered a slot for these frames to begin with. local function HidePvPPanels() - if BattlefieldFrame and BattlefieldFrame:IsVisible() then HideUIPanel(BattlefieldFrame) end - if PVPBattlegroundFrame and PVPBattlegroundFrame:IsVisible() then HideUIPanel(PVPBattlegroundFrame) end - if PVPFrame and PVPFrame:IsVisible() then HideUIPanel(PVPFrame) end - if HonorFrame and HonorFrame:IsVisible() then HideUIPanel(HonorFrame) end + if BattlefieldFrame and BattlefieldFrame:IsVisible() then BattlefieldFrame:Hide() end + if PVPBattlegroundFrame and PVPBattlegroundFrame:IsVisible() then PVPBattlegroundFrame:Hide() end + if PVPFrame and PVPFrame:IsVisible() then PVPFrame:Hide() end + if HonorFrame and HonorFrame:IsVisible() then HonorFrame:Hide() end end -- Suppress the PvP panel entirely while we are auto-queueing. Reference-counted -- so nested queues (Queue All BGs) do not release too early. +-- +-- IMPORTANT: We previously hijacked BattlefieldFrame.Show / PVPBattlegroundFrame.Show +-- to no-op during suppression. That was the source of the "Character / Friends +-- panels jump to the middle of the screen" bug: Blizzard's ShowUIPanel() first +-- allocates a UI panel slot (left / center / doublewide) via UIPanelWindows, +-- THEN calls frame:Show(). Silently dropping :Show() left the slot reserved by +-- an invisible frame, so the next panel the user opened (Character, Friends, +-- Spellbook, ...) got shoved into a different slot -> centered. +-- +-- The correct approach on 1.12 is to temporarily remove these frames from +-- UIPanelWindows while suppressing, so ShowUIPanel treats them as plain +-- frames and never allocates a slot. When suppression ends, the original +-- UIPanelWindows entries are restored so normal Blizzard UI behaviour is +-- preserved for the rest of the session. local suppressPanels = 0 -local suppressHooked = false -local origBattlefieldShow, origPVPBGShow +local savedUIPanelEntries = nil -local function InstallPanelSuppressor() - if suppressHooked then return end - suppressHooked = true - if BattlefieldFrame then - origBattlefieldShow = BattlefieldFrame.Show - BattlefieldFrame.Show = function(self, ...) - if suppressPanels > 0 then return end - origBattlefieldShow(self) - end - end - if PVPBattlegroundFrame then - origPVPBGShow = PVPBattlegroundFrame.Show - PVPBattlegroundFrame.Show = function(self, ...) - if suppressPanels > 0 then return end - origPVPBGShow(self) - end +local SUPPRESSED_PANEL_NAMES = { + "BattlefieldFrame", + "PVPBattlegroundFrame", + "PVPFrame", + "HonorFrame", +} + +local function SuppressUIPanelWindows() + if savedUIPanelEntries then return end + savedUIPanelEntries = {} + if type(UIPanelWindows) ~= "table" then return end + for i = 1, table.getn(SUPPRESSED_PANEL_NAMES) do + local name = SUPPRESSED_PANEL_NAMES[i] + savedUIPanelEntries[name] = UIPanelWindows[name] + UIPanelWindows[name] = nil end end +local function RestoreUIPanelWindows() + if not savedUIPanelEntries then return end + if type(UIPanelWindows) == "table" then + for i = 1, table.getn(SUPPRESSED_PANEL_NAMES) do + local name = SUPPRESSED_PANEL_NAMES[i] + UIPanelWindows[name] = savedUIPanelEntries[name] + end + end + savedUIPanelEntries = nil +end + local function BeginSuppress() - InstallPanelSuppressor() suppressPanels = suppressPanels + 1 + SuppressUIPanelWindows() HidePvPPanels() end @@ -422,6 +452,9 @@ local function EndSuppress() suppressPanels = suppressPanels - 1 if suppressPanels < 0 then suppressPanels = 0 end HidePvPPanels() + if suppressPanels == 0 then + RestoreUIPanelWindows() + end end -- Central pending-queue state. `pendingQueue` is a FIFO of items: diff --git a/RelationshipsPVP.toc b/RelationshipsPVP.toc index e49792d..5c48fd8 100644 --- a/RelationshipsPVP.toc +++ b/RelationshipsPVP.toc @@ -2,7 +2,7 @@ ## Title: Relationships PVP ## Notes: PvP panel with per-battleground and per-arena stats, marks, kills/deaths, honor, K/D, and queue controls. Supports the Battleground Finder and Arena on OctoWoW. ## Author: Relationship -## Version: 1.1 +## Version: 1.2 ## SavedVariablesPerCharacter: RelationshipsPVPCharDB RelationshipsPVP.xml