Fix black video in sheet-mode player and mini capsule hand-off delays

Sheet mode has no container lifecycle hook on either transition, so the
shared render view was stuck until the render watchdog (~10s of black):

- Presenting the sheet: the capsule parks the view while the sheet's
  window exists but is not yet visible - viewDidMoveToWindow has already
  fired and findTransferTarget rejects non-visible windows, so nothing
  picked the parked view up.
- Dismissing the sheet: the dismissed sheet's hierarchy stays alive
  holding the view inside a now-invisible window, with no unmount or
  park at all.

Add scheduleSharedViewAdoptionRetry() to MPVContainerNSView: for ~1s it
re-checks every 50ms whether the shared view needs re-homing (parked,
or owned by a container whose window lost visibility) and runs the same
recovery the watchdog uses. Deduplicated so overlapping triggers don't
stack loops. Triggered after parking with no transfer target and from
hide()'s no-window branch, which every sheet-mode collapse funnels
through.

The retry ticks pass quiet: true to recoverSharedPlayerViewIfNeeded so
teardown after closing a video (when no container legitimately exists)
no longer spams warnings, and the loop stops once the shared view is
gone.
This commit is contained in:
Arkadiusz Fal
2026-06-23 21:24:13 +02:00
parent 945804c109
commit 7808d4c730
2 changed files with 55 additions and 5 deletions

View File

@@ -192,6 +192,12 @@ final class ExpandedPlayerWindowManager: NSObject {
/// - completion: Called after the window is hidden
func hide(animated: Bool = true, completion: (() -> Void)? = nil) {
guard let window = playerWindow else {
// No window means sheet mode (or the window is already gone).
// A dismissed sheet's hierarchy stays alive holding the shared
// render view inside a now-invisible window with no container
// lifecycle event to react to - watch for the dismissal to finish
// and re-home the view to the mini capsule.
MPVContainerNSView.scheduleSharedViewAdoptionRetry()
completion?()
return
}