fix(macos): restore video layer on focus

This commit is contained in:
edde746
2026-05-11 10:13:05 +02:00
parent 8d76dff353
commit 9b248a7a5b
7 changed files with 56 additions and 12 deletions
+38 -3
View File
@@ -100,14 +100,27 @@ class MpvPlayerCore: MpvPlayerCoreBase {
private var isVisible = false
private var pausedState = true
private var shouldRestoreOnWindowVisible = false
func setVisible(_ visible: Bool) {
func setVisible(_ visible: Bool, restoreOnWindowVisible: Bool = false) {
guard metalLayer != nil, !isPipActive else { return }
if visible && isVisible && !shouldRestoreOnWindowVisible {
isBackgrounded = false
if metalLayer?.isHidden == true {
setMetalLayerHidden(false)
}
beginPlaybackActivity()
print("[MpvPlayerCore] setVisible(true) skipped - already visible")
return
}
isVisible = visible
shouldRestoreOnWindowVisible = !visible && restoreOnWindowVisible
isBackgrounded = !visible
if visible {
shouldRestoreOnWindowVisible = false
if let contentView = window?.contentView {
contentView.wantsLayer = true
if let superlayer = contentView.layer {
@@ -120,7 +133,7 @@ class MpvPlayerCore: MpvPlayerCoreBase {
}
setMetalLayerHidden(!visible)
print("[MpvPlayerCore] setVisible(\(visible))")
print("[MpvPlayerCore] setVisible(\(visible), restoreOnWindowVisible: \(restoreOnWindowVisible))")
}
func setPaused(_ paused: Bool) {
@@ -211,7 +224,11 @@ class MpvPlayerCore: MpvPlayerCoreBase {
} else if windowVisible && layerHiddenForOcclusion {
print("[MpvPlayerCore] Window visible - showing Metal layer")
layerHiddenForOcclusion = false
setMetalLayerHidden(!isVisible)
if shouldRestoreOnWindowVisible {
restoreMetalLayerAfterOcclusion()
} else {
setMetalLayerHidden(!isVisible)
}
isBackgrounded = false
if !pausedState {
beginPlaybackActivity()
@@ -235,6 +252,24 @@ class MpvPlayerCore: MpvPlayerCoreBase {
print("[MpvPlayerCore] Ended playback activity assertion")
}
private func restoreMetalLayerAfterOcclusion() {
if let metalLayer, let contentView = window?.contentView {
contentView.wantsLayer = true
if let superlayer = contentView.layer {
let targetFrame = contentView.bounds
let needsAttach = metalLayer.superlayer !== superlayer || superlayer.sublayers?.first !== metalLayer
if needsAttach {
attachMetalLayer(to: superlayer, frame: targetFrame)
} else if !metalLayer.frame.equalTo(targetFrame) {
updateFrame(targetFrame)
}
}
}
isVisible = true
shouldRestoreOnWindowVisible = false
setMetalLayerHidden(false)
}
private func attachMetalLayer(to superlayer: CALayer, frame: CGRect) {
guard let metalLayer else { return }
+3 -1
View File
@@ -13,7 +13,9 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPluginS
// MpvPluginShared conformance
var coreBase: MpvPlayerCoreBase? { playerCore }
func setPlayerVisible(_ visible: Bool) { playerCore?.setVisible(visible) }
func setPlayerVisible(_ visible: Bool, restoreOnWindowVisible: Bool) {
playerCore?.setVisible(visible, restoreOnWindowVisible: restoreOnWindowVisible)
}
func updatePlayerFrame() { playerCore?.updateFrame() }
// PiP