cmux-next: Mac Screen tabs (see and control another Mac) and Share This Mac

Draft
AZ
16d ago
+20239-54

Draft. This adds Mac Screen tabs to cmux-next on macOS: see and control another Mac from a cmux tab. It also adds Share This Mac, so a Mac running cmux can be viewed by another. The screen code is CmuxScreenKit (feat-cmux-screen-kit), which this PR is stacked on.

What it adds

  • cmux://mac-screen (the home page):
    • Your paired Macs (Connect, Open in New Tab, Rename, Forget).
    • "Pair a Mac" (paste a cmux-vnc://pair link).
    • Share This Mac.
    • Pasting a pairing link into the address bar also pairs. It is never sent as a search.
  • cmux://mac-screen?mac=<id> (one Mac's screen):
    • The record holds only an id; the pairing secret is in the Keychain.
    • Tabs opened by automation, or restored after relaunch, wait for Connect.
    • The picture is WebRTC video with hardware H.264, fitted to the pane, rendered by the new macOS ScreenVideoView.
    • Input reuses the remote view pane's capture (RemoteInputSurface): physical keys, IME text, pointer, buttons and scroll. cmux's Command/Control shortcuts stay local; Control-Option-Escape releases the keyboard.
    • Toolbar: path, fps, RTT, codec, size, display, quality, Send Keys, Refresh and Disconnect.
    • Connecting, reconnecting, failed and ended cards; reconnects are automatic.
    • A hidden tab keeps its stream for 20 s, then ends it; showing the tab reconnects.
  • Share This Mac:
    • Off by default; a person turns it on.
    • Screen Recording and Accessibility rows with Open System Settings.
    • The link (masked), Copy, a QR code, and Reset Link with a confirmation.
    • The viewer's status with Disconnect.
    • While a device controls this Mac, a menu bar item offers Disconnect Viewer and Stop Sharing.
    • It runs ScreenStreamHost with ScreenCaptureKit and CGEvent in-process.
  • Library additions (additive; both iOS demo apps and cmux-vnc-host still build):
    • macOS ScreenVideoView.
    • ScreenStreamHost.onEvent and disconnectViewer().
    • An empty display list now fails instead of crashing.
    • Signaling uses an ephemeral URLSession with no URL cache, so the room secret header and TURN credentials no longer reach Cache.db.
  • Settings > Development (DEV builds only): a new section, shown only when the host is a DEV build (dev_only category in the settings export, dev_build from DevTools.isDebugBuild). It holds Mac Screen > Relay Only (macScreen.debug.relayOnly, off): Mac Screen sessions use the TURN relay only (ICE policy relay, viewer side), and connected tabs reconnect when it changes. Library: additive ScreenStreamViewer(pairing:relayOnly:) and ScreenSession.relayOnly, off by default. Exports regenerated on the fleet (scripts/measure/export-settings-artifacts.sh); settings page tests 125/125.
  • macScreen.open ("New Mac Screen Tab"): in the palette, the File menu and the + menu. CLI: tab new-mac-screen.
  • debug.mac_screen and scripts/cmux-next/mac-screen-live.py for live checks. Links move only through 0600 files.

Verification

  • Live runs from a tagged build:
    • Pairing and streaming from mini 2's Swift host, Rust host and a cmux-next Share This Mac host.
    • Connect to picture in 0.7–2.1 s, direct path, H264 HW, 1920Ɨ1080 letterboxed.
    • Input proven on the remote (click, type, Cmd-A/C/V, scroll, right-click, drag).
    • Lifecycle: confirm gate, Disconnect and Reconnect, host restart, Try Again.
    • Viewer CPU mostly 6–9% at 19–36 fps. No hangs in a 30 s Time Profiler trace.
  • Review: a correctness review found 14 items, and a live verification round found 6 bugs. All are fixed; see the review comment.
  • Final evidence: the final evidence round runs on the head build and goes to an independent verifier.

Known issues and decisions

  • WebRTC.framework and the Chromium Embedded Framework both define 8 RTC* Objective-C classes. Code binds within its own framework, so only lookups by class name are ambiguous, and the live runs work. The clean fix is a WebRTC build with a renamed prefix; that is a library dependency decision.
  • The trust call for Share This Mac is on #13742.
  • App size: this PR adds about 70 lines of glue to CmuxNextApp. The VNC branches under it add about 480 more, which the stack needs to offset before targeting feat-cmux-next.
  • The palette shows a globe icon for Mac Screen tab rows, the same as the remote view tab.

Changelog

  • Added: Mac Screen tabs in cmux-next for seeing and controlling another Mac, and Share This Mac.

šŸ¤– Generated with Claude Code