Fix frozen terminals after split churn

Merged
LA
8mo ago
+46316-4536

Summary

Fix an intermittent state where terminal panels look frozen/unresponsive after split/tab churn (caret not blinking; typed characters only appear after Enter or a focus toggle).

What Changed

  • Ghostty fork: restart macOS CVDisplayLink when the surface display ID changes (avoids “vsync running but no callbacks” -> no presents until focus/occlusion changes).
  • cmuxterm:
    • Don’t send display_id=0 to Ghostty; set a valid display ID early when creating a surface.
    • Make createTab / new_surface focus deterministic (focusPane + selectTab + apply selection side-effects) so newly-created terminals become interactive immediately.
    • Strengthen focus retries in GhosttySurfaceScrollView.ensureFocus so focus isn’t permanently dropped during rapid bonsplit/SwiftUI reparenting.
    • Debug socket helpers: make simulate_shortcut / simulate_type resilient to transient keyWindow nil by targeting a visible window and activating it.

Tests / Tooling

  • Added tests/test_visual_typing_char_by_char.py (panel snapshots + pixel diffs) to ensure per-character typing visibly renders.
  • Updated tests/test_initial_terminal_interactive_and_rendering.py and tests/test_new_tab_interactive_after_splits.py to catch focus/render stalls.
  • Added tests/test_terminal_input_render_report.py to generate a manual HTML report with screenshots.

Verification

  • Host:
    • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination 'platform=macOS' build
  • VM (UTM):
    • xcodebuild ... build
    • tests/test_update_timing.py, tests/test_signals_auto.py, tests/test_ctrl_socket.py, tests/test_notifications.py
    • plus the new focus/render tests above