summaryrefslogtreecommitdiff
path: root/src/detached/client.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/detached/client.zig')
-rw-r--r--src/detached/client.zig33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/detached/client.zig b/src/detached/client.zig
index 8c9a2560..69ab2fdd 100644
--- a/src/detached/client.zig
+++ b/src/detached/client.zig
@@ -109,6 +109,10 @@ pub const Client = struct {
regions: std.ArrayListUnmanaged(pardes.Region) = .empty,
/// The palette its chrome is drawn in, as its last frame gave it.
chrome: pardes.Chrome = .{},
+ /// The post chain its frames are drawn through, as the session last
+ /// sent it; its paths and SPIR-V owned here. `post_key` moves with it.
+ post: wire.Post = .{},
+ post_key: u32 = 0,
in: std.ArrayListUnmanaged(u8) = .empty,
out: std.ArrayListUnmanaged(u8) = .empty,
/// Bytes of `in` belonging to the message `next` returned last. Compacted at
@@ -187,6 +191,7 @@ pub const Client = struct {
}
for (&c.tag_layers) |*layer| c.gpa.free(layer.cells);
c.regions.deinit(c.gpa);
+ c.freePost();
c.in.deinit(c.gpa);
c.out.deinit(c.gpa);
}
@@ -356,10 +361,30 @@ pub const Client = struct {
// open a URI on this display or read this display's selection back
// over the socket. `Ungreeted` is the same refusal a frame gets.
.set_clipboard, .read_clipboard, .open_link => if (!c.attached()) return error.Ungreeted,
+ // Kept, like the chrome: the frames that follow are drawn
+ // through it.
+ .post => |chain| {
+ if (!c.attached()) return error.Ungreeted;
+ c.freePost();
+ c.post = chain;
+ for (c.post.passes[0..c.post.len]) |*pass| {
+ pass.path = c.gpa.dupe(u8, pass.path) catch return error.Closed;
+ pass.spirv = c.gpa.dupe(u8, pass.spirv) catch return error.Closed;
+ }
+ c.post_key +%= 1;
+ },
}
return msg;
}
+ fn freePost(c: *Client) void {
+ for (c.post.passes[0..c.post.len]) |pass| {
+ c.gpa.free(pass.path);
+ c.gpa.free(pass.spirv);
+ }
+ c.post = .{};
+ }
+
// ---- internals --------------------------------------------------------
fn reshape(c: *Client, cols: u16, rows: u16) (Error || wire.Error)!void {
@@ -1131,7 +1156,7 @@ test "detached session: the seam's own routing rules, per surviving effect" {
test "detached session: a frontend is never asked to fork, write, or watch" {
// THE INVARIANT OF THE WHOLE DETACHED DESIGN, pinned as a property of the
// protocol rather than of one code path: a frontend is input and screen, so
- // the set of messages that can reach it is exactly the eight below. If a
+ // the set of messages that can reach it is exactly the nine below. If a
// machine-local effect is ever put back on the wire, a frontend becomes the
// process that owns a pane's shell again — and a pane whose shell belongs to
// a frontend dies when that frontend leaves, which is the bug this replaced.
@@ -1149,6 +1174,10 @@ test "detached session: a frontend is never asked to fork, write, or watch" {
// The three that need THIS human's display and cannot be done by a
// daemon nobody is looking at.
"set_clipboard", "read_clipboard", "open_link",
+ // Display state, like a frame's chrome: the passes this display
+ // draws its frames through. A file's SPIR-V arrives compiled, so the
+ // frontend still reads no disk and runs no program.
+ "post",
};
// One: the union a frontend decodes into has no other variant. Named
@@ -1183,7 +1212,7 @@ test "detached session: a frontend is never asked to fork, write, or watch" {
if (@intFromEnum(want) == tag) break true;
} else false;
if (!named) {
- std.debug.print("tag 0x{x:0>2} is decodable by a frontend and is not one of the seven\n", .{tag});
+ std.debug.print("tag 0x{x:0>2} is decodable by a frontend and is not one of the nine\n", .{tag});
return error.MachineLocalEffectOnTheWire;
}
}