mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 00:36:07 +03:00
terminal: style needs to be copied to new page on scroll
This commit is contained in:
@ -20,6 +20,8 @@ const Row = pagepkg.Row;
|
||||
const Cell = pagepkg.Cell;
|
||||
const Pin = PageList.Pin;
|
||||
|
||||
const log = std.log.scoped(.screen);
|
||||
|
||||
/// The general purpose allocator to use for all memory allocations.
|
||||
/// Unfortunately some screen operations do require allocation.
|
||||
alloc: Allocator,
|
||||
@ -524,9 +526,16 @@ pub fn cursorDownScroll(self: *Screen) !void {
|
||||
}
|
||||
}
|
||||
|
||||
// The newly created line needs to be styled according to the bg color
|
||||
// if it is set.
|
||||
if (self.cursor.style_id != style.default_id) {
|
||||
// We need to ensure our new page has our style.
|
||||
self.manualStyleUpdate() catch |err| {
|
||||
// This should never happen because if we're in a new
|
||||
// page then we should have space for one style.
|
||||
log.warn("error updating style on scroll err={}", .{err});
|
||||
};
|
||||
|
||||
// The newly created line needs to be styled according to
|
||||
// the bg color if it is set.
|
||||
if (self.cursor.style.bgCell()) |blank_cell| {
|
||||
const cell_current: [*]pagepkg.Cell = @ptrCast(self.cursor.page_cell);
|
||||
const cells = cell_current - self.cursor.x;
|
||||
@ -2505,6 +2514,33 @@ test "Screen: scrolling" {
|
||||
}
|
||||
}
|
||||
|
||||
test "Screen: scrolling across pages preserves style" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 10, 3, 1);
|
||||
defer s.deinit();
|
||||
try s.setAttribute(.{ .bold = {} });
|
||||
try s.testWriteString("1ABCD\n2EFGH\n3IJKL");
|
||||
const start_page = &s.pages.pages.last.?.data;
|
||||
|
||||
// Scroll down enough to go to another page
|
||||
const rem = start_page.capacity.rows - start_page.size.rows + 1;
|
||||
for (0..rem) |_| try s.cursorDownScroll();
|
||||
|
||||
// We need our page to change for this test o make sense. If this
|
||||
// assertion fails then the bug is in the test: we should be scrolling
|
||||
// above enough for a new page to show up.
|
||||
const page = &s.pages.pages.last.?.data;
|
||||
try testing.expect(start_page != page);
|
||||
|
||||
const styleval = page.styles.lookupId(
|
||||
page.memory,
|
||||
s.cursor.style_id,
|
||||
).?;
|
||||
try testing.expect(styleval.flags.bold);
|
||||
}
|
||||
|
||||
test "Screen: scroll down from 0" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@ -559,6 +559,24 @@ fn printCell(
|
||||
.protected = self.screen.cursor.protected,
|
||||
};
|
||||
|
||||
if (comptime std.debug.runtime_safety) {
|
||||
// We've had bugs around this, so let's add an assertion: every
|
||||
// style we use should be present in the style table.
|
||||
if (self.screen.cursor.style_id != style.default_id) {
|
||||
const page = &self.screen.cursor.page_pin.page.data;
|
||||
if (page.styles.lookupId(
|
||||
page.memory,
|
||||
self.screen.cursor.style_id,
|
||||
) == null) {
|
||||
log.err("can't find style page={X} id={}", .{
|
||||
@intFromPtr(&self.screen.cursor.page_pin.page.data),
|
||||
self.screen.cursor.style_id,
|
||||
});
|
||||
@panic("style not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the style ref count handling
|
||||
style_ref: {
|
||||
if (prev_style_id != style.default_id) {
|
||||
|
Reference in New Issue
Block a user