diff --git a/src/ChangeLog b/src/ChangeLog index 5759d155580..16e3328a735 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,23 @@ +2014-06-04 Eli Zaretskii + + 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 * callproc.c (call_process): Don't check read-only if we don't insert diff --git a/src/dispextern.h b/src/dispextern.h index 9ecd4ecdf7e..8ccc3d35d8c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -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 *); diff --git a/src/dispnew.c b/src/dispnew.c index 1a9eefc5cfc..163780952a6 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -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, diff --git a/src/term.c b/src/term.c index 12cd2ce8508..8661cba1160 100644 --- a/src/term.c +++ b/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;