From 49fb5c868871d246cb129b0dd179785a4d9a739f Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 2 Oct 2023 16:49:11 -0500 Subject: [PATCH 1/4] gtk(mouse): use "text" enum as default value Use the .text field of the enum as the default value of the mouse shape instead of renaming .default. Store the default value as the current value for use in subsequent commits --- src/apprt/gtk/Surface.zig | 2 +- src/terminal/Terminal.zig | 3 +++ src/termio/Exec.zig | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 99acf2f66..6fa58825c 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -424,7 +424,7 @@ pub fn setMouseShape( shape: terminal.MouseShape, ) !void { const name: [:0]const u8 = switch (shape) { - .default => "text", + .default => "default", .help => "help", .pointer => "pointer", .context_menu => "context-menu", diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 1bd5f2cf3..256b4c9fe 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -21,6 +21,7 @@ const Tabstops = @import("Tabstops.zig"); const trace = @import("tracy").trace; const color = @import("color.zig"); const Screen = @import("Screen.zig"); +const mouse_shape = @import("mouse_shape.zig"); const log = std.log.scoped(.terminal); @@ -84,6 +85,8 @@ previous_char: ?u21 = null, /// The modes that this terminal currently has active. modes: modes.ModeState = .{}, +mouse_shape: mouse_shape.MouseShape = .text, + /// These are just a packed set of flags we may set on the terminal. flags: packed struct { // This isn't a mode, this is set by OSC 133 using the "A" event. diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 5d3166853..bcd76ed41 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1902,7 +1902,7 @@ const StreamHandler = struct { self: *StreamHandler, ) !void { self.terminal.fullReset(self.alloc); - try self.setMouseShape(.default); + try self.setMouseShape(.text); } pub fn queryKittyKeyboard(self: *StreamHandler) !void { From c96cedcf220390ea0c23532591397212591513b9 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 2 Oct 2023 16:50:39 -0500 Subject: [PATCH 2/4] mouse: set mouse as text only when not reporting mouse events The selection mode is only valid when mouse reporting events are on. If we have any mouse reporting events turned on, reset the mouse shape back to default (a pointer). --- src/termio/Exec.zig | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index bcd76ed41..b89e9a64c 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -1698,10 +1698,42 @@ const StreamHandler = struct { self.messageWriter(.{ .linefeed_mode = enabled }); }, - .mouse_event_x10 => self.terminal.flags.mouse_event = if (enabled) .x10 else .none, - .mouse_event_normal => self.terminal.flags.mouse_event = if (enabled) .normal else .none, - .mouse_event_button => self.terminal.flags.mouse_event = if (enabled) .button else .none, - .mouse_event_any => self.terminal.flags.mouse_event = if (enabled) .any else .none, + .mouse_event_x10 => { + if (enabled) { + self.terminal.flags.mouse_event = .x10; + try self.setMouseShape(.default); + } else { + self.terminal.flags.mouse_event = .none; + try self.setMouseShape(.text); + } + }, + .mouse_event_normal => { + if (enabled) { + self.terminal.flags.mouse_event = .normal; + try self.setMouseShape(.default); + } else { + self.terminal.flags.mouse_event = .none; + try self.setMouseShape(.text); + } + }, + .mouse_event_button => { + if (enabled) { + self.terminal.flags.mouse_event = .button; + try self.setMouseShape(.default); + } else { + self.terminal.flags.mouse_event = .none; + try self.setMouseShape(.text); + } + }, + .mouse_event_any => { + if (enabled) { + self.terminal.flags.mouse_event = .any; + try self.setMouseShape(.default); + } else { + self.terminal.flags.mouse_event = .none; + try self.setMouseShape(.text); + } + }, .mouse_format_utf8 => self.terminal.flags.mouse_format = if (enabled) .utf8 else .x10, .mouse_format_sgr => self.terminal.flags.mouse_format = if (enabled) .sgr else .x10, From 9a6469743389509ad2d200eb95e832337ec277f7 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 2 Oct 2023 16:51:45 -0500 Subject: [PATCH 3/4] mouse: set mouse to text when bypassing mouse reporting When shift is held, we are bypassing mouse reporting mode. Change the cursor to text to indicate this to the user. On release, change back to whatever we were before. --- src/Surface.zig | 11 +++++++++++ src/termio/Exec.zig | 1 + 2 files changed, 12 insertions(+) diff --git a/src/Surface.zig b/src/Surface.zig index 40b6a2f90..6d694ea3e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1121,6 +1121,17 @@ pub fn keyCallback( self.hideMouse(); } + if (self.io.terminal.flags.mouse_event != .none and + event.physical_key == .left_shift or + event.physical_key == .right_shift) + { + switch (event.action) { + .press => try self.rt_surface.setMouseShape(.text), + .release => try self.rt_surface.setMouseShape(self.io.terminal.mouse_shape), + else => {}, + } + } + // No binding, so we have to perform an encoding task. This // may still result in no encoding. Under different modes and // inputs there are many keybindings that result in no encoding diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index b89e9a64c..5fc3c6c1f 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -2024,6 +2024,7 @@ const StreamHandler = struct { self: *StreamHandler, shape: terminal.MouseShape, ) !void { + self.terminal.mouse_shape = shape; _ = self.ev.surface_mailbox.push(.{ .set_mouse_shape = shape, }, .{ .forever = {} }); From d20c4866b153da8404510f3b46f908d428b3a0da Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 6 Nov 2023 14:42:10 -0800 Subject: [PATCH 4/4] some comments, make switch exaustive --- src/Surface.zig | 5 ++++- src/terminal/Terminal.zig | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Surface.zig b/src/Surface.zig index 6d694ea3e..d7329889b 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1121,6 +1121,9 @@ pub fn keyCallback( self.hideMouse(); } + // When we are in the middle of a mouse event and we press shift, + // we change the mouse to a text shape so that selection appears + // possible. if (self.io.terminal.flags.mouse_event != .none and event.physical_key == .left_shift or event.physical_key == .right_shift) @@ -1128,7 +1131,7 @@ pub fn keyCallback( switch (event.action) { .press => try self.rt_surface.setMouseShape(.text), .release => try self.rt_surface.setMouseShape(self.io.terminal.mouse_shape), - else => {}, + .repeat => {}, } } diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 256b4c9fe..cf3dbea71 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -85,6 +85,7 @@ previous_char: ?u21 = null, /// The modes that this terminal currently has active. modes: modes.ModeState = .{}, +/// The most recently set mouse shape for the terminal. mouse_shape: mouse_shape.MouseShape = .text, /// These are just a packed set of flags we may set on the terminal.