mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-10 19:29:37 +00:00
core: fix PageList.scroll using wrong type for row offset (#13048)
Changes `PageList.scroll` to use `usize` as the type for the number of remaining rows when trying to find a specific row in the list of pages. Previously `CellCountInt=u16` was used, but the row offset can be larger than `maxInt(u16)=65535`, in which case the scroll operation would fail. Fixes #13000 where scrolling does not work correctly in the GTK app with a large scrollback history. E.g. nothing happens when you click in the middle of the scrollbar. Note that this problem only manifests at millions of lines of history instead of already when the row offset overflows `u16`. The reason for that is that GTK often emits multiple scroll adjustments, the first of which is usually close enough to the current position to not overflow `u16`. The other scroll adjustments are then handled by the fast path in `PageList.scroll` that works correctly. #### AI Disclosure No AI was used.
This commit is contained in:
@@ -2582,18 +2582,15 @@ pub fn scroll(self: *PageList, behavior: Scroll) void {
|
||||
if (n < midpoint) {
|
||||
// Iterate forward from the first node.
|
||||
var node_it = self.pages.first;
|
||||
var rem: size.CellCountInt = std.math.cast(
|
||||
size.CellCountInt,
|
||||
n,
|
||||
) orelse {
|
||||
self.viewport = .active;
|
||||
break :row;
|
||||
};
|
||||
var rem: usize = n;
|
||||
while (node_it) |node| : (node_it = node.next) {
|
||||
if (rem < node.data.size.rows) {
|
||||
self.viewport_pin.* = .{
|
||||
.node = node,
|
||||
.y = rem,
|
||||
.y = std.math.cast(size.CellCountInt, rem) orelse {
|
||||
self.viewport = .active;
|
||||
break :row;
|
||||
},
|
||||
};
|
||||
break :row;
|
||||
}
|
||||
@@ -2603,18 +2600,15 @@ pub fn scroll(self: *PageList, behavior: Scroll) void {
|
||||
} else {
|
||||
// Iterate backwards from the last node.
|
||||
var node_it = self.pages.last;
|
||||
var rem: size.CellCountInt = std.math.cast(
|
||||
size.CellCountInt,
|
||||
self.total_rows - n,
|
||||
) orelse {
|
||||
self.viewport = .active;
|
||||
break :row;
|
||||
};
|
||||
var rem: usize = self.total_rows - n;
|
||||
while (node_it) |node| : (node_it = node.prev) {
|
||||
if (rem <= node.data.size.rows) {
|
||||
self.viewport_pin.* = .{
|
||||
.node = node,
|
||||
.y = node.data.size.rows - rem,
|
||||
.y = std.math.cast(size.CellCountInt, node.data.size.rows - rem) orelse {
|
||||
self.viewport = .active;
|
||||
break :row;
|
||||
},
|
||||
};
|
||||
break :row;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user