summaryrefslogtreecommitdiff
path: root/src/detached
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 14:20:10 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit17c0d06618085de8d0bbf8152750ffa862db0080 (patch)
tree71a2d33dcf14e4e95387f3aa556e9952135de894 /src/detached
parentb546b578baadbd8fdd15b42988ad4d66c9c8ff21 (diff)
downloadpardes-17c0d06618085de8d0bbf8152750ffa862db0080.tar.gz
pardes-17c0d06618085de8d0bbf8152750ffa862db0080.zip
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 <[email protected]>
Diffstat (limited to 'src/detached')
-rw-r--r--src/detached/wire.zig11
1 files changed, 7 insertions, 4 deletions
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