diff --git a/src/Surface.zig b/src/Surface.zig index 40b6a2f90..d7329889b 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1121,6 +1121,20 @@ 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) + { + switch (event.action) { + .press => try self.rt_surface.setMouseShape(.text), + .release => try self.rt_surface.setMouseShape(self.io.terminal.mouse_shape), + .repeat => {}, + } + } + // 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/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..cf3dbea71 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,9 @@ 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. 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..5fc3c6c1f 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, @@ -1902,7 +1934,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 { @@ -1992,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 = {} });