Fix fullscreen not working when player window is pinned on macOS

A pinned window carries .fullScreenAuxiliary, which AppKit refuses to
make a primary fullscreen window, so toggleFullScreen was a silent
no-op. Drop the floating config before entering fullscreen and restore
it in windowDidExitFullScreen, keeping the pin setting intact.
This commit is contained in:
Arkadiusz Fal
2026-06-08 22:33:01 +02:00
parent a0a6634d1c
commit 0fa4df161b
2 changed files with 32 additions and 2 deletions

View File

@@ -1571,8 +1571,9 @@ extension ExpandedPlayerSheet {
playerService.seekBackward(by: seconds)
},
onToggleFullscreen: {
// Toggle native macOS fullscreen
NSApp.keyWindow?.toggleFullScreen(nil)
// Toggle native macOS fullscreen (drops the floating
// config first so a pinned window can enter fullscreen)
ExpandedPlayerWindowManager.shared.toggleFullScreen()
},
isFullscreen: NSApp.keyWindow?.styleMask.contains(.fullScreen) == true,
onClose: { [self] in

View File

@@ -246,9 +246,28 @@ final class ExpandedPlayerWindowManager: NSObject {
/// Call this when the user changes the player mode setting.
func updateWindowLevel(floating: Bool) {
guard let window = playerWindow else { return }
// Don't touch level/collectionBehavior mid-fullscreen; the setting is
// re-read in windowDidExitFullScreen.
guard !window.styleMask.contains(.fullScreen) else { return }
configureWindowLevel(window, floating: floating)
}
/// Toggles native fullscreen on the player window.
func toggleFullScreen() {
guard let window = playerWindow else {
// Inline-sheet presentation: fullscreen the main app window
NSApp.keyWindow?.toggleFullScreen(nil)
return
}
// A floating (pinned) window carries .fullScreenAuxiliary, which AppKit
// refuses to make a primary fullscreen window. Switch to the primary
// config for the transition; windowDidExitFullScreen restores floating.
if !window.styleMask.contains(.fullScreen) {
configureWindowLevel(window, floating: false)
}
window.toggleFullScreen(nil)
}
/// Restores a window that was hidden for PiP mode.
/// Call this when returning from PiP to show the player window again.
func restoreFromPiP(animated: Bool = true) {
@@ -497,6 +516,16 @@ extension ExpandedPlayerWindowManager: NSWindowDelegate {
// Return false - we've already hidden the window with orderOut
return false
}
nonisolated func windowDidExitFullScreen(_ notification: Notification) {
MainActor.assumeIsolated {
guard let window = playerWindow else { return }
// Restore the pinned (floating) config that toggleFullScreen
// dropped so the window could enter primary fullscreen.
let floating = appEnvironment?.settingsManager.macPlayerFloating ?? false
configureWindowLevel(window, floating: floating)
}
}
}
// MARK: - Two-Phase Window Root