- commit
- fcf31d6
- parent
- 53dacdc
- author
- Eric Bower
- date
- 2025-12-02 20:05:56 -0500 EST
fix: dont send ghostty snapshot on first attach chore: clear main screen and set cursor to home on first attach
1 files changed,
+22,
-14
+22,
-14
1@@ -83,6 +83,7 @@ const Daemon = struct {
2 running: bool,
3 pid: i32,
4 command: ?[]const []const u8 = null,
5+ has_pty_output: bool = false,
6
7 pub fn deinit(self: *Daemon) void {
8 self.clients.deinit(self.alloc);
9@@ -410,6 +411,10 @@ fn attach(daemon: *Daemon) !void {
10
11 _ = c.tcsetattr(posix.STDIN_FILENO, c.TCSANOW, &raw_termios);
12
13+ // Clear screen and move cursor to home before attaching
14+ const clear_seq = "\x1b[2J\x1b[H";
15+ _ = try posix.write(posix.STDOUT_FILENO, clear_seq);
16+
17 try clientLoop(daemon.cfg, client_sock);
18 }
19
20@@ -640,6 +645,7 @@ fn daemonLoop(daemon: *Daemon, server_sock_fd: i32, pty_fd: i32) !void {
21 } else {
22 // Feed PTY output to terminal emulator for state tracking
23 try vt_stream.nextSlice(buf[0..n]);
24+ daemon.has_pty_output = true;
25
26 // Broadcast data to all clients
27 for (daemon.clients.items) |client| {
28@@ -704,21 +710,23 @@ fn daemonLoop(daemon: *Daemon, server_sock_fd: i32, pty_fd: i32) !void {
29 try term.resize(daemon.alloc, resize.cols, resize.rows);
30 std.log.debug("init resize rows={d} cols={d}", .{ resize.rows, resize.cols });
31
32- // Send terminal state after resize
33- var builder: std.Io.Writer.Allocating = .init(daemon.alloc);
34- defer builder.deinit();
35- var term_formatter = ghostty_vt.formatter.TerminalFormatter.init(&term, .vt);
36- term_formatter.content = .{ .selection = null };
37- term_formatter.extra = .all;
38- term_formatter.format(&builder.writer) catch |err| {
39- std.log.warn("failed to format terminal state err={s}", .{@errorName(err)});
40- };
41- const term_output = builder.writer.buffered();
42- if (term_output.len > 0) {
43- ipc.appendMessage(daemon.alloc, &client.write_buf, .Output, term_output) catch |err| {
44- std.log.warn("failed to buffer terminal state for client err={s}", .{@errorName(err)});
45+ // Only send terminal state if there's been PTY output (skip on first attach)
46+ if (daemon.has_pty_output) {
47+ var builder: std.Io.Writer.Allocating = .init(daemon.alloc);
48+ defer builder.deinit();
49+ var term_formatter = ghostty_vt.formatter.TerminalFormatter.init(&term, .vt);
50+ term_formatter.content = .{ .selection = null };
51+ term_formatter.extra = .all;
52+ term_formatter.format(&builder.writer) catch |err| {
53+ std.log.warn("failed to format terminal state err={s}", .{@errorName(err)});
54 };
55- client.has_pending_output = true;
56+ const term_output = builder.writer.buffered();
57+ if (term_output.len > 0) {
58+ ipc.appendMessage(daemon.alloc, &client.write_buf, .Output, term_output) catch |err| {
59+ std.log.warn("failed to buffer terminal state for client err={s}", .{@errorName(err)});
60+ };
61+ client.has_pending_output = true;
62+ }
63 }
64 }
65 },