From 07706163ab3a5dfbb2c6940ac6e5966b19e0074e Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 07:28:59 -0300 Subject: A detached session no frontend has sized is 160x50, not 80x24 At 80x24 a script's third or fourth pane/new was refused for want of rows. `size` still sets any other size, and a frontend attaching its own. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/pardes-9p/SKILL.md | 2 +- docs/fs.md | 2 +- src/detached/server.zig | 9 +++++++++ test/fs.py | 10 +++++----- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md index e88f7652..1bb825fe 100644 --- a/.agents/skills/pardes-9p/SKILL.md +++ b/.agents/skills/pardes-9p/SKILL.md @@ -76,7 +76,7 @@ $m/listeners this session's dial addresses $m/focus the serial of the pane with the keyboard (empty while a column/workspace tag has it); echo a serial into it to move the keyboard (a folded pane stays folded) $m/ctl the settings, one a line as a write takes them; write a setting or a session builtin; - `size ` sizes a --detach session no frontend is attached to (80x24 before) + `size ` sizes a --detach session no frontend is attached to (160x50 before) (Newcol makes an empty column, Dump, Theme x; Exit QUITS the editor, Kill [word...] stops the commands pardes started (command panes, lines it typed into shells), a word matching a command line's first word; Exit and Restore refuse once, diff --git a/docs/fs.md b/docs/fs.md index 92f2876a..7baac666 100644 --- a/docs/fs.md +++ b/docs/fs.md @@ -113,7 +113,7 @@ Existing Plan9port/v9fs clients need a userspace bridge for QUIC. which makes its column the active one as a click there would /ctl the settings, one a line as a write takes them; write a setting or a session builtin; `size ` sets the screen of a session no frontend is attached to - (`--detach`, 80x24 until then; refused while a frontend owns the size), + (`--detach`, 160x50 until then; refused while a frontend owns the size), from 20x6 to 4096x4096 (outside that, `invalid size`, EINVAL), and refused when a column has not the rows for its panes' minima, each its tag and 2 rows, the minimum placement keeps; so a size once taken is taken again, diff --git a/src/detached/server.zig b/src/detached/server.zig index bb66b841..13cf4488 100644 --- a/src/detached/server.zig +++ b/src/detached/server.zig @@ -1201,11 +1201,20 @@ fn onQuitSignal(_: std.posix.SIG) callconv(.c) void { if (quit_wake >= 0) _ = libc.send(quit_wake, "q", 1, nosignal); } +/// The screen of a detached session no frontend has sized. +pub const detached_cols = 160; +pub const detached_rows = 50; + pub fn run(init: std.process.Init, opts: pardes.Options, name: []const u8) !void { const gpa = init.gpa; const allocs = pardes.memory.init(gpa); defer pardes.memory.deinit(); var options = opts; + // No frontend yet, so no size to take: one roomy enough for a script's + // panes (80x24 left pane/new refused after a few); `size` sets another, + // and an attaching frontend its own. + options.cols = detached_cols; + options.rows = detached_rows; options.image_allocator = allocs.image; options.pdf_allocator = allocs.pdf; options.tree_sitter_allocator = allocs.tree_sitter; diff --git a/test/fs.py b/test/fs.py index 45fdbc38..89801a71 100644 --- a/test/fs.py +++ b/test/fs.py @@ -596,12 +596,12 @@ def cut_writes(binary): client.write(f'/pane/{serial}/ctl', block) body = client.read(f'/pane/{serial}/body').decode().splitlines() assert body == ['line %05d of the block' % i for i in range(2500)], (len(body), body[:2]) - # A detached session with no frontend is 80x24 until told. + # A detached session with no frontend is 160x50 until told. screen = client.screen() - assert (screen['cols'], screen['rows']) == (80, 24), (screen['cols'], screen['rows']) - client.write('/ctl', b'size 132 50\n') + assert (screen['cols'], screen['rows']) == (160, 50), (screen['cols'], screen['rows']) + client.write('/ctl', b'size 132 40\n') screen = client.screen() - assert (screen['cols'], screen['rows']) == (132, 50), (screen['cols'], screen['rows']) + assert (screen['cols'], screen['rows']) == (132, 40), (screen['cols'], screen['rows']) def test(binary, quic=False): @@ -813,7 +813,7 @@ def test(binary, quic=False): contents = restored.read(f'/pane/{file_id}/body') assert contents == b'dumped state\n', (contents, saved.read_text(), restored.read('/index')) assert restored.read(f'/pane/{control_id}/body') == b'', 'commands ran through exec, not the body' - assert restored.screen()['cols'] == 80 + assert restored.screen()['cols'] == (80 if tty else 160) # a detached one is 160x50 opened = look(restored, '/n/own/os' + str(root / (name + '.txt')), source=control_id) assert restored.read(f'/pane/{opened}/body') == b'initial\n' -- cgit v1.3