diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-04 16:32:43 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-04 16:32:43 +0300 |
| commit | 648afa1fd5b4c2eb74b4292b4eceeeb6d93016c1 (patch) | |
| tree | 368bce0f173319b98bce0e99f0c829fcd54520b3 /vendor/patches | |
| parent | f5f753c7286ff4cc30cfe3a9d48c053bfe2881c7 (diff) | |
fix: backport libghostty resize overflow fix
refs #465
Diffstat (limited to 'vendor/patches')
| -rw-r--r-- | vendor/patches/libghostty-vt/0001-backport-resizecols-cursor-subtraction.patch | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/vendor/patches/libghostty-vt/0001-backport-resizecols-cursor-subtraction.patch b/vendor/patches/libghostty-vt/0001-backport-resizecols-cursor-subtraction.patch new file mode 100644 index 00000000..1f8d0f36 --- /dev/null +++ b/vendor/patches/libghostty-vt/0001-backport-resizecols-cursor-subtraction.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: herdr maintainers <maintainers@herdr.dev> +Date: Thu, 4 Jun 2026 00:00:00 +0000 +Subject: [PATCH] backport resizeCols cursor subtraction saturation + +Backport ghostty-org/ghostty#12907 onto the vendored libghostty-vt source. +Shrink-both resize can leave the old cursor row past the new row count after +resizeWithoutReflow reduces self.rows. Saturating subtraction treats rows below +that cursor as zero instead of trapping in safety builds. + +Herdr issue: https://github.com/ogulcancelik/herdr/issues/465 +Upstream discussion: https://github.com/ghostty-org/ghostty/discussions/12905 +Upstream PR: https://github.com/ghostty-org/ghostty/pull/12907 +Vendored base: 0f7cd84b880b203c98683e520e84b9db0c5938d8 +--- + vendor/libghostty-vt/src/terminal/PageList.zig | 33 +++++++++++++++++++++-- + vendor/libghostty-vt/src/terminal/c/terminal.zig | 23 ++++++++++++++++ + 2 files changed, 54 insertions(+), 2 deletions(-) + +diff --git a/vendor/libghostty-vt/src/terminal/PageList.zig b/vendor/libghostty-vt/src/terminal/PageList.zig +index 0000000..0000000 100644 +--- a/vendor/libghostty-vt/src/terminal/PageList.zig ++++ b/vendor/libghostty-vt/src/terminal/PageList.zig +@@ -1059,7 +1059,7 @@ fn resizeCols( + break :cursor .{ + .tracked_pin = c.pin orelse try self.trackPin(p), + .untrack = c.pin == null, +- .remaining_rows = self.rows - c.y - 1, ++ .remaining_rows = self.rows -| (c.y + 1), + .wrapped_rows = wrapped, + }; + } else null; +@@ -1192,7 +1192,7 @@ fn resizeCols( + break :wrapped wrapped; + }; + +- const current = self.rows - active_pt.active.y - 1; ++ const current = self.rows -| (active_pt.active.y + 1); + + var req_rows = c.remaining_rows; + req_rows -|= wrapped -| c.wrapped_rows; +@@ -10828,6 +10828,37 @@ test "PageList resize (no reflow) less rows and cols" { + } + } + ++test "PageList resize less rows and cols cursor at bottom" { ++ const testing = std.testing; ++ const alloc = testing.allocator; ++ ++ var s = try init(alloc, 80, 24, 0); ++ defer s.deinit(); ++ ++ const cursor_pin = try s.trackPin(s.pin(.{ .active = .{ ++ .x = 0, ++ .y = s.rows - 1, ++ } }).?); ++ defer s.untrackPin(cursor_pin); ++ ++ // Shrink both axes so the original cursor.y is strictly past the new row ++ // count, after resizeWithoutReflow has already reduced self.rows. ++ try s.resize(.{ ++ .cols = 79, ++ .rows = 20, ++ .reflow = true, ++ .cursor = .{ .x = 0, .y = 23, .pin = cursor_pin }, ++ }); ++ try testing.expectEqual(@as(usize, 79), s.cols); ++ try testing.expectEqual(@as(usize, 20), s.rows); ++ ++ // remaining_rows saturates to 0, so the cursor lands on the new bottom row. ++ try testing.expectEqual(point.Point{ .active = .{ ++ .x = 0, ++ .y = s.rows - 1, ++ } }, s.pointFromPin(.active, cursor_pin.*).?); ++} ++ + test "PageList resize (no reflow) more rows and less cols" { + const testing = std.testing; + const alloc = testing.allocator; +diff --git a/vendor/libghostty-vt/src/terminal/c/terminal.zig b/vendor/libghostty-vt/src/terminal/c/terminal.zig +index 0000000..0000000 100644 +--- a/vendor/libghostty-vt/src/terminal/c/terminal.zig ++++ b/vendor/libghostty-vt/src/terminal/c/terminal.zig +@@ -1005,6 +1005,29 @@ test "resize invalid value" { + try testing.expectEqual(Result.invalid_value, resize(t, 80, 0, 9, 18)); + } + ++test "resize shrinks both axes with cursor at bottom" { ++ var t: Terminal = null; ++ try testing.expectEqual(Result.success, new( ++ &lib.alloc.test_allocator, ++ &t, ++ .{ ++ .cols = 80, ++ .rows = 24, ++ .max_scrollback = 0, ++ }, ++ )); ++ defer free(t); ++ ++ // CSI 24;1H parks the cursor on the bottom row. ++ const move = "\x1b[24;1H"; ++ vt_write(t, move, move.len); ++ ++ // Shrink both axes; pre-resize cursor.y sits past the new bottom row. ++ try testing.expectEqual(Result.success, resize(t, 79, 23, 8, 16)); ++ try testing.expectEqual(79, t.?.terminal.cols); ++ try testing.expectEqual(23, t.?.terminal.rows); ++} ++ + test "mode_get and mode_set" { + var t: Terminal = null; + try testing.expectEqual(Result.success, new( +-- +2.49.0 |
