This commit is contained in:
Kovid Goyal 2023-02-10 09:27:19 +05:30
commit 94ab58343a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 38 additions and 18 deletions

View File

@ -64,6 +64,11 @@ init_overlay_line(Screen *self, index_type columns) {
return true; return true;
} }
static void save_overlay_line(Screen *self, const char* func_name);
static void restore_overlay_line(Screen *self);
static void deactivate_overlay_line(Screen *self);
static void clear_saved_overlay_line(Screen *self);
#define RESET_CHARSETS \ #define RESET_CHARSETS \
self->g0_charset = translation_table(0); \ self->g0_charset = translation_table(0); \
self->g1_charset = self->g0_charset; \ self->g1_charset = self->g0_charset; \
@ -140,6 +145,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
init_tabstops(self->alt_tabstops, self->columns); init_tabstops(self->alt_tabstops, self->columns);
self->key_encoding_flags = self->main_key_encoding_flags; self->key_encoding_flags = self->main_key_encoding_flags;
if (!init_overlay_line(self, self->columns)) { Py_CLEAR(self); return NULL; } if (!init_overlay_line(self, self->columns)) { Py_CLEAR(self); return NULL; }
clear_saved_overlay_line(self);
self->hyperlink_pool = alloc_hyperlink_pool(); self->hyperlink_pool = alloc_hyperlink_pool();
if (!self->hyperlink_pool) { Py_CLEAR(self); return PyErr_NoMemory(); } if (!self->hyperlink_pool) { Py_CLEAR(self); return PyErr_NoMemory(); }
self->as_ansi_buf.hyperlink_pool = self->hyperlink_pool; self->as_ansi_buf.hyperlink_pool = self->hyperlink_pool;
@ -147,15 +153,14 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
return (PyObject*) self; return (PyObject*) self;
} }
static void deactivate_overlay_line(Screen *self);
static Line* range_line_(Screen *self, int y); static Line* range_line_(Screen *self, int y);
void void
screen_reset(Screen *self) { screen_reset(Screen *self) {
if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self, true, true); if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self, true, true);
if (self->overlay_line.is_active) deactivate_overlay_line(self); if (self->overlay_line.is_active) deactivate_overlay_line(self);
clear_saved_overlay_line(self);
Py_CLEAR(self->last_reported_cwd); Py_CLEAR(self->last_reported_cwd);
Py_CLEAR(self->overlay_line.save.overlay_text);
self->render_unfocused_cursor = false; self->render_unfocused_cursor = false;
memset(self->main_key_encoding_flags, 0, sizeof(self->main_key_encoding_flags)); memset(self->main_key_encoding_flags, 0, sizeof(self->main_key_encoding_flags));
memset(self->alt_key_encoding_flags, 0, sizeof(self->alt_key_encoding_flags)); memset(self->alt_key_encoding_flags, 0, sizeof(self->alt_key_encoding_flags));
@ -277,7 +282,6 @@ index_selection(const Screen *self, Selections *selections, bool up) {
#define INDEX_DOWN \ #define INDEX_DOWN \
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
linebuf_reverse_index(self->linebuf, top, bottom); \ linebuf_reverse_index(self->linebuf, top, bottom); \
linebuf_clear_line(self->linebuf, top, true); \ linebuf_clear_line(self->linebuf, top, true); \
if (self->linebuf == self->main_linebuf && self->last_visited_prompt.is_set) { \ if (self->linebuf == self->main_linebuf && self->last_visited_prompt.is_set) { \
@ -332,7 +336,7 @@ found:
static bool static bool
screen_resize(Screen *self, unsigned int lines, unsigned int columns) { screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
if (self->overlay_line.is_active) deactivate_overlay_line(self); if (self->overlay_line.is_active) save_overlay_line(self, __func__);
lines = MAX(1u, lines); columns = MAX(1u, columns); lines = MAX(1u, lines); columns = MAX(1u, columns);
bool is_main = self->linebuf == self->main_linebuf; bool is_main = self->linebuf == self->main_linebuf;
@ -422,6 +426,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
self->linebuf->line->cpu_cells[0].ch = 0; self->linebuf->line->cpu_cells[0].ch = 0;
self->cursor->x = 0; self->cursor->x = 0;
} }
restore_overlay_line(self);
return true; return true;
} }
@ -711,6 +716,7 @@ draw_codepoint(Screen *self, char_type och, bool from_input_stream) {
void void
screen_draw_overlay_text(Screen *self, const char *utf8_text) { screen_draw_overlay_text(Screen *self, const char *utf8_text) {
if (self->overlay_line.is_active) deactivate_overlay_line(self); if (self->overlay_line.is_active) deactivate_overlay_line(self);
if (self->overlay_line.save.overlay_text) clear_saved_overlay_line(self);
if (!utf8_text || !utf8_text[0]) return; if (!utf8_text || !utf8_text[0]) return;
Line *line = range_line_(self, self->cursor->y); Line *line = range_line_(self, self->cursor->y);
if (!line) return; if (!line) return;
@ -761,15 +767,21 @@ save_overlay_line(Screen *self, const char* func_name) {
static void static void
restore_overlay_line(Screen *self) { restore_overlay_line(Screen *self) {
if (self->overlay_line.save.overlay_text) { if (self->overlay_line.save.overlay_text && screen_is_cursor_visible(self)) {
debug("Received input from child (%s) while overlay active. Overlay contents: %s\n", self->overlay_line.save.func_name, PyUnicode_AsUTF8(self->overlay_line.save.overlay_text)); debug("Received input from child (%s) while overlay active. Overlay contents: %s\n", self->overlay_line.save.func_name, PyUnicode_AsUTF8(self->overlay_line.save.overlay_text));
screen_draw_overlay_text(self, PyUnicode_AsUTF8(self->overlay_line.save.overlay_text)); screen_draw_overlay_text(self, PyUnicode_AsUTF8(self->overlay_line.save.overlay_text));
Py_CLEAR(self->overlay_line.save.overlay_text); clear_saved_overlay_line(self);
update_ime_position_for_window(self->window_id, false, 0); update_ime_position_for_window(self->window_id, false, 0);
} }
} }
static void restore_overlay_line_from_cleanup(Screen **self) { static void
clear_saved_overlay_line(Screen *self) {
Py_CLEAR(self->overlay_line.save.overlay_text);
}
static void
restore_overlay_line_from_cleanup(Screen **self) {
restore_overlay_line(*self); restore_overlay_line(*self);
} }
@ -1007,11 +1019,12 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) {
case DECTCEM: case DECTCEM:
if(!val) { if(!val) {
save_overlay_line(self, __func__); save_overlay_line(self, __func__);
} self->modes.mDECTCEM = val;
else { } else {
self->modes.mDECTCEM = val;
if (self->overlay_line.is_active && !self->overlay_line.save.overlay_text) save_overlay_line(self, __func__);
restore_overlay_line(self); restore_overlay_line(self);
} }
self->modes.mDECTCEM = val;
break; break;
case DECSCNM: case DECSCNM:
// Render screen in reverse video // Render screen in reverse video
@ -1177,6 +1190,7 @@ screen_backspace(Screen *self) {
void void
screen_tab(Screen *self) { screen_tab(Screen *self) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Move to the next tab space, or the end of the screen if there aren't anymore left. // Move to the next tab space, or the end of the screen if there aren't anymore left.
unsigned int found = 0; unsigned int found = 0;
for (unsigned int i = self->cursor->x + 1; i < self->columns; i++) { for (unsigned int i = self->cursor->x + 1; i < self->columns; i++) {
@ -1208,6 +1222,7 @@ screen_tab(Screen *self) {
void void
screen_backtab(Screen *self, unsigned int count) { screen_backtab(Screen *self, unsigned int count) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Move back count tabs // Move back count tabs
if (!count) count = 1; if (!count) count = 1;
int i; int i;
@ -1259,6 +1274,7 @@ screen_cursor_forward(Screen *self, unsigned int count/*=1*/) {
void void
screen_cursor_up(Screen *self, unsigned int count/*=1*/, bool do_carriage_return/*=false*/, int move_direction/*=-1*/) { screen_cursor_up(Screen *self, unsigned int count/*=1*/, bool do_carriage_return/*=false*/, int move_direction/*=-1*/) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
bool in_margins = cursor_within_margins(self); bool in_margins = cursor_within_margins(self);
if (count == 0) count = 1; if (count == 0) count = 1;
if (move_direction < 0 && count > self->cursor->y) self->cursor->y = 0; if (move_direction < 0 && count > self->cursor->y) self->cursor->y = 0;
@ -1284,6 +1300,7 @@ screen_cursor_down1(Screen *self, unsigned int count/*=1*/) {
void void
screen_cursor_to_column(Screen *self, unsigned int column) { screen_cursor_to_column(Screen *self, unsigned int column) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
unsigned int x = MAX(column, 1u) - 1; unsigned int x = MAX(column, 1u) - 1;
if (x != self->cursor->x) { if (x != self->cursor->x) {
self->cursor->x = x; self->cursor->x = x;
@ -1292,7 +1309,6 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
} }
#define INDEX_UP \ #define INDEX_UP \
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
linebuf_index(self->linebuf, top, bottom); \ linebuf_index(self->linebuf, top, bottom); \
INDEX_GRAPHICS(-1) \ INDEX_GRAPHICS(-1) \
if (self->linebuf == self->main_linebuf && self->margin_top == 0) { \ if (self->linebuf == self->main_linebuf && self->margin_top == 0) { \
@ -1311,6 +1327,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
void void
screen_index(Screen *self) { screen_index(Screen *self) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Move cursor down one line, scrolling screen if needed // Move cursor down one line, scrolling screen if needed
unsigned int top = self->margin_top, bottom = self->margin_bottom; unsigned int top = self->margin_top, bottom = self->margin_bottom;
if (self->cursor->y == bottom) { if (self->cursor->y == bottom) {
@ -1320,6 +1337,7 @@ screen_index(Screen *self) {
void void
screen_scroll(Screen *self, unsigned int count) { screen_scroll(Screen *self, unsigned int count) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Scroll the screen up by count lines, not moving the cursor // Scroll the screen up by count lines, not moving the cursor
unsigned int top = self->margin_top, bottom = self->margin_bottom; unsigned int top = self->margin_top, bottom = self->margin_bottom;
while (count > 0) { while (count > 0) {
@ -1330,6 +1348,7 @@ screen_scroll(Screen *self, unsigned int count) {
void void
screen_reverse_index(Screen *self) { screen_reverse_index(Screen *self) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Move cursor up one line, scrolling screen if needed // Move cursor up one line, scrolling screen if needed
unsigned int top = self->margin_top, bottom = self->margin_bottom; unsigned int top = self->margin_top, bottom = self->margin_bottom;
if (self->cursor->y == top) { if (self->cursor->y == top) {
@ -1339,6 +1358,7 @@ screen_reverse_index(Screen *self) {
static void static void
_reverse_scroll(Screen *self, unsigned int count, bool fill_from_scrollback) { _reverse_scroll(Screen *self, unsigned int count, bool fill_from_scrollback) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
// Scroll the screen down by count lines, not moving the cursor // Scroll the screen down by count lines, not moving the cursor
unsigned int top = self->margin_top, bottom = self->margin_bottom; unsigned int top = self->margin_top, bottom = self->margin_bottom;
fill_from_scrollback = fill_from_scrollback && self->linebuf == self->main_linebuf; fill_from_scrollback = fill_from_scrollback && self->linebuf == self->main_linebuf;
@ -1375,7 +1395,6 @@ screen_carriage_return(Screen *self) {
void void
screen_linefeed(Screen *self) { screen_linefeed(Screen *self) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
bool in_margins = cursor_within_margins(self); bool in_margins = cursor_within_margins(self);
screen_index(self); screen_index(self);
if (self->modes.mLNM) screen_carriage_return(self); if (self->modes.mLNM) screen_carriage_return(self);
@ -1429,7 +1448,7 @@ copy_specific_mode(Screen *self, unsigned int mode, const ScreenModes *src, Scre
SIMPLE_MODE(BRACKETED_PASTE) SIMPLE_MODE(BRACKETED_PASTE)
SIMPLE_MODE(FOCUS_TRACKING) SIMPLE_MODE(FOCUS_TRACKING)
SIMPLE_MODE(DECCKM) SIMPLE_MODE(DECCKM)
SIMPLE_MODE(DECTCEM) SIDE_EFFECTS(DECTCEM) // side effect: redraw IME overlay line
SIMPLE_MODE(DECAWM) SIMPLE_MODE(DECAWM)
case MOUSE_BUTTON_TRACKING: case MOUSE_MOTION_TRACKING: case MOUSE_MOVE_TRACKING: case MOUSE_BUTTON_TRACKING: case MOUSE_MOTION_TRACKING: case MOUSE_MOVE_TRACKING:
dest->mouse_tracking_mode = src->mouse_tracking_mode; break; dest->mouse_tracking_mode = src->mouse_tracking_mode; break;
@ -1484,6 +1503,7 @@ screen_save_modes(Screen *self) {
void void
screen_restore_cursor(Screen *self) { screen_restore_cursor(Screen *self) {
MOVE_OVERLAY_LINE_WITH_CURSOR;
Savepoint *sp = self->linebuf == self->main_linebuf ? &self->main_savepoint : &self->alt_savepoint; Savepoint *sp = self->linebuf == self->main_linebuf ? &self->main_savepoint : &self->alt_savepoint;
if (!sp->is_valid) { if (!sp->is_valid) {
screen_cursor_position(self, 1, 1); screen_cursor_position(self, 1, 1);