fix: observe playback state to unhide native video surface
This commit is contained in:
@@ -285,8 +285,15 @@ def check_cli_instances(root, app, fixtures):
|
|||||||
and state["position"] > 0 and state["hasVideo"] for state in states.values()),
|
and state["position"] > 0 and state["hasVideo"] for state in states.values()),
|
||||||
"cold default CLI opens one actual player window")
|
"cold default CLI opens one actual player window")
|
||||||
first_pid = next(iter(first))
|
first_pid = next(iter(first))
|
||||||
|
renderer = first[first_pid]["window"]
|
||||||
|
if (not renderer.get("rendererAttached") or renderer.get("rendererHidden")
|
||||||
|
or abs(renderer["rendererWidth"] - renderer["videoWidth"]) > 1
|
||||||
|
or abs(renderer["rendererHeight"] - renderer["videoHeight"]) > 1):
|
||||||
|
raise RuntimeError(f"playing renderer must fill its visible native surface: {renderer}")
|
||||||
opened = input_request(first_pid, 1, lambda state: state["showsQueue"]
|
opened = input_request(first_pid, 1, lambda state: state["showsQueue"]
|
||||||
and state["window"].get("videoOwnsMouse") is True
|
and state["window"].get("videoOwnsMouse") is True
|
||||||
|
and state["window"].get("rendererAttached") is True
|
||||||
|
and state["window"].get("rendererHidden") is False
|
||||||
and abs(state["window"]["videoWidth"] - first[first_pid]["window"]["videoWidth"]) < 1,
|
and abs(state["window"]["videoWidth"] - first[first_pid]["window"]["videoWidth"]) < 1,
|
||||||
"queue preserves video size and mouse target", action="queue", visible=True)
|
"queue preserves video size and mouse target", action="queue", visible=True)
|
||||||
window = opened[first_pid]["window"]
|
window = opened[first_pid]["window"]
|
||||||
|
|||||||
@@ -122,6 +122,12 @@ private enum CLIInstanceCheck {
|
|||||||
result["sidebarOwnsMouse"] = hit(NSPoint(x: surface.bounds.maxX + 130, y: surface.bounds.midY)) !== surface
|
result["sidebarOwnsMouse"] = hit(NSPoint(x: surface.bounds.maxX + 130, y: surface.bounds.midY)) !== surface
|
||||||
result["videoWidth"] = surface.bounds.width
|
result["videoWidth"] = surface.bounds.width
|
||||||
result["videoHeight"] = surface.bounds.height
|
result["videoHeight"] = surface.bounds.height
|
||||||
|
if let video = PlayerModel.shared.videoView {
|
||||||
|
result["rendererWidth"] = video.bounds.width
|
||||||
|
result["rendererHeight"] = video.bounds.height
|
||||||
|
result["rendererAttached"] = video.superview === surface
|
||||||
|
result["rendererHidden"] = video.isHidden
|
||||||
|
}
|
||||||
result["surfaceMovesOnMouseDown"] = surface.mouseDownCanMoveWindow
|
result["surfaceMovesOnMouseDown"] = surface.mouseDownCanMoveWindow
|
||||||
let edges = [NSPoint(x: 1, y: content.bounds.midY),
|
let edges = [NSPoint(x: 1, y: content.bounds.midY),
|
||||||
NSPoint(x: content.bounds.maxX - 1, y: content.bounds.midY),
|
NSPoint(x: content.bounds.maxX - 1, y: content.bounds.midY),
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ make check
|
|||||||
|
|
||||||
The full suite requires a graphical macOS session and a working audio device; it launches isolated app instances and plays short test audio. Targeted `check-*` targets are listed in the [Makefile](Makefile). Visual appearance, physical media-key routing, and receiver behavior still need manual checks.
|
The full suite requires a graphical macOS session and a working audio device; it launches isolated app instances and plays short test audio. Targeted `check-*` targets are listed in the [Makefile](Makefile). Visual appearance, physical media-key routing, and receiver behavior still need manual checks.
|
||||||
|
|
||||||
|
The startup checks verify that playing video remains attached, unhidden and sized to its native drag surface, including with the queue open; playback-state checks alone do not establish renderer visibility.
|
||||||
|
|
||||||
`make benchmark-playback` measures cold source startup, cached/uncached seeks, and sustained native/Cast playback with repeatable loopback fixtures. It requires the same macOS session/audio device and fixture-generation FFmpeg; results exclude live extraction, WAN/TLS, and physical-receiver latency.
|
`make benchmark-playback` measures cold source startup, cached/uncached seeks, and sustained native/Cast playback with repeatable loopback fixtures. It requires the same macOS session/audio device and fixture-generation FFmpeg; results exclude live extraction, WAN/TLS, and physical-receiver latency.
|
||||||
The [benchmark runner](Checks/playback-benchmark.py) accepts `--compare-native <baseline-binary>` for alternating native-only comparisons; add `--seek-work` to isolate cache-miss seeks when both binaries support that mode. Preserve the baseline executable before rebuilding.
|
The [benchmark runner](Checks/playback-benchmark.py) accepts `--compare-native <baseline-binary>` for alternating native-only comparisons; add `--seek-work` to isolate cache-miss seeks when both binaries support that mode. Preserve the baseline executable before rebuilding.
|
||||||
|
|
||||||
|
|||||||
@@ -1881,7 +1881,7 @@ private struct CaptionSelector: NSViewRepresentable {
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct PlaybackSurface: NSViewRepresentable {
|
struct PlaybackSurface: NSViewRepresentable {
|
||||||
let model: PlayerModel
|
@ObservedObject var model: PlayerModel
|
||||||
|
|
||||||
func makeNSView(context: Context) -> DragView { DragView(model: model) }
|
func makeNSView(context: Context) -> DragView { DragView(model: model) }
|
||||||
func updateNSView(_ view: DragView, context: Context) { view.updateVideo() }
|
func updateNSView(_ view: DragView, context: Context) { view.updateVideo() }
|
||||||
|
|||||||
Reference in New Issue
Block a user