mirror of
https://github.com/yattee/yattee.git
synced 2026-10-27 23:17:18 +00:00
Replace UIScreen.main with scene-local context
- List row hairlines read displayScale from the SwiftUI environment - MPV render views take contentScaleFactor from traitCollection and re-apply it on UITraitDisplayScale changes - ExpandedPlayerWindow scales against the presenting view's own height - MPVPiPBridge sizes the PiP layer from the container view's window scene screen (UIScreen.main kept only as a nil-window fallback) - WideScreenPlayerLayout falls back to the offered geometry size - Remote control fullscreen state comes from the player sheet's layout pass via NavigationCoordinator.isWideScreenLayoutActive instead of screen bounds aspect - Orientation TODOs for Dynamic Island side detection and prefersInterfaceOrientationLocked
This commit is contained in:
@@ -68,6 +68,7 @@ final class NavigationCoordinator {
|
||||
if !isPlayerExpanded {
|
||||
hasAppliedPanelDefaultVisibility = false
|
||||
isCornerLayoutActive = false
|
||||
isWideScreenLayoutActive = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,6 +83,11 @@ final class NavigationCoordinator {
|
||||
/// different view than the layout resolver.
|
||||
var isCornerLayoutActive = false
|
||||
|
||||
/// Whether the expanded player currently resolves to the widescreen
|
||||
/// (landscape) layout. Set from the sheet's layout pass so non-view code
|
||||
/// (remote control state) reads the real layout instead of screen bounds.
|
||||
var isWideScreenLayoutActive = false
|
||||
|
||||
/// Whether the mini player queue sheet is showing.
|
||||
var isMiniPlayerQueueSheetPresented = false
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ final class OrientationManager {
|
||||
notifyOrientationChange()
|
||||
}
|
||||
|
||||
// TODO: Modernization - Consider adopting `prefersInterfaceOrientationLocked` (iOS 26+)
|
||||
// as the modern replacement for orientation locking via `supportedInterfaceOrientations`.
|
||||
/// Returns the supported interface orientations.
|
||||
/// When locked, returns only the locked orientation.
|
||||
/// Otherwise: iPhone = all except upside-down, iPad = all
|
||||
|
||||
@@ -30,6 +30,8 @@ final class MPVPiPBridge: NSObject {
|
||||
private let sampleBufferLayer = AVSampleBufferDisplayLayer()
|
||||
private var pipController: AVPictureInPictureController?
|
||||
private weak var mpvBackend: MPVBackend?
|
||||
/// The view currently hosting `sampleBufferLayer`; used to reach the scene's screen while PiP is active.
|
||||
private weak var containerView: PlatformView?
|
||||
|
||||
/// Whether PiP is currently active.
|
||||
var isPiPActive: Bool {
|
||||
@@ -123,6 +125,7 @@ final class MPVPiPBridge: NSObject {
|
||||
/// - containerView: The view to embed the sample buffer layer in
|
||||
func setup(backend: MPVBackend, in containerView: PlatformView) {
|
||||
self.mpvBackend = backend
|
||||
self.containerView = containerView
|
||||
|
||||
// Configure sample buffer layer
|
||||
sampleBufferLayer.frame = containerView.bounds
|
||||
@@ -283,9 +286,13 @@ final class MPVPiPBridge: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
let screenWidth = UIScreen.main.bounds.width
|
||||
// TODO: Modernization - The UIScreen.main fallback assumes a single display. It is only
|
||||
// reached when the container view has no window scene (e.g. layer detached); consider
|
||||
// returning early there instead of sizing against a screen the layer may not be on.
|
||||
let screenBounds = containerView?.window?.windowScene?.screen.bounds ?? UIScreen.main.bounds
|
||||
let screenWidth = screenBounds.width
|
||||
// Calculate height based on aspect ratio, capped to leave room for details
|
||||
let maxHeight = UIScreen.main.bounds.height * 0.6 // Leave 40% for details
|
||||
let maxHeight = screenBounds.height * 0.6 // Leave 40% for details
|
||||
let calculatedHeight = screenWidth / aspectRatio
|
||||
let height = min(calculatedHeight, maxHeight)
|
||||
let width = height < calculatedHeight ? height * aspectRatio : screenWidth
|
||||
@@ -409,6 +416,7 @@ final class MPVPiPBridge: NSObject {
|
||||
/// as the layer must be in a visible window hierarchy.
|
||||
func moveLayer(to containerView: PlatformView) {
|
||||
sampleBufferLayer.removeFromSuperlayer()
|
||||
self.containerView = containerView
|
||||
if let frame = sanitizedGeometry(containerView.bounds, from: "moveLayer(to:)") {
|
||||
sampleBufferLayer.frame = frame
|
||||
}
|
||||
|
||||
@@ -229,7 +229,10 @@ final class MPVRenderView: UIView {
|
||||
|
||||
private func commonInit() {
|
||||
backgroundColor = .black
|
||||
contentScaleFactor = UIScreen.main.scale
|
||||
contentScaleFactor = traitCollection.displayScale
|
||||
registerForTraitChanges([UITraitDisplayScale.self]) { (self: MPVRenderView, _) in
|
||||
self.contentScaleFactor = self.traitCollection.displayScale
|
||||
}
|
||||
|
||||
// Configure EAGL layer
|
||||
// Note: retainedBacking=true is required for glReadPixels to work (PiP frame capture).
|
||||
|
||||
@@ -86,7 +86,10 @@ final class MPVSoftwareRenderView: UIView {
|
||||
|
||||
private func commonInit() {
|
||||
backgroundColor = .black
|
||||
contentScaleFactor = UIScreen.main.scale
|
||||
contentScaleFactor = traitCollection.displayScale
|
||||
registerForTraitChanges([UITraitDisplayScale.self]) { (self: MPVSoftwareRenderView, _) in
|
||||
self.contentScaleFactor = self.traitCollection.displayScale
|
||||
}
|
||||
|
||||
// Observe app lifecycle
|
||||
NotificationCenter.default.addObserver(
|
||||
|
||||
@@ -480,8 +480,7 @@ final class RemoteControlCoordinator {
|
||||
// Compute fullscreen state (same logic as shouldShowFullscreenButton in PlayerControlsActions)
|
||||
#if os(iOS)
|
||||
let isIPad = UIDevice.current.userInterfaceIdiom == .pad
|
||||
let screenBounds = UIScreen.main.bounds
|
||||
let isWideScreenLayout = screenBounds.width > screenBounds.height
|
||||
let isWideScreenLayout = navigationCoordinator?.isWideScreenLayoutActive ?? false
|
||||
// iPad in widescreen = can't force rotation, so fullscreen toggle not available
|
||||
let canToggleFullscreen = !(isIPad && isWideScreenLayout) && state.currentVideo != nil
|
||||
let isFullscreen = isWideScreenLayout
|
||||
|
||||
Reference in New Issue
Block a user