mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +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 Cell = pagepkg.Cell;
|
||||||
const Pin = PageList.Pin;
|
const Pin = PageList.Pin;
|
||||||
|
|
||||||
|
const log = std.log.scoped(.screen);
|
||||||
|
|
||||||
/// The general purpose allocator to use for all memory allocations.
|
/// The general purpose allocator to use for all memory allocations.
|
||||||
/// Unfortunately some screen operations do require allocation.
|
/// Unfortunately some screen operations do require allocation.
|
||||||
alloc: Allocator,
|
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) {
|
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| {
|
if (self.cursor.style.bgCell()) |blank_cell| {
|
||||||
const cell_current: [*]pagepkg.Cell = @ptrCast(self.cursor.page_cell);
|
const cell_current: [*]pagepkg.Cell = @ptrCast(self.cursor.page_cell);
|
||||||
const cells = cell_current - self.cursor.x;
|
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" {
|
test "Screen: scroll down from 0" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
@ -559,6 +559,24 @@ fn printCell(
|
|||||||
.protected = self.screen.cursor.protected,
|
.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
|
// Handle the style ref count handling
|
||||||
style_ref: {
|
style_ref: {
|
||||||
if (prev_style_id != style.default_id) {
|
if (prev_style_id != style.default_id) {
|
||||||
|
Reference in New Issue
Block a user