mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
terminal: fullReset uses the new screen reset methods
This commit is contained in:
@ -83,8 +83,8 @@ pub const Dirty = packed struct {
|
|||||||
/// The cursor position and style.
|
/// The cursor position and style.
|
||||||
pub const Cursor = struct {
|
pub const Cursor = struct {
|
||||||
// The x/y position within the viewport.
|
// The x/y position within the viewport.
|
||||||
x: size.CellCountInt,
|
x: size.CellCountInt = 0,
|
||||||
y: size.CellCountInt,
|
y: size.CellCountInt = 0,
|
||||||
|
|
||||||
/// The visual style of the cursor. This defaults to block because
|
/// The visual style of the cursor. This defaults to block because
|
||||||
/// it has to default to something, but users of this struct are
|
/// it has to default to something, but users of this struct are
|
||||||
@ -249,6 +249,50 @@ pub fn assertIntegrity(self: *const Screen) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset the screen according to the logic of a DEC RIS sequence.
|
||||||
|
///
|
||||||
|
/// - Clears the screen and attempts to reclaim memory.
|
||||||
|
/// - Moves the cursor to the top-left.
|
||||||
|
/// - Clears any cursor state: style, hyperlink, etc.
|
||||||
|
/// - Resets the charset
|
||||||
|
/// - Clears the selection
|
||||||
|
/// - Deletes all Kitty graphics
|
||||||
|
/// - Resets Kitty Keyboard settings
|
||||||
|
/// - Disables protection mode
|
||||||
|
///
|
||||||
|
pub fn reset(self: *Screen) void {
|
||||||
|
// Reset our pages
|
||||||
|
self.pages.reset();
|
||||||
|
|
||||||
|
// The above reset preserves tracked pins so we can still use
|
||||||
|
// our cursor pin, which should be at the top-left already.
|
||||||
|
const cursor_pin: *PageList.Pin = self.cursor.page_pin;
|
||||||
|
assert(cursor_pin.node == self.pages.pages.first.?);
|
||||||
|
assert(cursor_pin.x == 0);
|
||||||
|
assert(cursor_pin.y == 0);
|
||||||
|
const cursor_rac = cursor_pin.rowAndCell();
|
||||||
|
self.cursor.deinit(self.alloc);
|
||||||
|
self.cursor = .{
|
||||||
|
.page_pin = cursor_pin,
|
||||||
|
.page_row = cursor_rac.row,
|
||||||
|
.page_cell = cursor_rac.cell,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear kitty graphics
|
||||||
|
self.kitty_images.delete(
|
||||||
|
self.alloc,
|
||||||
|
undefined, // All image deletion doesn't need the terminal
|
||||||
|
.{ .all = true },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reset our basic state
|
||||||
|
self.saved_cursor = null;
|
||||||
|
self.charset = .{};
|
||||||
|
self.kitty_keyboard = .{};
|
||||||
|
self.protected_mode = .off;
|
||||||
|
self.clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
/// Clone the screen.
|
/// Clone the screen.
|
||||||
///
|
///
|
||||||
/// This will copy:
|
/// This will copy:
|
||||||
|
@ -2627,82 +2627,38 @@ pub fn plainStringUnwrapped(self: *Terminal, alloc: Allocator) ![]const u8 {
|
|||||||
|
|
||||||
/// Full reset.
|
/// Full reset.
|
||||||
///
|
///
|
||||||
/// This will attempt to free the existing screen memory and allocate
|
/// This will attempt to free the existing screen memory but if that fails
|
||||||
/// new screens but if that fails this will reuse the existing memory
|
/// this will reuse the existing memory. In the latter case, memory may
|
||||||
/// from the prior screens. In the latter case, memory may be wasted
|
/// be wasted (since its unused) but it isn't leaked.
|
||||||
/// (since its unused) but it isn't leaked.
|
|
||||||
pub fn fullReset(self: *Terminal) void {
|
pub fn fullReset(self: *Terminal) void {
|
||||||
// Attempt to initialize new screens.
|
// Reset our screens
|
||||||
var new_primary = Screen.init(
|
self.screen.reset();
|
||||||
self.screen.alloc,
|
self.secondary_screen.reset();
|
||||||
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
|
// Ensure we're back on primary screen
|
||||||
// and we can deinitialize the old screens.
|
if (self.active_screen != .primary) {
|
||||||
self.screen.deinit();
|
const old = self.screen;
|
||||||
self.secondary_screen.deinit();
|
self.screen = self.secondary_screen;
|
||||||
|
self.secondary_screen = old;
|
||||||
|
self.active_screen = .primary;
|
||||||
|
}
|
||||||
|
|
||||||
// Replace with the newly allocated screens.
|
// Rest our basic state
|
||||||
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.
|
|
||||||
self.screen.saved_cursor = null;
|
|
||||||
self.restoreCursor() catch |err| {
|
|
||||||
log.warn("restore cursor on primary screen failed err={}", .{err});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.screen.endHyperlink();
|
|
||||||
self.screen.charset = .{};
|
|
||||||
self.modes.reset();
|
self.modes.reset();
|
||||||
self.flags = .{};
|
self.flags = .{};
|
||||||
self.tabstops.reset(TABSTOP_INTERVAL);
|
self.tabstops.reset(TABSTOP_INTERVAL);
|
||||||
self.screen.kitty_keyboard = .{};
|
self.previous_char = null;
|
||||||
self.secondary_screen.kitty_keyboard = .{};
|
self.pwd.clearRetainingCapacity();
|
||||||
self.screen.protected_mode = .off;
|
self.status_display = .main;
|
||||||
self.scrolling_region = .{
|
self.scrolling_region = .{
|
||||||
.top = 0,
|
.top = 0,
|
||||||
.bottom = self.rows - 1,
|
.bottom = self.rows - 1,
|
||||||
.left = 0,
|
.left = 0,
|
||||||
.right = self.cols - 1,
|
.right = self.cols - 1,
|
||||||
};
|
};
|
||||||
self.previous_char = null;
|
|
||||||
self.pwd.clearRetainingCapacity();
|
// Always mark dirty so we redraw everything
|
||||||
self.status_display = .main;
|
self.flags.dirty.clear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the point is dirty, used for testing.
|
/// Returns true if the point is dirty, used for testing.
|
||||||
|
Reference in New Issue
Block a user