mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
Merge pull request #113 from mitchellh/alt-scroll
Mouse Alt Scroll (mode 1007) and Horizontal Scroll
This commit is contained in:
@ -1074,20 +1074,60 @@ pub fn scrollCallback(self: *Surface, xoff: f64, yoff: f64) !void {
|
|||||||
} else |_| {}
|
} else |_| {}
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.info("SCROLL: {} {}", .{ xoff, yoff });
|
// log.info("SCROLL: {} {}", .{ xoff, yoff });
|
||||||
_ = xoff;
|
|
||||||
|
|
||||||
// Positive is up
|
// Positive is up
|
||||||
const sign: isize = if (yoff > 0) -1 else 1;
|
const y_sign: isize = if (yoff > 0) -1 else 1;
|
||||||
const delta: isize = sign * @max(@divFloor(self.grid_size.rows, 15), 1);
|
const y_delta_unsigned: usize = if (yoff == 0) 0 else @max(@divFloor(self.grid_size.rows, 15), 1);
|
||||||
log.info("scroll: delta={}", .{delta});
|
const y_delta: isize = y_sign * @intCast(isize, y_delta_unsigned);
|
||||||
|
|
||||||
|
// Positive is right
|
||||||
|
const x_sign: isize = if (xoff < 0) -1 else 1;
|
||||||
|
const x_delta_unsigned: usize = if (xoff == 0) 0 else 1;
|
||||||
|
const x_delta: isize = x_sign * @intCast(isize, x_delta_unsigned);
|
||||||
|
log.info("scroll: delta_y={} delta_x={}", .{ y_delta, x_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)
|
||||||
|
{
|
||||||
|
if (y_delta_unsigned > 0) {
|
||||||
|
const seq = if (y_delta < 0) "\x1bOA" else "\x1bOB";
|
||||||
|
for (0..y_delta_unsigned) |_| {
|
||||||
|
_ = self.io_thread.mailbox.push(.{
|
||||||
|
.write_stable = seq,
|
||||||
|
}, .{ .forever = {} });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x_delta_unsigned > 0) {
|
||||||
|
const seq = if (x_delta < 0) "\x1bOC" else "\x1bOD";
|
||||||
|
for (0..x_delta_unsigned) |_| {
|
||||||
|
_ = self.io_thread.mailbox.push(.{
|
||||||
|
.write_stable = 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 = y_delta });
|
||||||
|
|
||||||
// If we're scrolling up or down, then send a mouse event. This requires
|
// If we're scrolling up or down, then send a mouse event. This requires
|
||||||
// a lock since we read terminal state.
|
// a lock since we read terminal state.
|
||||||
@ -1095,6 +1135,10 @@ pub fn scrollCallback(self: *Surface, xoff: f64, yoff: f64) !void {
|
|||||||
const pos = try self.rt_surface.getCursorPos();
|
const pos = try self.rt_surface.getCursorPos();
|
||||||
try self.mouseReport(if (yoff < 0) .five else .four, .press, self.mouse.mods, pos);
|
try self.mouseReport(if (yoff < 0) .five else .four, .press, self.mouse.mods, pos);
|
||||||
}
|
}
|
||||||
|
if (xoff != 0) {
|
||||||
|
const pos = try self.rt_surface.getCursorPos();
|
||||||
|
try self.mouseReport(if (xoff > 0) .six else .seven, .press, self.mouse.mods, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
|
||||||
|
@ -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}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user