pingdotgg / pingdotgg/t3code

[Bug]: SwiftUI client (TestFlight, macOS) — TimelineView/Canvas render loop saturates WindowServer and freezes the entire session

Open
#10,499 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs more info via-triage
Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Before submitting
  • I searched existing issues and did not find a duplicate. (Closest relatives: #5491, #8309 — same class of per-publish rework, but neither covers a WindowServer-saturating render loop on macOS.)
  • I included enough detail to reproduce or investigate the problem.
Area

apps/mobile — the experimental SwiftUI client (apps/swift-ios, per #5178), distributed via TestFlight, running as the iOS-on-Mac app on Apple Silicon.

Steps to reproduce

Not fully deterministic yet (happened once), but the setup:

  1. Run the T3 Code SwiftUI TestFlight client (v0.1.0, build 47) on an Apple Silicon Mac (it runs as the iOS app on macOS via the Wrapper/ structure).
  2. Have an agent turn streaming output with the app in the foreground.
  3. Observe WindowServer (Activity Monitor → Window Server, or ps sampling) over the next minutes.

I have a watchdog installed that samples WindowServer CPU every 5 minutes, so next occurrence I can capture precise timing and a fresh sudo spindump.

Expected behavior

The client renders streaming deltas efficiently; WindowServer stays near its idle baseline; other apps remain responsive.

Actual behavior

WindowServer was driven into a sustained 50% CPU render flood for 3+ minutes, saturating it and freezing the entire macOS session — beachballs in every app (Safari 15.2s slow HID responses, DockHelper 21.8s, TestFlight 8.5s per the concurrent spindump log). The system load average spiked past 40. Force-quitting T3 Code SwiftUI at the peak resolved it.

macOS itself generated a CPU-resource diagnostic on WindowServer:

Command:          WindowServer
Event:            cpu usage
CPU:              90 seconds cpu time over 178 seconds (50% cpu average),
                  exceeding limit of 50% cpu over 180 seconds
Duration:         178.47s
Hardware model:   MacBookPro18,4
OS Version:       macOS 26.6.2 (Build 25G83)

The microstackshots show a continuous SwiftUI render loop that never settles, with TimelineView and Canvas in the view graph:

ViewGraphRootValueUpdater.render(interval:updateDisplayList:targetTimestamp:)
└─ closure #1 in NSHostingView.layout()
   └─ CanvasDisplayList.updateValue()
      ├─ closure #2 in CanvasDisplayList.updateValue()
      │  └─ Attribute.syncMainIfReferences<A>(do:)
      └─ TimelineView<>.UpdateFilter.updateValue()
Impact

Blocks work completely — it did not just degrade your app; it took the whole machine down with it (unresponsive UI session-wide for ~15 minutes until the app was force-quit).

Suspected root cause

A TimelineView-driven Canvas re-rendering every frame without ever settling (streaming indicator / spinner / progress animation that never pauses when idle or hidden?). On macOS, WindowServer is shared by every process on the machine, so per-frame invalidations of the whole view graph don't just burn your app's CPU — they monopolize system-wide compositing.

This looks like the same class of per-publish rework already fought in this codebase: #5491 (streaming markdown republished per delta) and open PR #8309 (one state publication per stream event flooding clients). If each stream delta republishes state feeding a TimelineView/Canvas, every delta invalidates the entire view graph.

Mitigations worth considering: pause TimelineView schedules when the content isn't visible/changed (.animation.periodic), drive continuous animation with Canvas's own TimelineView pause support, throttle state publications during streaming, and gate animations on NSApplication.isActive / scene phase.

Version or commit

T3 Code SwiftUI (TestFlight) — com.t3tools.t3code.swiftui, CFBundleShortVersionString 0.1.0, build 47

Environment

macOS 26.6.2 (25G83), MacBookPro18,4 (M1 Max, 10-core), 64 GB RAM. App installed via TestFlight Beta Distribution (Team ARK85ZXQ4Z), running as iOS-app-on-Mac (Wrapper/T3Code.app). Note: the machine was also memory-pressured (27 GB swap in use), which amplified the blast radius, but the WindowServer render flood is what triggered the cascade and it stopped when the app was quit.

Logs or stack traces

Full Apple-generated diagnostic (WindowServer cpu_resource .diag, 128 KB, 774 lines): https://gist.github.com/sscarduzio/46ee64f051801dbdf34e7368fc75e717

Workaround

Force-quit the SwiftUI client. Until fixed, I've installed a watchdog that alerts me if WindowServer exceeds 40% CPU sustained, so I can kill the app before the system freezes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/swift-ios and the Wrapper/structure, reproducing streaming output in the TestFlight build while observing WindowServer and the supplied diagnostic. Trace the SwiftUI view graph entries involving TimelineView and Canvas, then verify the render loop settles when streaming is idle or stopped. Done means the client no longer sustains WindowServer CPU saturation or freezes the macOS session.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
mobile, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.