mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Terminal: Reinitialize screens on scrollback reset
When resetting the terminal screen, the memory buffer allocated for the scrollback is now cleared by reinitializing the screen and falling back to the current method if any of the attempts to reinitialize fail. Closes #2464
This commit is contained in:

committed by
Mitchell Hashimoto

parent
c483c8c475
commit
e0c5bdc53b
@ -2621,12 +2621,59 @@ pub fn plainStringUnwrapped(self: *Terminal, alloc: Allocator) ![]const u8 {
|
||||
return try self.screen.dumpStringAllocUnwrapped(alloc, .{ .viewport = .{} });
|
||||
}
|
||||
|
||||
/// Full reset
|
||||
/// Full reset.
|
||||
///
|
||||
/// This will attempt to free the existing screen memory and allocate
|
||||
/// new screens but if that fails this will reuse the existing memory
|
||||
/// from the prior screens. In the latter case, memory may be wasted
|
||||
/// (since its unused) but it isn't leaked.
|
||||
pub fn fullReset(self: *Terminal) void {
|
||||
// Switch back to primary screen and clear it. We do not restore cursor
|
||||
// because see the next step...
|
||||
self.primaryScreen(.{ .clear_on_exit = true, .cursor_save = false });
|
||||
// Attempt to initialize new screens.
|
||||
var new_primary = Screen.init(
|
||||
self.screen.alloc,
|
||||
self.cols,
|
||||
self.rows,
|
||||
self.screen.pages.explicit_max_size,
|
||||
) catch |err| {
|
||||
log.warn("failed to allocate new primary screen, reusing old memory err={}", .{err});
|
||||
self.fallbackReset();
|
||||
return;
|
||||
};
|
||||
const new_secondary = Screen.init(
|
||||
self.secondary_screen.alloc,
|
||||
self.cols,
|
||||
self.rows,
|
||||
0,
|
||||
) catch |err| {
|
||||
log.warn("failed to allocate new secondary screen, reusing old memory err={}", .{err});
|
||||
new_primary.deinit();
|
||||
self.fallbackReset();
|
||||
return;
|
||||
};
|
||||
|
||||
// If we got here, both new screens were successfully allocated
|
||||
// and we can deinitialize the old screens.
|
||||
self.screen.deinit();
|
||||
self.secondary_screen.deinit();
|
||||
|
||||
// Replace with the newly allocated screens.
|
||||
self.screen = new_primary;
|
||||
self.secondary_screen = new_secondary;
|
||||
|
||||
self.resetCommonState();
|
||||
}
|
||||
|
||||
fn fallbackReset(self: *Terminal) void {
|
||||
// Clear existing screens without reallocation
|
||||
self.primaryScreen(.{ .clear_on_exit = true, .cursor_save = false });
|
||||
self.screen.clearSelection();
|
||||
self.eraseDisplay(.scrollback, false);
|
||||
self.eraseDisplay(.complete, false);
|
||||
self.screen.cursorAbsolute(0, 0);
|
||||
self.resetCommonState();
|
||||
}
|
||||
|
||||
fn resetCommonState(self: *Terminal) void {
|
||||
// We set the saved cursor to null and then restore. This will force
|
||||
// our cursor to go back to the default which will also move the cursor
|
||||
// to the top-left.
|
||||
@ -2640,7 +2687,6 @@ pub fn fullReset(self: *Terminal) void {
|
||||
self.modes = .{};
|
||||
self.flags = .{};
|
||||
self.tabstops.reset(TABSTOP_INTERVAL);
|
||||
self.screen.clearSelection();
|
||||
self.screen.kitty_keyboard = .{};
|
||||
self.secondary_screen.kitty_keyboard = .{};
|
||||
self.screen.protected_mode = .off;
|
||||
@ -2651,9 +2697,6 @@ pub fn fullReset(self: *Terminal) void {
|
||||
.right = self.cols - 1,
|
||||
};
|
||||
self.previous_char = null;
|
||||
self.eraseDisplay(.scrollback, false);
|
||||
self.eraseDisplay(.complete, false);
|
||||
self.screen.cursorAbsolute(0, 0);
|
||||
self.pwd.clearRetainingCapacity();
|
||||
self.status_display = .main;
|
||||
}
|
||||
|
Reference in New Issue
Block a user