mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
surface: calculate scroll amount directly from yoff/xoff for non-precision scrolls
Calculate the scroll amount for non-precision scrolls as a direct multiple of yoff. This fixes an issue where Ghostty sends scroll wheel events (or arrow keys if in alternate scroll mode) that are variable, dependent on the screen size. I checked multiple terminals, and each responds to a single wheel click by sending only a single wheel / arrow key - independent of screen size. ```sh printf "\x1b[?1049h" printf "\x1b[?1007h" cat -v ``` Using the above procedure, with varying screen sizes: ``` # 50% Screen height | terminal | arrows keys sent| wheels events sent| |------------|-----------------|-------------------| | alacritty | 3 | 1 | | foot | 3 | 1 | | xterm | 5 | 1 | | kitty | 3 | 1 | | ghostty | 2 | 2 | # 100% Screen height | terminal | arrows keys sent| wheels events sent| |------------|-----------------|-------------------| | alacritty | 3 | 1 | | foot | 3 | 1 | | xterm | 5 | 1 | | kitty | 5 | 1 | | ghostty | 3 | 3 | ``` Both ghostty and kitty scale the number of arrow keys sent in proportion to the screen size. However, when mouse reporting is on, only ghostty does this. This commit makes Ghostty behave like foot, and more generally removes the dependence on screen size.
This commit is contained in:
@ -2348,22 +2348,12 @@ pub fn scrollCallback(
|
|||||||
if (self.mouse.hidden) self.showMouse();
|
if (self.mouse.hidden) self.showMouse();
|
||||||
|
|
||||||
const y: ScrollAmount = if (yoff == 0) .{} else y: {
|
const y: ScrollAmount = if (yoff == 0) .{} else y: {
|
||||||
// Non-precision scrolling is easy to calculate. We don't use
|
// Non-precision scrolls don't accumulate. We cast that raw yoff to an isize and interpret
|
||||||
// the given offset at all and instead just treat a positive
|
// it as the number of lines to scroll.
|
||||||
// as a scroll up and a negative as a scroll down and scroll in
|
|
||||||
// steps.
|
|
||||||
if (!scroll_mods.precision) {
|
if (!scroll_mods.precision) {
|
||||||
// Calculate our magnitude of scroll. This is constant (not
|
// Calculate our magnitude of scroll. This is a direct multiple of yoff
|
||||||
// dependent on yoff).
|
const y_delta_f64: f64 = @round(yoff * self.config.mouse_scroll_multiplier);
|
||||||
const grid_size = self.size.grid();
|
const y_delta_isize: isize = @intFromFloat(y_delta_f64);
|
||||||
const grid_rows_f64: f64 = @floatFromInt(grid_size.rows);
|
|
||||||
const y_delta_f64: f64 = @round((grid_rows_f64 * self.config.mouse_scroll_multiplier) / 15.0);
|
|
||||||
const y_delta_usize: usize = @max(1, @as(usize, @intFromFloat(y_delta_f64)));
|
|
||||||
|
|
||||||
// Calculate our direction of scroll based on the sign of yoff.
|
|
||||||
const y_sign: isize = if (yoff >= 0) 1 else -1;
|
|
||||||
const y_delta_isize: isize = y_sign * @as(isize, @intCast(y_delta_usize));
|
|
||||||
|
|
||||||
break :y .{ .delta = y_delta_isize };
|
break :y .{ .delta = y_delta_isize };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2404,10 +2394,8 @@ pub fn scrollCallback(
|
|||||||
// For detailed comments see the y calculation above.
|
// For detailed comments see the y calculation above.
|
||||||
const x: ScrollAmount = if (xoff == 0) .{} else x: {
|
const x: ScrollAmount = if (xoff == 0) .{} else x: {
|
||||||
if (!scroll_mods.precision) {
|
if (!scroll_mods.precision) {
|
||||||
const x_delta_f64: f64 = @round(1 * self.config.mouse_scroll_multiplier);
|
const x_delta_f64: f64 = @round(xoff * self.config.mouse_scroll_multiplier);
|
||||||
const x_delta_usize: usize = @max(1, @as(usize, @intFromFloat(x_delta_f64)));
|
const x_delta_isize: isize = @intFromFloat(x_delta_f64);
|
||||||
const x_sign: isize = if (xoff >= 0) 1 else -1;
|
|
||||||
const x_delta_isize: isize = x_sign * @as(isize, @intCast(x_delta_usize));
|
|
||||||
break :x .{ .delta = x_delta_isize };
|
break :x .{ .delta = x_delta_isize };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user