Attempt to solve bug #17497 by minimizing cursor motion during TTY menu updates.
src/term.c (tty_menu_display): Don't position cursor here. Instead, pass the cursor coordinates to update_frame_with_menu. (tty_menu_activate): Send the hide cursor command only once in an iteration through the outer 'while' loop. src/dispnew.c (update_frame_1): Accept an additional argument SET_CURSOR_P, and position the cursor at the end of the frame update only if that argument is non-zero. All callers changed to provide the additional argument as non-zero, except for update_frame_with_menu. (update_frame_with_menu): Accept 2 additional arguments ROW and COL; if they are non-negative, instruct update_frame_1 not to position the cursor, and instead position it according to ROW and COL. src/dispextern.h (update_frame_with_menu): Update prototype.
This commit is contained in:
parent
4a52a98a9a
commit
d13adf6ddc
4 changed files with 50 additions and 18 deletions
|
@ -1,3 +1,23 @@
|
|||
2014-06-04 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Minimize cursor motion during TTY menu updates.
|
||||
* term.c (tty_menu_display): Don't position cursor here. Instead,
|
||||
pass the cursor coordinates to update_frame_with_menu.
|
||||
(tty_menu_activate): Send the hide cursor command only once in an
|
||||
iteration through the outer 'while' loop.
|
||||
|
||||
* dispnew.c (update_frame_1): Accept an additional argument
|
||||
SET_CURSOR_P, and position the cursor at the end of the frame
|
||||
update only if that argument is non-zero. All callers changed to
|
||||
provide the additional argument as non-zero, except for
|
||||
update_frame_with_menu.
|
||||
(update_frame_with_menu): Accept 2 additional arguments ROW and
|
||||
COL; if they are non-negative, instruct update_frame_1 not to
|
||||
position the cursor, and instead position it according to ROW and
|
||||
COL.
|
||||
|
||||
* dispextern.h (update_frame_with_menu): Update prototype.
|
||||
|
||||
2014-06-02 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* callproc.c (call_process): Don't check read-only if we don't insert
|
||||
|
|
|
@ -3454,7 +3454,7 @@ extern Lisp_Object marginal_area_string (struct window *, enum window_part,
|
|||
int *, int *, int *, int *);
|
||||
extern void redraw_frame (struct frame *);
|
||||
extern bool update_frame (struct frame *, bool, bool);
|
||||
extern void update_frame_with_menu (struct frame *);
|
||||
extern void update_frame_with_menu (struct frame *, int, int);
|
||||
extern void bitch_at_user (void);
|
||||
extern void adjust_frame_glyphs (struct frame *);
|
||||
void free_glyphs (struct frame *);
|
||||
|
|
|
@ -92,7 +92,7 @@ static void check_matrix_pointers (struct glyph_matrix *,
|
|||
static void mirror_line_dance (struct window *, int, int, int *, char *);
|
||||
static bool update_window_tree (struct window *, bool);
|
||||
static bool update_window (struct window *, bool);
|
||||
static bool update_frame_1 (struct frame *, bool, bool);
|
||||
static bool update_frame_1 (struct frame *, bool, bool, bool);
|
||||
static bool scrolling (struct frame *);
|
||||
static void set_window_cursor_after_update (struct window *);
|
||||
static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
|
||||
|
@ -3070,7 +3070,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
|
|||
|
||||
/* Update the display */
|
||||
update_begin (f);
|
||||
paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
|
||||
paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1);
|
||||
update_end (f);
|
||||
|
||||
if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
|
||||
|
@ -3100,12 +3100,17 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
|
|||
glyphs. This is like the second part of update_frame, but it
|
||||
doesn't call build_frame_matrix, because we already have the
|
||||
desired matrix prepared, and don't want it to be overwritten by the
|
||||
text of the normal display. */
|
||||
text of the normal display.
|
||||
|
||||
ROW and COL, if non-negative, are the row and column of the TTY
|
||||
frame where to position the cursor after the frame update is
|
||||
complete. Negative values mean ask update_frame_1 to position the
|
||||
cursor "normally", i.e. at point in the selected window. */
|
||||
void
|
||||
update_frame_with_menu (struct frame *f)
|
||||
update_frame_with_menu (struct frame *f, int row, int col)
|
||||
{
|
||||
struct window *root_window = XWINDOW (f->root_window);
|
||||
bool paused_p;
|
||||
bool paused_p, cursor_at_point_p;
|
||||
|
||||
eassert (FRAME_TERMCAP_P (f));
|
||||
|
||||
|
@ -3115,9 +3120,14 @@ update_frame_with_menu (struct frame *f)
|
|||
|
||||
/* Update the display. */
|
||||
update_begin (f);
|
||||
cursor_at_point_p = !(row >= 0 && col >= 0);
|
||||
/* Force update_frame_1 not to stop due to pending input, and not
|
||||
try scrolling. */
|
||||
paused_p = update_frame_1 (f, 1, 1);
|
||||
paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p);
|
||||
/* ROW and COL tell us where in the menu to position the cursor, so
|
||||
that screen readers know the active region on the screen. */
|
||||
if (!cursor_at_point_p)
|
||||
cursor_to (f, row, col);
|
||||
update_end (f);
|
||||
|
||||
if (FRAME_TTY (f)->termscript)
|
||||
|
@ -4413,12 +4423,14 @@ scrolling_window (struct window *w, bool header_line_p)
|
|||
/* Update the desired frame matrix of frame F.
|
||||
|
||||
FORCE_P means that the update should not be stopped by pending input.
|
||||
INHIBIT_HAIRY_ID_P means that scrolling should not be tried.
|
||||
INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
|
||||
SET_CURSOR_P false means do not set cursor at point in selected window.
|
||||
|
||||
Value is true if update was stopped due to pending input. */
|
||||
|
||||
static bool
|
||||
update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
|
||||
update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
|
||||
bool set_cursor_p)
|
||||
{
|
||||
/* Frame matrices to work on. */
|
||||
struct glyph_matrix *current_matrix = f->current_matrix;
|
||||
|
@ -4490,7 +4502,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
|
|||
pause_p = 0 < i && i < FRAME_LINES (f) - 1;
|
||||
|
||||
/* Now just clean up termcap drivers and set cursor, etc. */
|
||||
if (!pause_p)
|
||||
if (!pause_p && set_cursor_p)
|
||||
{
|
||||
if ((cursor_in_echo_area
|
||||
/* If we are showing a message instead of the mini-buffer,
|
||||
|
|
16
src/term.c
16
src/term.c
|
@ -2907,8 +2907,7 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces,
|
|||
display_tty_menu_item (menu->text[j], max_width, face, x, y + i,
|
||||
menu->submenu[j] != NULL);
|
||||
}
|
||||
update_frame_with_menu (sf);
|
||||
cursor_to (sf, row, col);
|
||||
update_frame_with_menu (sf, row, col);
|
||||
}
|
||||
|
||||
/* --------------------------- X Menu emulation ---------------------- */
|
||||
|
@ -3079,7 +3078,7 @@ static void
|
|||
screen_update (struct frame *f, struct glyph_matrix *mtx)
|
||||
{
|
||||
restore_desired_matrix (f, mtx);
|
||||
update_frame_with_menu (f);
|
||||
update_frame_with_menu (f, -1, -1);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
|
@ -3228,7 +3227,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
|
||||
/* Force update of the current frame, so that the desired and the
|
||||
current matrices are identical. */
|
||||
update_frame_with_menu (sf);
|
||||
update_frame_with_menu (sf, -1, -1);
|
||||
state[0].menu = menu;
|
||||
state[0].screen_behind = save_and_enable_current_matrix (sf);
|
||||
|
||||
|
@ -3373,8 +3372,6 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
state[statecount - 1].y,
|
||||
state[statecount - 1].pane,
|
||||
faces, x, y, first_item, 1);
|
||||
tty_hide_cursor (tty);
|
||||
fflush (tty->output);
|
||||
/* The call to display help-echo below will move the cursor,
|
||||
so remember its current position as computed by
|
||||
tty_menu_display. */
|
||||
|
@ -3393,10 +3390,13 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
item, so that screen readers and other accessibility aids
|
||||
know where the active region is. */
|
||||
cursor_to (sf, row, col);
|
||||
tty_hide_cursor (tty);
|
||||
fflush (tty->output);
|
||||
prev_menu_help_message = menu_help_message;
|
||||
}
|
||||
/* Both tty_menu_display and help_callback invoke update_end,
|
||||
which calls tty_show_cursor. Re-hide it, so it doesn't show
|
||||
through the menus. */
|
||||
tty_hide_cursor (tty);
|
||||
fflush (tty->output);
|
||||
}
|
||||
|
||||
sf->mouse_moved = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue