Skip to content

fix(mac): re-attach capture on stream death instead of full display rebuild (#29) - #157

Open
kdbhalala wants to merge 1 commit into
peetzweg:mainfrom
kdbhalala:feat/mac-29-capture-reattach
Open

fix(mac): re-attach capture on stream death instead of full display rebuild (#29)#157
kdbhalala wants to merge 1 commit into
peetzweg:mainfrom
kdbhalala:feat/mac-29-capture-reattach

Conversation

@kdbhalala

Copy link
Copy Markdown

fix(mac): re-attach capture on stream death instead of full display rebuild (#29)

Addresses issue #29 (rotation infinite rebuild loop) — fix-plan point 1.

Root cause

scheduleCaptureRecovery responded to a dead SCStream with a full
display destroy+create
(reconfigure). With ≥2 devices that rebuild kills
the neighbor's stream (OS side effect), whose recovery rebuilds its
display, killing the first — an endless ~3s ping-pong. Observed live
2026-06-11 (iPhone USB + iPad USB).

Fix

A dead stream does NOT mean the display is gone. If our own virtual display
still exists, re-attach the capture to it (no destroy/create) — this alone
breaks the loop. Full reconfigure is now only the fallback when the display
is genuinely gone (e.g. display sleep tore it down).

Not in this PR (follow-ups)

Verification

  • Logic: the re-attach path is guarded by a non-null display bounds check.
  • Requires 2 devices (iPhone + iPad) to reproduce/verify the loop — not
    runnable on a single device. Manual: 2 connected, rotate one then the other
    within ~10s, watch /tmp/opensidecar-mac.log for alternating
    reconfiguring / -3815 / capture died (should be absent after fix).

References #29, #9, #26.

…ad of full rebuild (peetzweg#29)

Per peetzweg#29 fix-plan point 1: a dead SCStream does not mean the virtual display
is gone. If our own display still exists, re-attach the capture to it rather
than destroy+create — the full rebuild is what killed the neighbor's stream
and ping-ponged the infinite rotation rebuild loop with N>=2 devices.

- scheduleCaptureRecovery: if virtualDisplay still present, re-attach capture
  only (findSCDisplay + startCapture at pixel res), fallback to full rebuild
  on failure
- capture at points*2 @2x (matches setupExtend), not SCDisplay.width (logical)
- peetzweg#9's missingTicks debounce already covers peetzweg#29 point 2 (enforcement recovery)
- point 3 (serialize rebuilds across sessions) left as follow-up: needs 2-device repro

Visual/loop verification needs 2 devices (iPhone+iPad) — untested on single device.
@kdbhalala
kdbhalala force-pushed the feat/mac-29-capture-reattach branch from 0a46602 to d4dba08 Compare July 16, 2026 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant