diff options
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index b16d39b7..402b3cd8 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -3482,6 +3482,9 @@ pub const Mouse = struct { col: u16, row: u16, ctrl: bool = false, + shift: bool = false, + /// Alt, which xterm's mouse reports call meta. + alt: bool = false, body_hit: ?BodyHit = null, tag_hit: ?TagHit = null, /// A pixel frontend's press on the rule it draws at the top of this row, @@ -3575,6 +3578,8 @@ pub const Event = union(enum) { /// The host pointer left the drawable area. Unlike an out-of-range motion, /// this must not clamp onto and preview the final grid cell. pointer_leave, + /// The window gained (true) or lost the host's keyboard focus. + focus: bool, tick, }; @@ -4346,6 +4351,13 @@ pub const Pardes = struct { unattended: bool = false, haptic: HapticSlot = if (platform == .macos) .none else {}, drag: mouse.Drag = .none, + /// A press a terminal's program took (mouse.programMouse): its drags + /// and release are the program's too, wherever the pointer goes. + mouse_grab: ?mouse.Grab = null, + /// Whether the host window has the keyboard (Event.focus), and the pane + /// whose program was last told it has it (reportFocus). + window_focused: bool = true, + focus_told: ?struct { id: usize, serial: u32 } = null, hover_col: u16 = 0, hover_row: u16 = 0, pointer_raw_col: u16 = 0, @@ -4361,6 +4373,10 @@ pub const Pardes = struct { chord_hold: bool = false, /// The look just run found nothing (look.zig missed). look_missed: bool = false, + /// The diff line a right click just expanded to, by row: a look at its + /// text goes to the place that row names, not the first equal line + /// (look.zig diffLook). + diff_look: ?struct { serial: u32, row: usize } = null, look_hover_wait: ?look.LookHoverWait = null, /// The place a look-hover last found nothing to open: the pointer /// resting there does not ask again every frame (look.noteLookHover). @@ -4502,6 +4518,9 @@ pub const Pardes = struct { /// the terminal motion surface, memoized against the pane it was built /// for — see panes.terminal.RowsCache for the lifetime rule shell_rows: panes.terminal.RowsCache = .{}, + /// Finished command panes' output, and whether it is a diff + /// (File.DiffOutput). + diff_output: panes.File.DiffOutput = .{}, /// The message row's entry points, called from everywhere as /// `p.setMessage(...)`; they live with the rest of it in Messages.zig. @@ -4752,6 +4771,7 @@ pub const Pardes = struct { p.locations_cache.deinit(p.tree_sitter_gpa); p.fs.deinit(gpa); p.shell_rows.reset(gpa); + p.diff_output.reset(gpa); p.scratch.deinit(); p.frame_arena.deinit(); gpa.free(p.surface.cells); @@ -5039,6 +5059,25 @@ pub const Pardes = struct { } /// The column the keyboard is in: its tag's, or its pane's. + /// DECSET 1004: a program that asked is told `CSI I` when its pane + /// takes the keyboard (the active pane, its body, the window focused) + /// and `CSI O` when it gives it up, to another pane, a tag or header, + /// or another window. + fn reportFocus(p: *Pardes) void { + const want: @FieldType(Pardes, "focus_told") = blk: { + if (!p.window_focused or p.header_focus) break :blk null; + const pane = p.panes[p.active] orelse break :blk null; + if (pane.focus != .body) break :blk null; + break :blk .{ .id = p.active, .serial = pane.serial }; + }; + if (std.meta.eql(want, p.focus_told)) return; + if (p.focus_told) |old| if (p.panes[old.id]) |pane| { + if (pane.serial == old.serial and panes.terminal.reportsFocus(pane)) p.emitWrite(old.id, "\x1b[O"); + }; + if (want) |new| if (panes.terminal.reportsFocus(p.panes[new.id].?)) p.emitWrite(new.id, "\x1b[I"); + p.focus_told = want; + } + pub fn noteTyped(p: *Pardes) void { if (p.header_focus) { if (p.header_column) |c| p.setActiveColumn(c); @@ -5699,6 +5738,7 @@ pub const Pardes = struct { } pub fn update(p: *Pardes, ev: Event) void { + defer p.reportFocus(); // A tick with nothing animating is the one event that cannot change // the screen. p.needs_frame = p.needs_frame or ev != .tick; @@ -5831,6 +5871,7 @@ pub const Pardes = struct { .command => |line| _ = p.executeBuiltinLine(p.active, line), .pinch => |scale| p.ov_pinch_scale = scale, .touch_scroll => |delta| p.ov_touch_scroll_delta = delta, + .focus => |focused| p.window_focused = focused, .pointer_leave => { p.pointer_inside = false; p.pointer_body_hit = null; |
