- commit
- 23203f8
- parent
- 659cf8e
- author
- Eric Bower
- date
- 2025-10-12 21:07:15 -0400 EDT
refactor: resize ghostty term on attach
4 files changed,
+33,
-3
+2,
-0
1@@ -69,6 +69,8 @@ Responses are sent from the daemon to the client in response to a request. Every
2 - **Request Type**: `attach_session_request`
3 - **Request Payload**:
4 - `session_name`: string
5+ - `rows`: u16 (terminal height in rows)
6+ - `cols`: u16 (terminal width in columns)
7
8 - **Direction**: Daemon -> Client
9 - **Response Type**: `attach_session_response`
+12,
-1
1@@ -8,6 +8,7 @@ const protocol = @import("protocol.zig");
2
3 const c = @cImport({
4 @cInclude("termios.h");
5+ @cInclude("sys/ioctl.h");
6 });
7
8 const Context = struct {
9@@ -98,7 +99,17 @@ pub fn main(config: config_mod.Config, iter: *std.process.ArgIterator) !void {
10 .config = config,
11 };
12
13- const request_payload = protocol.AttachSessionRequest{ .session_name = session_name };
14+ // Get terminal size
15+ var ws: c.struct_winsize = undefined;
16+ const result = c.ioctl(posix.STDOUT_FILENO, c.TIOCGWINSZ, &ws);
17+ const rows: u16 = if (result == 0) ws.ws_row else 24;
18+ const cols: u16 = if (result == 0) ws.ws_col else 80;
19+
20+ const request_payload = protocol.AttachSessionRequest{
21+ .session_name = session_name,
22+ .rows = rows,
23+ .cols = cols,
24+ };
25 var out: std.io.Writer.Allocating = .init(allocator);
26 defer out.deinit();
27
+17,
-2
1@@ -305,7 +305,7 @@ fn handleMessage(client: *Client, data: []const u8) !void {
2 const parsed = try protocol.parseMessage(protocol.AttachSessionRequest, client.allocator, data);
3 defer parsed.deinit();
4 std.debug.print("Handling attach request for session: {s}\n", .{parsed.value.payload.session_name});
5- try handleAttachSession(client.server_ctx, client, parsed.value.payload.session_name);
6+ try handleAttachSession(client.server_ctx, client, parsed.value.payload.session_name, parsed.value.payload.rows, parsed.value.payload.cols);
7 },
8 .detach_session_request => {
9 const parsed = try protocol.parseMessage(protocol.DetachSessionRequest, client.allocator, data);
10@@ -537,7 +537,7 @@ fn handleListSessions(ctx: *ServerContext, client: *Client) !void {
11 _ = written;
12 }
13
14-fn handleAttachSession(ctx: *ServerContext, client: *Client, session_name: []const u8) !void {
15+fn handleAttachSession(ctx: *ServerContext, client: *Client, session_name: []const u8, rows: u16, cols: u16) !void {
16 // Check if session already exists
17 const is_reattach = ctx.sessions.contains(session_name);
18 const session = if (is_reattach) blk: {
19@@ -551,6 +551,21 @@ fn handleAttachSession(ctx: *ServerContext, client: *Client, session_name: []con
20 break :blk new_session;
21 };
22
23+ // Update libghostty-vt terminal size
24+ try session.vt.resize(session.allocator, cols, rows);
25+
26+ // Update PTY window size
27+ var ws = c.struct_winsize{
28+ .ws_row = rows,
29+ .ws_col = cols,
30+ .ws_xpixel = 0,
31+ .ws_ypixel = 0,
32+ };
33+ const result = c.ioctl(session.pty_master_fd, c.TIOCSWINSZ, &ws);
34+ if (result < 0) {
35+ return error.IoctlFailed;
36+ }
37+
38 // Mark client as attached
39 client.attached_session = session.name;
40 try session.attached_clients.put(client.fd, {});
+2,
-0
1@@ -63,6 +63,8 @@ pub const MessageType = enum {
2 // Typed payload structs for requests
3 pub const AttachSessionRequest = struct {
4 session_name: []const u8,
5+ rows: u16,
6+ cols: u16,
7 };
8
9 pub const DetachSessionRequest = struct {