diff --git a/kitty/graphics.c b/kitty/graphics.c index 858235cfb..4ff7f3d21 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -728,9 +728,14 @@ clear_filter_func(ImageRef *ref, Image UNUSED *img, const void UNUSED *data) { return ref->start_row + (int32_t)ref->effective_num_rows > 0; } +static inline bool +clear_all_filter_func(ImageRef *ref UNUSED, Image UNUSED *img, const void UNUSED *data) { + return true; +} + void -grman_clear(GraphicsManager *self) { - filter_refs(self, NULL, true, clear_filter_func); +grman_clear(GraphicsManager *self, bool all) { + filter_refs(self, NULL, true, all ? clear_all_filter_func : clear_filter_func); } static inline bool diff --git a/kitty/graphics.h b/kitty/graphics.h index f3c8bc048..2fe0b586a 100644 --- a/kitty/graphics.h +++ b/kitty/graphics.h @@ -83,7 +83,7 @@ typedef struct { } ScrollData; GraphicsManager* grman_alloc(); -void grman_clear(GraphicsManager*); +void grman_clear(GraphicsManager*, bool); const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty); bool grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float screen_left, float screen_top, float dx, float dy, unsigned int num_cols, unsigned int num_rows); void grman_scroll_images(GraphicsManager *self, const ScrollData*); diff --git a/kitty/history.c b/kitty/history.c index d1e16f017..dd94b3310 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -90,6 +90,12 @@ historybuf_mark_line_dirty(HistoryBuf *self, index_type y) { self->line_attrs[index_of(self, y)] |= TEXT_DIRTY_MASK; } +inline void +historybuf_clear(HistoryBuf *self) { + self->count = 0; + self->start_of_data = 0; +} + static inline index_type historybuf_push(HistoryBuf *self) { index_type idx = (self->start_of_data + self->count) % self->ynum; diff --git a/kitty/lineops.h b/kitty/lineops.h index b67ae5bd2..6e67247a6 100644 --- a/kitty/lineops.h +++ b/kitty/lineops.h @@ -79,3 +79,4 @@ void historybuf_init_line(HistoryBuf *self, index_type num, Line *l); void historybuf_mark_line_clean(HistoryBuf *self, index_type y); void historybuf_mark_line_dirty(HistoryBuf *self, index_type y); void historybuf_refresh_sprite_positions(HistoryBuf *self); +void historybuf_clear(HistoryBuf *self); diff --git a/kitty/screen.c b/kitty/screen.c index b8f378660..2a5bcb325 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -103,7 +103,7 @@ void screen_reset(Screen *self) { if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self); linebuf_clear(self->linebuf, BLANK_CHAR); - grman_clear(self->grman); + grman_clear(self->grman, false); self->modes = empty_modes; #define R(name) self->color_profile->overridden.name = 0 R(default_fg); R(default_bg); R(cursor_color); R(highlight_fg); R(highlight_bg); @@ -430,7 +430,7 @@ screen_handle_graphics_command(Screen *self, const GraphicsCommand *cmd, const u void screen_toggle_screen_buffer(Screen *self) { bool to_alt = self->linebuf == self->main_linebuf; - grman_clear(self->alt_grman); // always clear the alt buffer graphics to free up resources, since it has to be cleared when switching back to it anyway + grman_clear(self->alt_grman, true); // always clear the alt buffer graphics to free up resources, since it has to be cleared when switching back to it anyway if (to_alt) { linebuf_clear(self->alt_linebuf, BLANK_CHAR); screen_save_cursor(self); @@ -882,6 +882,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) { including cursor position. * ``2`` -- Erases complete display. All lines are erased and changed to single-width. Cursor does not move. + * ``3`` -- Erase complete display and scrollback buffer as well. :param bool private: when ``True`` character attributes are left unchanged */ unsigned int a, b; @@ -891,7 +892,8 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) { case 1: a = 0; b = self->cursor->y; break; case 2: - grman_clear(self->grman); + case 3: + grman_clear(self->grman, how == 3); a = 0; b = self->lines; break; default: return; @@ -911,6 +913,13 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) { if (how != 2) { screen_erase_in_line(self, how, private); } + if (how == 3 && self->linebuf == self->main_linebuf) { + historybuf_clear(self->historybuf); + if (self->scrolled_by != 0) { + self->scrolled_by = 0; + self->scroll_changed = true; + } + } } void