mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Fold ancillary window changes into main redraw.
This fixes a long-standing inconsistency in updates to the terminal window: redrawing of actual text was deferred for 1/50 second, but all the other kinds of change the terminal can make to the window (position, size, z-order, title, mouse pointer shape, scrollbar...) were enacted immediately. In particular, this could mean that two updates requested by the terminal output stream happened in reverse order. Now they're all done as part of term_update, which should mean that things requested in the same chunk of terminal input happen at the same time, or at the very least, not in reverse order compared to the order the requests came in. Also, the same timer-based UPDATE_DELAY mechanism that applies to the text updates now applies to all the other window modifications, which should prevent any of those from being the limiting factor to how fast this terminal implementation can process input data (which is exactly why I set up that system for the main text update). This makes everything happen with a bit more latency, but I'm about to reverse that in a follow-up commit.
This commit is contained in:
parent
99dfc66457
commit
d74308e90e
228
terminal.c
228
terminal.c
@ -1357,7 +1357,8 @@ static void power_on(Terminal *term, bool clear)
|
||||
term->xterm_extended_mouse = false;
|
||||
term->urxvt_extended_mouse = false;
|
||||
win_set_raw_mouse_mode(term->win, false);
|
||||
win_set_raw_mouse_mode_pointer(term->win, false);
|
||||
term->win_pointer_shape_pending = true;
|
||||
term->win_pointer_shape_raw = false;
|
||||
term->bracketed_paste = false;
|
||||
term->srm_echo = false;
|
||||
{
|
||||
@ -1382,6 +1383,7 @@ static void power_on(Terminal *term, bool clear)
|
||||
term->curs.x = 0;
|
||||
term_schedule_tblink(term);
|
||||
term_schedule_cblink(term);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1391,8 +1393,55 @@ void term_update(Terminal *term)
|
||||
{
|
||||
term->window_update_pending = false;
|
||||
|
||||
if (term->win_move_pending) {
|
||||
win_move(term->win, term->win_move_pending_x,
|
||||
term->win_move_pending_y);
|
||||
term->win_move_pending = false;
|
||||
}
|
||||
if (term->win_resize_pending) {
|
||||
win_request_resize(term->win, term->win_resize_pending_w,
|
||||
term->win_resize_pending_h);
|
||||
term->win_resize_pending = false;
|
||||
}
|
||||
if (term->win_zorder_pending) {
|
||||
win_set_zorder(term->win, term->win_zorder_top);
|
||||
term->win_zorder_pending = false;
|
||||
}
|
||||
if (term->win_minimise_pending) {
|
||||
win_set_minimised(term->win, term->win_minimise_enable);
|
||||
term->win_minimise_pending = false;
|
||||
}
|
||||
if (term->win_maximise_pending) {
|
||||
win_set_maximised(term->win, term->win_maximise_enable);
|
||||
term->win_maximise_pending = false;
|
||||
}
|
||||
if (term->win_title_pending) {
|
||||
win_set_title(term->win, term->window_title);
|
||||
term->win_title_pending = false;
|
||||
}
|
||||
if (term->win_icon_title_pending) {
|
||||
win_set_icon_title(term->win, term->icon_title);
|
||||
term->win_icon_title_pending = false;
|
||||
}
|
||||
if (term->win_pointer_shape_pending) {
|
||||
win_set_raw_mouse_mode_pointer(term->win, term->win_pointer_shape_raw);
|
||||
term->win_pointer_shape_pending = false;
|
||||
}
|
||||
if (term->win_refresh_pending) {
|
||||
win_refresh(term->win);
|
||||
term->win_refresh_pending = false;
|
||||
}
|
||||
if (term->win_palette_pending) {
|
||||
unsigned start = term->win_palette_pending_min;
|
||||
unsigned ncolours = term->win_palette_pending_limit - start;
|
||||
win_palette_set(term->win, start, ncolours, term->palette + start);
|
||||
term->win_palette_pending = false;
|
||||
}
|
||||
|
||||
if (win_setup_draw_ctx(term->win)) {
|
||||
bool need_sbar_update = term->seen_disp_event;
|
||||
bool need_sbar_update = term->seen_disp_event ||
|
||||
term->win_scrollbar_update_pending;
|
||||
term->win_scrollbar_update_pending = false;
|
||||
if (term->seen_disp_event && term->scroll_on_disp) {
|
||||
term->disptop = 0; /* return to main screen */
|
||||
term->seen_disp_event = false;
|
||||
@ -1603,7 +1652,8 @@ void term_reconfig(Terminal *term, Conf *conf)
|
||||
if (strcmp(old_title, new_title)) {
|
||||
sfree(term->window_title);
|
||||
term->window_title = dupstr(new_title);
|
||||
win_set_title(term->win, term->window_title);
|
||||
term->win_title_pending = true;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1690,9 +1740,11 @@ void term_clrsb(Terminal *term)
|
||||
term->alt_sblines = 0;
|
||||
|
||||
/*
|
||||
* Update the scrollbar to reflect the new state of the world.
|
||||
* The scrollbar will need updating to reflect the new state of
|
||||
* the world.
|
||||
*/
|
||||
update_sbar(term);
|
||||
term->win_scrollbar_update_pending = true;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
const optionalrgb optionalrgb_none = {0, 0, 0, 0};
|
||||
@ -1712,8 +1764,8 @@ void term_setup_window_titles(Terminal *term, const char *title_hostname)
|
||||
term->window_title = dupstr(appname);
|
||||
term->icon_title = dupstr(term->window_title);
|
||||
}
|
||||
win_set_title(term->win, term->window_title);
|
||||
win_set_icon_title(term->win, term->icon_title);
|
||||
term->win_title_pending = true;
|
||||
term->win_icon_title_pending = true;
|
||||
}
|
||||
|
||||
static void palette_rebuild(Terminal *term)
|
||||
@ -1747,13 +1799,14 @@ static void palette_rebuild(Terminal *term)
|
||||
|
||||
if (min_changed <= max_changed) {
|
||||
/*
|
||||
* At least one colour changed, so pass the result back to the
|
||||
* TermWin. This also requires invalidating the rest of the
|
||||
* window, because usually all the text will need redrawing in
|
||||
* the new colours.
|
||||
* At least one colour changed, so schedule a redraw event to
|
||||
* pass the result back to the TermWin. This also requires
|
||||
* invalidating the rest of the window, because usually all
|
||||
* the text will need redrawing in the new colours.
|
||||
*/
|
||||
win_palette_set(term->win, min_changed, max_changed - min_changed + 1,
|
||||
term->palette + min_changed);
|
||||
term->win_palette_pending = true;
|
||||
term->win_palette_pending_min = min_changed;
|
||||
term->win_palette_pending_limit = max_changed + 1;
|
||||
term_invalidate(term);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
@ -1921,6 +1974,18 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
|
||||
term->winpos_x = term->winpos_y = 0;
|
||||
term->winpixsize_x = term->winpixsize_y = 0;
|
||||
|
||||
term->win_move_pending = false;
|
||||
term->win_resize_pending = false;
|
||||
term->win_zorder_pending = false;
|
||||
term->win_minimise_pending = false;
|
||||
term->win_maximise_pending = false;
|
||||
term->win_title_pending = false;
|
||||
term->win_icon_title_pending = false;
|
||||
term->win_pointer_shape_pending = false;
|
||||
term->win_refresh_pending = false;
|
||||
term->win_scrollbar_update_pending = false;
|
||||
term->win_palette_pending = false;
|
||||
|
||||
palette_reset(term, false);
|
||||
|
||||
return term;
|
||||
@ -2176,8 +2241,8 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
|
||||
|
||||
swap_screen(term, save_alt_which, false, false);
|
||||
|
||||
update_sbar(term);
|
||||
term_update(term);
|
||||
term->win_scrollbar_update_pending = true;
|
||||
term_schedule_update(term);
|
||||
if (term->backend)
|
||||
backend_size(term->backend, term->cols, term->rows);
|
||||
}
|
||||
@ -2830,7 +2895,9 @@ static void term_update_raw_mouse_mode(Terminal *term)
|
||||
{
|
||||
bool want_raw = (term->xterm_mouse != 0 && !term->xterm_mouse_forbidden);
|
||||
win_set_raw_mouse_mode(term->win, want_raw);
|
||||
win_set_raw_mouse_mode_pointer(term->win, want_raw);
|
||||
term->win_pointer_shape_pending = true;
|
||||
term->win_pointer_shape_raw = want_raw;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2856,8 +2923,12 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state)
|
||||
break;
|
||||
case 3: /* DECCOLM: 80/132 columns */
|
||||
deselect(term);
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(term->win, state ? 132 : 80, term->rows);
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w = state ? 132 : 80;
|
||||
term->win_resize_pending_h = term->rows;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
term->reset_132 = state;
|
||||
term->alt_t = term->marg_t = 0;
|
||||
term->alt_b = term->marg_b = term->rows - 1;
|
||||
@ -2978,9 +3049,10 @@ static void do_osc(Terminal *term)
|
||||
case 0:
|
||||
case 1:
|
||||
if (!term->no_remote_wintitle) {
|
||||
win_set_icon_title(term->win, term->osc_string);
|
||||
sfree(term->icon_title);
|
||||
term->icon_title = dupstr(term->osc_string);
|
||||
term->win_icon_title_pending = true;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
if (term->esc_args[0] == 1)
|
||||
break;
|
||||
@ -2988,9 +3060,10 @@ static void do_osc(Terminal *term)
|
||||
case 2:
|
||||
case 21:
|
||||
if (!term->no_remote_wintitle) {
|
||||
win_set_title(term->win, term->osc_string);
|
||||
sfree(term->window_title);
|
||||
term->window_title = dupstr(term->osc_string);
|
||||
term->win_title_pending = true;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@ -3861,8 +3934,12 @@ static void term_out(Terminal *term)
|
||||
if (term->ldisc) /* cause ldisc to notice changes */
|
||||
ldisc_echoedit_update(term->ldisc);
|
||||
if (term->reset_132) {
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(term->win, 80, term->rows);
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w = 80;
|
||||
term->win_resize_pending_h = term->rows;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
term->reset_132 = false;
|
||||
}
|
||||
if (term->scroll_on_disp)
|
||||
@ -4497,9 +4574,13 @@ static void term_out(Terminal *term)
|
||||
&& (term->esc_args[0] < 1 ||
|
||||
term->esc_args[0] >= 24)) {
|
||||
compatibility(VT340TEXT);
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(term->win, term->cols,
|
||||
def(term->esc_args[0], 24));
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w = term->cols;
|
||||
term->win_resize_pending_h =
|
||||
def(term->esc_args[0], 24);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
deselect(term);
|
||||
} else if (term->esc_nargs >= 1 &&
|
||||
term->esc_args[0] >= 1 &&
|
||||
@ -4511,17 +4592,25 @@ static void term_out(Terminal *term)
|
||||
char buf[80];
|
||||
const char *p;
|
||||
case 1:
|
||||
win_set_minimised(term->win, false);
|
||||
term->win_minimise_pending = true;
|
||||
term->win_minimise_enable = false;
|
||||
term_schedule_update(term);
|
||||
break;
|
||||
case 2:
|
||||
win_set_minimised(term->win, true);
|
||||
term->win_minimise_pending = true;
|
||||
term->win_minimise_enable = true;
|
||||
term_schedule_update(term);
|
||||
break;
|
||||
case 3:
|
||||
if (term->esc_nargs >= 3) {
|
||||
if (!term->no_remote_resize)
|
||||
win_move(term->win,
|
||||
def(term->esc_args[1], 0),
|
||||
def(term->esc_args[2], 0));
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_move_pending = true;
|
||||
term->win_move_pending_x =
|
||||
def(term->esc_args[1], 0);
|
||||
term->win_move_pending_y =
|
||||
def(term->esc_args[2], 0);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@ -4532,31 +4621,40 @@ static void term_out(Terminal *term)
|
||||
break;
|
||||
case 5:
|
||||
/* move to top */
|
||||
win_set_zorder(term->win, true);
|
||||
term->win_zorder_pending = true;
|
||||
term->win_zorder_top = true;
|
||||
term_schedule_update(term);
|
||||
break;
|
||||
case 6:
|
||||
/* move to bottom */
|
||||
win_set_zorder(term->win, false);
|
||||
term->win_zorder_pending = true;
|
||||
term->win_zorder_top = false;
|
||||
term_schedule_update(term);
|
||||
break;
|
||||
case 7:
|
||||
win_refresh(term->win);
|
||||
term->win_refresh_pending = true;
|
||||
term_schedule_update(term);
|
||||
break;
|
||||
case 8:
|
||||
if (term->esc_nargs >= 3) {
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(
|
||||
term->win,
|
||||
def(term->esc_args[2],
|
||||
term->conf_width),
|
||||
def(term->esc_args[1],
|
||||
term->conf_height));
|
||||
if (term->esc_nargs >= 3 &&
|
||||
!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w =
|
||||
def(term->esc_args[2],
|
||||
term->conf_width);
|
||||
term->win_resize_pending_h =
|
||||
def(term->esc_args[1],
|
||||
term->conf_height);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (term->esc_nargs >= 2)
|
||||
win_set_maximised(
|
||||
term->win,
|
||||
term->esc_args[1] ? true : false);
|
||||
if (term->esc_nargs >= 2) {
|
||||
term->win_maximise_pending = true;
|
||||
term->win_maximise_enable =
|
||||
term->esc_args[1];
|
||||
term_schedule_update(term);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (term->ldisc)
|
||||
@ -4662,10 +4760,13 @@ static void term_out(Terminal *term)
|
||||
*/
|
||||
compatibility(VT420);
|
||||
if (term->esc_nargs == 1 && term->esc_args[0] > 0) {
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(term->win, term->cols,
|
||||
def(term->esc_args[0],
|
||||
term->conf_height));
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w = term->cols;
|
||||
term->win_resize_pending_h =
|
||||
def(term->esc_args[0], term->conf_height);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
deselect(term);
|
||||
}
|
||||
break;
|
||||
@ -4677,11 +4778,13 @@ static void term_out(Terminal *term)
|
||||
*/
|
||||
compatibility(VT340TEXT);
|
||||
if (term->esc_nargs <= 1) {
|
||||
if (!term->no_remote_resize)
|
||||
win_request_resize(
|
||||
term->win,
|
||||
def(term->esc_args[0], term->conf_width),
|
||||
term->rows);
|
||||
if (!term->no_remote_resize) {
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w =
|
||||
def(term->esc_args[0], term->conf_width);
|
||||
term->win_resize_pending_h = term->rows;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
deselect(term);
|
||||
}
|
||||
break;
|
||||
@ -4887,10 +4990,11 @@ static void term_out(Terminal *term)
|
||||
*/
|
||||
if (!has_compat(VT420) && has_compat(VT100)) {
|
||||
if (!term->no_remote_resize) {
|
||||
if (term->reset_132)
|
||||
win_request_resize(term->win, 132, 24);
|
||||
else
|
||||
win_request_resize(term->win, 80, 24);
|
||||
term->win_resize_pending = true;
|
||||
term->win_resize_pending_w =
|
||||
term->reset_132 ? 132 : 80;
|
||||
term->win_resize_pending_h = 24;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -6041,8 +6145,8 @@ void term_scroll(Terminal *term, int rel, int where)
|
||||
term->disptop = sbtop;
|
||||
if (term->disptop > 0)
|
||||
term->disptop = 0;
|
||||
update_sbar(term);
|
||||
term_update(term);
|
||||
term->win_scrollbar_update_pending = true;
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6998,7 +7102,7 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
|
||||
*/
|
||||
if (term->selstate != DRAGGING)
|
||||
term_out(term);
|
||||
term_update(term);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
int format_arrow_key(char *buf, Terminal *term, int xkey, bool ctrl)
|
||||
|
24
terminal.h
24
terminal.h
@ -363,6 +363,30 @@ struct terminal_tag {
|
||||
rgb palette[OSC4_NCOLOURS];
|
||||
|
||||
unsigned winpos_x, winpos_y, winpixsize_x, winpixsize_y;
|
||||
|
||||
/*
|
||||
* Assorted 'pending' flags for ancillary window changes performed
|
||||
* in term_update. Generally, to trigger one of these operations,
|
||||
* you set the pending flag and/or the parameters here, then call
|
||||
* term_schedule_update.
|
||||
*/
|
||||
bool win_move_pending;
|
||||
int win_move_pending_x, win_move_pending_y;
|
||||
bool win_resize_pending;
|
||||
int win_resize_pending_w, win_resize_pending_h;
|
||||
bool win_zorder_pending;
|
||||
bool win_zorder_top;
|
||||
bool win_minimise_pending;
|
||||
bool win_minimise_enable;
|
||||
bool win_maximise_pending;
|
||||
bool win_maximise_enable;
|
||||
bool win_title_pending, win_icon_title_pending;
|
||||
bool win_pointer_shape_pending;
|
||||
bool win_pointer_shape_raw;
|
||||
bool win_refresh_pending;
|
||||
bool win_scrollbar_update_pending;
|
||||
bool win_palette_pending;
|
||||
unsigned win_palette_pending_min, win_palette_pending_limit;
|
||||
};
|
||||
|
||||
static inline bool in_utf(Terminal *term)
|
||||
|
Loading…
Reference in New Issue
Block a user