diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 20:55:53 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | c2a1b54651be6b2532d48825d913b747a0edbea8 (patch) | |
| tree | bf5c52f352f1b9eea361ef07ffcdbca290668cdc | |
| parent | 163531dce202e71977f4524cab65702606caca62 (diff) | |
| download | pardes-c2a1b54651be6b2532d48825d913b747a0edbea8.tar.gz pardes-c2a1b54651be6b2532d48825d913b747a0edbea8.zip | |
A pane's tagexec goes to the event reader holding the pane as an x record, as acme's tag clicks do, not run past it
A real click in a held pane's tag was already told to the reader, but
the same click written to the pane's tagexec ran at once, so a script
holding the pane could not intercept it. The line is now an x record
(l for a look), done when the reader writes it back. A column's or the
workspace's tag is still no pane's and runs as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/ninep/ctl.zig | 20 | ||||
| -rw-r--r-- | src/ninep/pane.zig | 3 |
2 files changed, 19 insertions, 4 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 75a7eb9a..4aa38292 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -58,15 +58,21 @@ pub fn run(p: *Pardes, id: usize, exec: bool, text: []const u8, in_tag: bool) vo // and a line written to a look or exec is a click: on that pane, or for // the root's, on the pane with the keyboard. The reader writes the // record back to have it done. - // A click in a column's or the workspace's tag is not the pane's. - if (!in_tag and p.panes[id].?.fs.readers > 0) { + // A click in a column's or the workspace's tag is not the pane's; one + // in the pane's own tag (its tagexec) is, an `x` or `l` record as + // acme's tag clicks are. + if (!p.exec_header and p.panes[id].?.fs.readers > 0) { const named = exec_line.namesBuiltin(text); // No flag 2: a written line was never expanded from a click, and no // expansion record follows (editors/acme/look.c:42-43, exec.c:154-157). var flag: u32 = 0; if (named) flag |= pardes.ctlfs.events.flag_builtin; if (!exec and !named and std.mem.indexOfAny(u8, text, "/.:") != null) flag |= pardes.ctlfs.events.flag_filename; - _ = pardes.ctlfs.events.noteAction(p, id, if (exec) .body_exec else .body_look, 0, 0, flag, text); + const action: pardes.ctlfs.events.Action = if (in_tag) + (if (exec) .tag_exec else .tag_look) + else + (if (exec) .body_exec else .body_look); + _ = pardes.ctlfs.events.noteAction(p, id, action, 0, 0, flag, text); return noteResult(p, context); } const before = Serials.snapshot(p); @@ -1747,6 +1753,14 @@ test "a pane's own look and exec go to the event reader holding it, which writes try testing.expectEqual(tree.Status.ok, wr(p, root_exec, "Msg rooted\n").reply.status); try testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "rooted") == null); try testing.expectEqualStrings("FX0 0 1 10 Msg rooted\n", call(p, .{ .tag = 5, .op = .read, .node = event, .handle = h, .size = 256 }).bytes); + // A click in its tag is the reader's too, an `x` record, as acme's is; + // written back, it is done. + try testing.expectEqual(tree.Status.ok, wr(p, Node.of(serial, .tagexec), "Msg tagged\n").reply.status); + try testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "tagged") == null); + const tagged = call(p, .{ .tag = 6, .op = .read, .node = event, .handle = h, .size = 256 }).bytes; + try testing.expectEqualStrings("Fx0 0 1 10 Msg tagged\n", tagged); + try testing.expectEqual(tree.Status.ok, wr(p, event, tagged).reply.status); + try testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "tagged") != null); _ = call(p, .{ .tag = 4, .op = .release, .node = event, .handle = h }); // With no reader, the root's and the pane's act at once. try testing.expectEqual(tree.Status.ok, wr(p, Node.of(serial, .exec), "Msg direct\n").reply.status); diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index ce6d0422..d276b771 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -580,7 +580,8 @@ pub fn write(p: *Pardes, req: Req, id: usize, pane: *Pane, file: PaneFile) Reply .sel => writeSel(p, req, pane), .dirty, .mark, .scroll => writeFlag(p, req, pane, file), .look, .exec => ctl.command(p, req, pane.serial, file == .exec, false), - // A click in its tag: never an event reader's to hear (cols.writeExec). + // A click in its tag: an event reader holding the pane hears it as + // an `x` record (ctl.run), as acme's tag clicks are. .tagexec => ctl.command(p, req, pane.serial, true, true), .event => events.writeEvent(p, req, id), .errors => if (appendErrors(p, id, req.data)) |took| |
