From 420a8121c0e5a35950366638b857df3866c27465 Mon Sep 17 00:00:00 2001 From: der richter Date: Sun, 19 Oct 2025 13:51:11 +0200 Subject: [PATCH] mac/common: fix window position on multi monitor setups on multi monitor setups the position of the window was wrongly computed when the position was forced, eg the calculated rectangle was screen relative but the function expected absolute coordinates. this is a regression from 50042f5ee094a36e38f9ea809408e0b5cbf3b874 and #15500, where support for --force-window-position was introduced. this worked in simple one monitor setups and in some cases on multi monitor setups by sheer coincidence. calculate the absolute position of the window by taking the screen into account when needed. Fixes #16929 --- video/out/mac/window.swift | 22 ++++++++++++++-------- video/out/mac_common.swift | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/video/out/mac/window.swift b/video/out/mac/window.swift index 537502031fdeb..50cd2d0eaa685 100644 --- a/video/out/mac/window.swift +++ b/video/out/mac/window.swift @@ -78,13 +78,11 @@ class Window: NSWindow, NSWindowDelegate { // workaround for an AppKit bug where the NSWindow can't be placed on a // none Main screen NSScreen outside the Main screen's frame bounds - if let wantedScreen = screen, screen != NSScreen.main { - var absoluteWantedOrigin = contentRect.origin - absoluteWantedOrigin.x += wantedScreen.frame.origin.x - absoluteWantedOrigin.y += wantedScreen.frame.origin.y + if screen != NSScreen.main { + let absolutePos = absolutePosition(for: contentRect, screen: screen) - if absoluteWantedOrigin != self.frame.origin { - self.setFrameOrigin(absoluteWantedOrigin) + if absolutePos.origin != self.frame.origin { + self.setFrameOrigin(absolutePos.origin) } } @@ -342,11 +340,11 @@ class Window: NSWindow, NSWindowDelegate { } } - func updateFrame(_ rect: NSRect) { + func updateFrame(_ rect: NSRect, _ screen: NSScreen? = nil) { if rect != frame { unfsContentFrame = rect if !isInFullscreen { - let cRect = frameRect(forContentRect: rect) + let cRect = absolutePosition(for: frameRect(forContentRect: rect), screen: screen) setFrame(cRect, display: true) common.windowDidUpdateFrame() } @@ -371,6 +369,14 @@ class Window: NSWindow, NSWindowDelegate { if keepAspect { contentAspectRatio = unfsContentFrame.size } } + func absolutePosition(for rect: NSRect, screen: NSScreen?) -> NSRect { + guard let tScreen = screen else { return rect } + var absolutePosition = rect + absolutePosition.origin.x += tScreen.frame.origin.x + absolutePosition.origin.y += tScreen.frame.origin.y + return absolutePosition + } + func centeredContentSize(for rect: NSRect, size sz: NSSize) -> NSRect { let cRect = contentRect(forFrameRect: rect) let dx = (cRect.size.width - sz.width) / 2 diff --git a/video/out/mac_common.swift b/video/out/mac_common.swift index ad9f01cdb4b7f..45f922d4380e6 100644 --- a/video/out/mac_common.swift +++ b/video/out/mac_common.swift @@ -47,7 +47,7 @@ class MacCommon: Common { let previousActiveApp = getActiveApp() initApp() - let (_, wr, forcePosition) = getInitProperties(vo) + let (screen, wr, forcePosition) = getInitProperties(vo) guard let layer = self.layer else { log.error("Something went wrong, no MetalLayer was initialized") exit(1) @@ -60,7 +60,7 @@ class MacCommon: Common { } if forcePosition { - window?.updateFrame(wr) + window?.updateFrame(wr, screen) } else if option.vo.auto_window_resize { window?.updateSize(wr.size) }