Resize macOS player sheet to match video aspect ratio

In sheet (inline) mode the expanded player kept a fixed size and never
reacted to the video's aspect ratio, unlike window/floating mode. Drive
the sheet's backing NSWindow size from the video aspect ratio, reusing
the same sizing math as the standalone window.

- Extract shared sizing into ExpandedPlayerWindowManager.fittedPlayerSize
  and add fittedSheetSize for the sheet path.
- Add SheetWindowResizer (NSViewRepresentable) + .sheetWindowSize modifier
  that resizes the hosting sheet window, since .presentationSizing(.fitted)
  only fits once at presentation.
- Let the sheet content fill the window and paint the window background
  black so animated resizes stay gap-free with no white bars.
This commit is contained in:
Arkadiusz Fal
2026-05-23 13:17:28 +02:00
parent 86f9ef56b3
commit c245a0e2a0
2 changed files with 124 additions and 14 deletions

View File

@@ -93,9 +93,18 @@ struct ContentView: View {
},
set: { appEnvironment.navigationCoordinator.isPlayerExpanded = $0 }
)) {
let size = expandedSheetSize(appEnvironment: appEnvironment)
ExpandedPlayerSheet()
.frame(minWidth: 640, minHeight: 480)
// Only a floor the content fills the sheet window so it tracks
// the window's animated resize with no gap. Do NOT pin an exact
// size here: a fixed frame snaps instantly while the window
// animates, exposing the window background as bars.
.frame(minWidth: 640, minHeight: 360)
.presentationSizing(.fitted)
// `.presentationSizing(.fitted)` only fits the sheet once, at
// presentation. Resize the backing window directly when the
// aspect-ratio-derived size changes so the sheet tracks the video.
.sheetWindowSize(size)
}
#elseif os(tvOS)
.fullScreenCover(isPresented: Binding(
@@ -111,6 +120,22 @@ struct ContentView: View {
private func presentExpandedPlayerWindow(appEnvironment: AppEnvironment) {
ExpandedPlayerWindowManager.shared.show(with: appEnvironment, animated: true)
}
/// Size for the expanded-player sheet, derived from the current video aspect
/// ratio (when auto-resize is enabled) so the sheet re-fits like window mode.
/// Reading `videoAspectRatio` / `playerSheetAutoResize` here registers the
/// @Observable dependency that drives the re-fit.
private func expandedSheetSize(appEnvironment: AppEnvironment) -> CGSize {
let settings = appEnvironment.settingsManager
let aspect: Double
if settings.playerSheetAutoResize,
let ratio = appEnvironment.playerService.state.videoAspectRatio, ratio > 0 {
aspect = ratio
} else {
aspect = 16.0 / 9.0 // fixed default when auto-resize is off / not yet known
}
return ExpandedPlayerWindowManager.fittedSheetSize(for: aspect)
}
#endif
#if os(macOS)