From 1d0f8cd158bb47941c0187d32422787c92e8feeb Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 14:25:52 -0300 Subject: A detached session no client watches draws no frames: yes | head -c 50M through pty/run goes from over 30 s to 11 s Profiling the 50 MB run showed 70% of its time in draw.render, recolorAnsi alone 43%, walking cells through PageList.pin. The detached session drew a frame after every pty read, with no client attached to see it. A host now says whether anyone watches (Host.VTable.watched). The detached server answers whether a client is attached, and while none is the core keeps the frame owed instead of drawing it. A /screen read draws its own, and a client attaching gets one (hello sets needs_frame). Debug, 80x24: 10 MB went from 7.36 s to 2.10 s, and 50 MB from over the 30 s client timeout (about 37 s by rate) to 11.08 s. What is left is the terminal's own parsing and scrollback growth. A session a frontend shows still draws after every read. Pacing those frames is the next step if that case matters. Co-Authored-By: Claude Opus 5.5 --- src/host_io.zig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/host_io.zig') diff --git a/src/host_io.zig b/src/host_io.zig index ac25e63c..c8c537b9 100644 --- a/src/host_io.zig +++ b/src/host_io.zig @@ -19,6 +19,10 @@ pub const Host = struct { present: ?*const fn (ctx: ?*anyopaque, surface: *const pardes.Surface) void = null, post_present: ?*const fn (ctx: ?*anyopaque) void = null, poll_frame: ?*const fn (ctx: ?*anyopaque) void = null, + /// Whether anyone sees a frame drawn now. A detached session with no + /// client attached draws none (a /screen read draws its own), and + /// the frame owed is drawn when one attaches. Absent: always. + watched: ?*const fn (ctx: ?*anyopaque) bool = null, detach: ?*const fn (ctx: ?*anyopaque) void = null, spawn: ?*const fn (ctx: ?*anyopaque, pane: u8, cwd: []const u8) void = null, pty_write: ?*const fn (ctx: ?*anyopaque, pane: u8, bytes: []const u8) void = null, -- cgit v1.3