summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 00:40:03 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit6732ce6edcf1562d3e126ed02f96466ab07c498e (patch)
tree77c68f4357b335e67b34f19e248f1ea00240e0eb /src/pardes.zig
parentfad6bf0cc7cc2cb579d9ad03147a7014906f6b92 (diff)
downloadpardes-6732ce6edcf1562d3e126ed02f96466ab07c498e.tar.gz
pardes-6732ce6edcf1562d3e126ed02f96466ab07c498e.zip
A desktop session holds 64 panes, and every route that finds none free says so
Sixteen panes was far too few for a real session. MAX_PANES is now 64 on a desktop and stays 16 on the board; the 48 more slots cost about 3.7 KB each in fixed tables (the core 1.33 to 1.45 MB, its surface 19 to 72 KB), and a pane itself (84 KB and its terminal) is allocated only when it opens. At the cap, pane/new fails with `pane/new: no pane slots: 64 max` and an err record rather than a bare ENFILE, a 9P look or exec that would open a pane fails its write with the same words and reads back empty, and New, Tty, Tutor and Alt-n say it on the message row (their ctl writes fail with it). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 8dbe6744..a6a088de 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -250,7 +250,11 @@ pub const pdf_raster_policy: PdfRasterPolicy = switch (platform) {
pub const Pane = panes.Pane;
const Text = panes.Text;
-pub const MAX_PANES = 16;
+/// Pane slots: 64 on a desktop, where a session keeps many files and
+/// terminals open; the board keeps its 16. A slot costs its share of the
+/// fixed tables (MAX_PANES-sized arrays in the core and its surface) whether
+/// or not a pane is in it; a pane itself is allocated when it opens.
+pub const MAX_PANES = if (platform == .esp32p4) 16 else 64;
pub const Layer = @import("Layer.zig");
pub const RowMetrics = Layer.Metrics;
pub const TagHit = Layer.TagHit;
@@ -4797,7 +4801,7 @@ pub const Pardes = struct {
/// A scratch for New (`.scratch`) or 9P's pane/new (`.fs`).
pub fn newScratchFor(p: *Pardes, from_id: usize, kind: exec.NewPane) void {
- const free = p.freeSlot() orelse return;
+ const free = p.freeSlot() orelse return p.reportError(from_id, "New", error.NoPaneSlots);
_ = p.newScratch(from_id, free) catch return;
exec.placeNew(p, from_id, from_id, free, kind);
}
@@ -5305,7 +5309,7 @@ pub const Pardes = struct {
p.raw_hover_intent = false;
look.cancelLookHover(p);
const reply = ctlfs.handle(p, req);
- if (reply.status == .err and (req.op == .write or req.op == .setattr)) ctlfs.events.noteError(p, req, reply);
+ if (reply.status == .err and (req.op == .write or req.op == .setattr or (req.op == .open and reply.errno == ctlfs.E.NFILE))) ctlfs.events.noteError(p, req, reply);
// The request was a whole step of its own, so it settles the way a
// step does: the cursor and scroll reconciled, the scripted panes
// told, and the panes it made announced to /log now rather than at
@@ -5665,7 +5669,7 @@ pub const Pardes = struct {
// global window ops (any mode): Alt-n new terminal below, Alt-c move
// the active terminal into a fresh column
if (hit(key, config.new_shell_below)) {
- const free = p.freeSlot() orelse return;
+ const free = p.freeSlot() orelse return p.reportError(p.active, "Tty", error.NoPaneSlots);
const nt = p.newShell(free, "") catch return;
nt.greet = true;
// From a tag, as a 9P new is: acme's t->w == nil.