diff --git a/src/Surface.zig b/src/Surface.zig index d19f61d11..fa7af108e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1152,6 +1152,22 @@ pub fn focusCallback(self: *Surface, focused: bool) !void { // Schedule render which also drains our mailbox try self.queueRender(); + + // Notify the app about focus in/out if it is requesting it + { + self.renderer_state.mutex.lock(); + const focus_event = self.io.terminal.modes.focus_event; + self.renderer_state.mutex.unlock(); + + if (focus_event) { + const seq = if (focused) "\x1b[I" else "\x1b[O"; + _ = self.io_thread.mailbox.push(.{ + .write_stable = seq, + }, .{ .forever = {} }); + + try self.io_thread.wakeup.notify(); + } + } } pub fn refreshCallback(self: *Surface) !void { diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 4c01f1b00..db801a15c 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -80,6 +80,7 @@ modes: packed struct { deccolm: bool = false, // 3, deccolm_supported: bool = false, // 40 + focus_event: bool = false, // 1004 mouse_alternate_scroll: bool = true, // 1007 mouse_event: MouseEvents = .none, mouse_format: MouseFormat = .x10, diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig index 228895972..e7d3f0a52 100644 --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -95,6 +95,9 @@ pub const Mode = enum(u16) { /// to track mouse movement. mouse_event_any = 1003, + /// Send focus in/out events. + focus_event = 1004, + /// Report mouse position in the utf8 format to support larger screens. mouse_format_utf8 = 1005, diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 617e0b156..a9632d799 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1061,6 +1061,8 @@ const StreamHandler = struct { .mouse_alternate_scroll => self.terminal.modes.mouse_alternate_scroll = enabled, + .focus_event => self.terminal.modes.focus_event = enabled, + else => if (enabled) log.warn("unimplemented mode: {}", .{mode}), } }