Fix macOS corner layout window resize and re-lock the aspect ratio when panels hide

Entering the corner layout cleared the window's aspect-ratio lock by setting
contentAspectRatio to zero. That doesn't remove the constraint: AppKit keeps
its aspect-ratio resize handler active with a degenerate 0:0 ratio, so every
interactive resize resolved to the current size and the window couldn't be
resized at all. Reset contentResizeIncrements to 1x1 instead, the supported
way back to free resizing (aspect ratio and resize increments are mutually
exclusive).

Free resize now also requires the corner panels to be visible. With the
panels hidden only the video remains, so the window follows the ratio lock
(and auto-fit, when on) exactly like the stacked layout. The new
AppEnvironment.isCornerPanelLayoutActive gate covers the layout-change
handler, window creation, and the fullscreen-exit replay.
This commit is contained in:
Arkadiusz Fal
2026-09-28 20:19:10 +02:00
parent 14fe028ece
commit 99692a3554
2 changed files with 39 additions and 13 deletions

View File

@@ -176,9 +176,10 @@ final class ExpandedPlayerWindowManager: NSObject {
// Lock manual resize to the video aspect ratio. Seeded with the real ratio
// when known (else 16:9); updated as soon as the real ratio is known.
// Corner layout (already active on a window re-mount, e.g. switching
// from the inline overlay) keeps the window unconstrained.
if appEnvironment.navigationCoordinator.isCornerLayoutActive != true {
// Corner layout with its panels visible (already active on a window
// re-mount, e.g. switching from the inline overlay) keeps the window
// unconstrained.
if !appEnvironment.isCornerPanelLayoutActive {
Self.applyAspectRatioConstraint(seedAspect, to: window)
}
@@ -599,8 +600,17 @@ final class ExpandedPlayerWindowManager: NSObject {
func unlockAspectRatio() {
guard let window = playerWindow else { return }
pendingFullScreenAspectRatio = nil
window.contentAspectRatio = .zero
LoggingService.shared.debug("unlockAspectRatio (corner layout)", category: .player)
// `aspectRatio` and `resizeIncrements` are mutually exclusive: setting
// one resets the other. Assigning a zero aspect ratio does NOT clear the
// lock — it leaves AppKit's aspect handler active with a degenerate 0:0
// ratio, which makes interactive resize a no-op (the window can't be
// resized at all). Resetting the increments to 1×1 is the supported way
// to return to free resizing.
window.contentResizeIncrements = NSSize(width: 1, height: 1)
LoggingService.shared.debug(
"unlockAspectRatio (corner layout) aspect=\(window.contentAspectRatio) increments=\(window.contentResizeIncrements)",
category: .player
)
}
// MARK: - Private Helpers
@@ -828,8 +838,8 @@ extension ExpandedPlayerWindowManager: NSWindowDelegate {
// exactly what the aspect-change handler would have done windowed.
if let ratio = pendingFullScreenAspectRatio {
pendingFullScreenAspectRatio = nil
// Corner layout keeps the window unconstrained.
guard appEnvironment?.navigationCoordinator.isCornerLayoutActive != true else { return }
// Corner layout with visible panels keeps the window unconstrained.
guard appEnvironment?.isCornerPanelLayoutActive != true else { return }
Self.applyAspectRatioConstraint(ratio, to: window)
if appEnvironment?.settingsManager.playerSheetAutoResize == true {
resizeToFitAspectRatio(ratio, animated: false)
@@ -839,6 +849,19 @@ extension ExpandedPlayerWindowManager: NSWindowDelegate {
}
}
// MARK: - Free-Resize Gate
extension AppEnvironment {
/// Whether the player window should resize freely instead of following
/// the video aspect ratio: the corner layout is resolved AND its panel
/// regions are shown, so the window frames video plus panels. Hiding the
/// panels in corner mode leaves only the video, which follows the ratio
/// lock (and auto-fit) exactly like the stacked layout.
var isCornerPanelLayoutActive: Bool {
navigationCoordinator.isCornerLayoutActive && settingsManager.landscapeDetailsPanelVisible
}
}
// MARK: - Two-Phase Window Root
/// Root view hosted in the expanded player window.