support mouse alt scroll (mode 1007)

This enables less and other older legacy programs to get mouse scroll
events
This commit is contained in:
Mitchell Hashimoto
2023-03-17 19:10:08 -07:00
parent 8b9a1d8530
commit 1b88f7e9ab
4 changed files with 33 additions and 1 deletions

View File

@ -1079,13 +1079,38 @@ pub fn scrollCallback(self: *Surface, xoff: f64, yoff: f64) !void {
// Positive is up // Positive is up
const sign: isize = if (yoff > 0) -1 else 1; const sign: isize = if (yoff > 0) -1 else 1;
const delta: isize = sign * @max(@divFloor(self.grid_size.rows, 15), 1); const delta_unsigned = @max(@divFloor(self.grid_size.rows, 15), 1);
const delta: isize = sign * delta_unsigned;
log.info("scroll: delta={}", .{delta}); log.info("scroll: delta={}", .{delta});
{ {
self.renderer_state.mutex.lock(); self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock(); defer self.renderer_state.mutex.unlock();
// If we're in alternate screen with alternate scroll enabled, then
// we convert to cursor keys. This only happens if we're:
// (1) alt screen (2) no explicit mouse reporting and (3) alt
// scroll mode enabled.
if (self.io.terminal.active_screen == .alternate and
self.io.terminal.modes.mouse_event == .none and
self.io.terminal.modes.mouse_alternate_scroll)
{
const up_down_seq = if (delta < 0) "\x1bOA" else "\x1bOB";
for (0..delta_unsigned) |_| {
_ = self.io_thread.mailbox.push(.{
.write_stable = up_down_seq,
}, .{ .forever = {} });
}
// After sending all our messages we have to notify our IO thread
try self.io_thread.wakeup.notify();
return;
}
// We have mouse events, are not in an alternate scroll buffer,
// or have alternate scroll disabled. In this case, we just run
// the normal logic.
// Modify our viewport, this requires a lock since it affects rendering // Modify our viewport, this requires a lock since it affects rendering
try self.io.terminal.scrollViewport(.{ .delta = delta }); try self.io.terminal.scrollViewport(.{ .delta = delta });

View File

@ -80,6 +80,7 @@ modes: packed struct {
deccolm: bool = false, // 3, deccolm: bool = false, // 3,
deccolm_supported: bool = false, // 40 deccolm_supported: bool = false, // 40
mouse_alternate_scroll: bool = true, // 1007
mouse_event: MouseEvents = .none, mouse_event: MouseEvents = .none,
mouse_format: MouseFormat = .x10, mouse_format: MouseFormat = .x10,

View File

@ -101,6 +101,10 @@ pub const Mode = enum(u16) {
/// Report mouse position in the SGR format. /// Report mouse position in the SGR format.
mouse_format_sgr = 1006, mouse_format_sgr = 1006,
/// Report mouse scroll events as cursor up/down keys. Any other mouse
/// mode overrides this.
mouse_alternate_scroll = 1007,
/// Report mouse position in the urxvt format. /// Report mouse position in the urxvt format.
mouse_format_urxvt = 1015, mouse_format_urxvt = 1015,

View File

@ -951,6 +951,8 @@ const StreamHandler = struct {
.mouse_format_urxvt => self.terminal.modes.mouse_format = if (enabled) .urxvt else .x10, .mouse_format_urxvt => self.terminal.modes.mouse_format = if (enabled) .urxvt else .x10,
.mouse_format_sgr_pixels => self.terminal.modes.mouse_format = if (enabled) .sgr_pixels else .x10, .mouse_format_sgr_pixels => self.terminal.modes.mouse_format = if (enabled) .sgr_pixels else .x10,
.mouse_alternate_scroll => self.terminal.modes.mouse_alternate_scroll = enabled,
else => if (enabled) log.warn("unimplemented mode: {}", .{mode}), else => if (enabled) log.warn("unimplemented mode: {}", .{mode}),
} }
} }