From 0a491cd2af1d0d596d31b246bd7796e0688e3ac7 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Fri, 2 Oct 2026 23:59:27 +0200 Subject: [PATCH] Keep the macOS PiP video sized to the PiP window Once PiP starts the player's container view collapses to zero, and AVSampleBufferDisplayLayer stops laying out its internal video sublayer, so resizing the PiP window left the video at its starting size in the bottom-left corner. Force the layer's layout after each resize. --- Yattee/Services/Player/MPV/MPVPiPBridge.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Yattee/Services/Player/MPV/MPVPiPBridge.swift b/Yattee/Services/Player/MPV/MPVPiPBridge.swift index 1662edb2..01822441 100644 --- a/Yattee/Services/Player/MPV/MPVPiPBridge.swift +++ b/Yattee/Services/Player/MPV/MPVPiPBridge.swift @@ -1016,6 +1016,19 @@ extension MPVPiPBridge { LoggingService.shared.debug("MPVPiPBridge: Restored \(count) hidden PiP views", category: .mpv) } + /// AVSampleBufferDisplayLayer lays out its internal video container + /// sublayer only during a layout pass of its host window. Once PiP starts + /// our container view collapses to zero and that pass stops reaching the + /// layer, so the video in the PiP window kept the size it had when PiP + /// started while the window around it was resized. Lay it out ourselves. + private func syncSampleBufferSublayers() { + CATransaction.begin() + CATransaction.setDisableActions(true) + sampleBufferLayer.setNeedsLayout() + sampleBufferLayer.layoutIfNeeded() + CATransaction.commit() + } + /// Update the sample buffer layer's frame to match the PiP window size. private func updateLayerFrameToMatchPiPWindow() { // Try to find the PiP window @@ -1043,6 +1056,7 @@ extension MPVPiPBridge { sampleBufferLayer.frame = newFrame CATransaction.commit() } + syncSampleBufferSublayers() } else { // Fallback: try to match superlayer guard let superlayer = sampleBufferLayer.superlayer else { return }