From 17c0d06618085de8d0bbf8152750ffa862db0080 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 14:20:10 -0300 Subject: A program that asked for focus reports (1004) hears CSI I when its pane takes the keyboard and CSI O when it gives it up, to another pane, a tag or another window The core has a window-focus event now, from SDL's window focus and from the tty's own focus reports (vaxis turns 1004 on outside); the detached wire carries it: version 10. The test shell's ESC]777;mouse;focus;<1|0> fakes the window's. Co-Authored-By: Claude Opus 5.5 --- src/detached/wire.zig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/detached') diff --git a/src/detached/wire.zig b/src/detached/wire.zig index 9a1ab608..c9d9b578 100644 --- a/src/detached/wire.zig +++ b/src/detached/wire.zig @@ -12,7 +12,7 @@ const ShaderAnimation = pardes.config.Runtime.ShaderAnimation; /// to be refused, which is what this number is for. /// 8: one layer type: a tag band carries all its rows (not a layer per /// line), and a frame carries the core's placed regions after its layers. -pub const version: u16 = 9; +pub const version: u16 = 10; /// The Chrome palette is carried field by field as its declaration lists /// them, so any change to it changes the wire: bump `version`, then this. @@ -58,6 +58,7 @@ pub const ClientTag = enum(u8) { pinch = 0x1b, touch_scroll = 0x1c, pointer_leave = 0x1d, + focus = 0x1e, }; // Session control precedes display-local effects. @@ -1076,6 +1077,7 @@ pub fn encodeClient(out: []u8, msg: ClientMsg) Error![]const u8 { .pinch => |v| try w.putF32(v), .touch_scroll => |v| try w.putF32(v), .pointer_leave => {}, + .focus => |focused| try w.putBool(focused), // See `clientTag`: no tag, so nothing to encode. .output, .eof, .exited, .lsp_resp, .pipe_resp, .file_changed, .tick => unreachable, }, @@ -1138,6 +1140,7 @@ pub fn decodeClient(tag: u8, payload: []const u8) Error!ClientMsg { .pinch => .{ .event = .{ .pinch = try r.getF32() } }, .touch_scroll => .{ .event = .{ .touch_scroll = try r.getF32() } }, .pointer_leave => .{ .event = .pointer_leave }, + .focus => .{ .event = .{ .focus = try r.getBool() } }, }; try r.end(); return msg; @@ -1222,7 +1225,7 @@ pub fn clientBound(msg: ClientMsg) usize { return msg_slack + switch (msg) { .hello, .bye => 0, .event => |ev| switch (ev) { - .mouse, .resize, .pdf_scroll, .pinch, .touch_scroll, .pointer_leave => 0, + .mouse, .resize, .pdf_scroll, .pinch, .touch_scroll, .pointer_leave, .focus => 0, .key => |k| k.text.len, .paste => |b| b.len, .command => |line| line.len, @@ -1455,7 +1458,7 @@ test "detached wire: a session is never told to do a frontend's remembering" { // Adding a name here is meant to be an ARGUMENT, not a formality, and the // bar is one sentence: A HUMAN DID IT. A keystroke, a click, a pinch, a // window resized, a paste, a command line executed, a pointer leaving the - // window — plus the two session words that say who is speaking. A pty's + // window, the window's focus — plus the two session words that say who is speaking. A pty's // output, a worker's answer, a watched file's new bytes and an animation // tick all fail that bar the same way: nobody did them, a machine reported // them, and the machine that reports them is the one already holding the @@ -1468,7 +1471,7 @@ test "detached wire: a session is never told to do a frontend's remembering" { "resize", "paste", "command", "pdf_scroll", "pinch", "touch_scroll", - "pointer_leave", + "pointer_leave", "focus", }; // One: the tag set is exactly that, named rather than counted, so -- cgit v1.3