aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2014-06-04 12:16:46 +0300
committerEli Zaretskii2014-06-04 12:16:46 +0300
commitd13adf6ddc858a988f88233fe6d73a8ca4a87cf7 (patch)
treef7ded9b13a8785e0c643bb3cd6a7cd893bfede25 /src
parent4a52a98a9a5a49719da0a44d5ab1ddfde9a2aedc (diff)
downloademacs-d13adf6ddc858a988f88233fe6d73a8ca4a87cf7.tar.gz
emacs-d13adf6ddc858a988f88233fe6d73a8ca4a87cf7.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog20
-rw-r--r--src/dispextern.h2
-rw-r--r--src/dispnew.c30
-rw-r--r--src/term.c16
4 files changed, 50 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 5759d155580..16e3328a735 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,23 @@
12014-06-04 Eli Zaretskii <eliz@gnu.org>
2
3 Minimize cursor motion during TTY menu updates.
4 * term.c (tty_menu_display): Don't position cursor here. Instead,
5 pass the cursor coordinates to update_frame_with_menu.
6 (tty_menu_activate): Send the hide cursor command only once in an
7 iteration through the outer 'while' loop.
8
9 * dispnew.c (update_frame_1): Accept an additional argument
10 SET_CURSOR_P, and position the cursor at the end of the frame
11 update only if that argument is non-zero. All callers changed to
12 provide the additional argument as non-zero, except for
13 update_frame_with_menu.
14 (update_frame_with_menu): Accept 2 additional arguments ROW and
15 COL; if they are non-negative, instruct update_frame_1 not to
16 position the cursor, and instead position it according to ROW and
17 COL.
18
19 * dispextern.h (update_frame_with_menu): Update prototype.
20
12014-06-02 Stefan Monnier <monnier@iro.umontreal.ca> 212014-06-02 Stefan Monnier <monnier@iro.umontreal.ca>
2 22
3 * callproc.c (call_process): Don't check read-only if we don't insert 23 * 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,
3454 int *, int *, int *, int *); 3454 int *, int *, int *, int *);
3455extern void redraw_frame (struct frame *); 3455extern void redraw_frame (struct frame *);
3456extern bool update_frame (struct frame *, bool, bool); 3456extern bool update_frame (struct frame *, bool, bool);
3457extern void update_frame_with_menu (struct frame *); 3457extern void update_frame_with_menu (struct frame *, int, int);
3458extern void bitch_at_user (void); 3458extern void bitch_at_user (void);
3459extern void adjust_frame_glyphs (struct frame *); 3459extern void adjust_frame_glyphs (struct frame *);
3460void free_glyphs (struct frame *); 3460void 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 *,
92static void mirror_line_dance (struct window *, int, int, int *, char *); 92static void mirror_line_dance (struct window *, int, int, int *, char *);
93static bool update_window_tree (struct window *, bool); 93static bool update_window_tree (struct window *, bool);
94static bool update_window (struct window *, bool); 94static bool update_window (struct window *, bool);
95static bool update_frame_1 (struct frame *, bool, bool); 95static bool update_frame_1 (struct frame *, bool, bool, bool);
96static bool scrolling (struct frame *); 96static bool scrolling (struct frame *);
97static void set_window_cursor_after_update (struct window *); 97static void set_window_cursor_after_update (struct window *);
98static void adjust_frame_glyphs_for_window_redisplay (struct frame *); 98static 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)
3070 3070
3071 /* Update the display */ 3071 /* Update the display */
3072 update_begin (f); 3072 update_begin (f);
3073 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p); 3073 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1);
3074 update_end (f); 3074 update_end (f);
3075 3075
3076 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) 3076 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)
3100 glyphs. This is like the second part of update_frame, but it 3100 glyphs. This is like the second part of update_frame, but it
3101 doesn't call build_frame_matrix, because we already have the 3101 doesn't call build_frame_matrix, because we already have the
3102 desired matrix prepared, and don't want it to be overwritten by the 3102 desired matrix prepared, and don't want it to be overwritten by the
3103 text of the normal display. */ 3103 text of the normal display.
3104
3105 ROW and COL, if non-negative, are the row and column of the TTY
3106 frame where to position the cursor after the frame update is
3107 complete. Negative values mean ask update_frame_1 to position the
3108 cursor "normally", i.e. at point in the selected window. */
3104void 3109void
3105update_frame_with_menu (struct frame *f) 3110update_frame_with_menu (struct frame *f, int row, int col)
3106{ 3111{
3107 struct window *root_window = XWINDOW (f->root_window); 3112 struct window *root_window = XWINDOW (f->root_window);
3108 bool paused_p; 3113 bool paused_p, cursor_at_point_p;
3109 3114
3110 eassert (FRAME_TERMCAP_P (f)); 3115 eassert (FRAME_TERMCAP_P (f));
3111 3116
@@ -3115,9 +3120,14 @@ update_frame_with_menu (struct frame *f)
3115 3120
3116 /* Update the display. */ 3121 /* Update the display. */
3117 update_begin (f); 3122 update_begin (f);
3123 cursor_at_point_p = !(row >= 0 && col >= 0);
3118 /* Force update_frame_1 not to stop due to pending input, and not 3124 /* Force update_frame_1 not to stop due to pending input, and not
3119 try scrolling. */ 3125 try scrolling. */
3120 paused_p = update_frame_1 (f, 1, 1); 3126 paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p);
3127 /* ROW and COL tell us where in the menu to position the cursor, so
3128 that screen readers know the active region on the screen. */
3129 if (!cursor_at_point_p)
3130 cursor_to (f, row, col);
3121 update_end (f); 3131 update_end (f);
3122 3132
3123 if (FRAME_TTY (f)->termscript) 3133 if (FRAME_TTY (f)->termscript)
@@ -4413,12 +4423,14 @@ scrolling_window (struct window *w, bool header_line_p)
4413/* Update the desired frame matrix of frame F. 4423/* Update the desired frame matrix of frame F.
4414 4424
4415 FORCE_P means that the update should not be stopped by pending input. 4425 FORCE_P means that the update should not be stopped by pending input.
4416 INHIBIT_HAIRY_ID_P means that scrolling should not be tried. 4426 INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
4427 SET_CURSOR_P false means do not set cursor at point in selected window.
4417 4428
4418 Value is true if update was stopped due to pending input. */ 4429 Value is true if update was stopped due to pending input. */
4419 4430
4420static bool 4431static bool
4421update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p) 4432update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4433 bool set_cursor_p)
4422{ 4434{
4423 /* Frame matrices to work on. */ 4435 /* Frame matrices to work on. */
4424 struct glyph_matrix *current_matrix = f->current_matrix; 4436 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)
4490 pause_p = 0 < i && i < FRAME_LINES (f) - 1; 4502 pause_p = 0 < i && i < FRAME_LINES (f) - 1;
4491 4503
4492 /* Now just clean up termcap drivers and set cursor, etc. */ 4504 /* Now just clean up termcap drivers and set cursor, etc. */
4493 if (!pause_p) 4505 if (!pause_p && set_cursor_p)
4494 { 4506 {
4495 if ((cursor_in_echo_area 4507 if ((cursor_in_echo_area
4496 /* If we are showing a message instead of the mini-buffer, 4508 /* 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,
2907 display_tty_menu_item (menu->text[j], max_width, face, x, y + i, 2907 display_tty_menu_item (menu->text[j], max_width, face, x, y + i,
2908 menu->submenu[j] != NULL); 2908 menu->submenu[j] != NULL);
2909 } 2909 }
2910 update_frame_with_menu (sf); 2910 update_frame_with_menu (sf, row, col);
2911 cursor_to (sf, row, col);
2912} 2911}
2913 2912
2914/* --------------------------- X Menu emulation ---------------------- */ 2913/* --------------------------- X Menu emulation ---------------------- */
@@ -3079,7 +3078,7 @@ static void
3079screen_update (struct frame *f, struct glyph_matrix *mtx) 3078screen_update (struct frame *f, struct glyph_matrix *mtx)
3080{ 3079{
3081 restore_desired_matrix (f, mtx); 3080 restore_desired_matrix (f, mtx);
3082 update_frame_with_menu (f); 3081 update_frame_with_menu (f, -1, -1);
3083} 3082}
3084 3083
3085typedef enum { 3084typedef enum {
@@ -3228,7 +3227,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3228 3227
3229 /* Force update of the current frame, so that the desired and the 3228 /* Force update of the current frame, so that the desired and the
3230 current matrices are identical. */ 3229 current matrices are identical. */
3231 update_frame_with_menu (sf); 3230 update_frame_with_menu (sf, -1, -1);
3232 state[0].menu = menu; 3231 state[0].menu = menu;
3233 state[0].screen_behind = save_and_enable_current_matrix (sf); 3232 state[0].screen_behind = save_and_enable_current_matrix (sf);
3234 3233
@@ -3373,8 +3372,6 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3373 state[statecount - 1].y, 3372 state[statecount - 1].y,
3374 state[statecount - 1].pane, 3373 state[statecount - 1].pane,
3375 faces, x, y, first_item, 1); 3374 faces, x, y, first_item, 1);
3376 tty_hide_cursor (tty);
3377 fflush (tty->output);
3378 /* The call to display help-echo below will move the cursor, 3375 /* The call to display help-echo below will move the cursor,
3379 so remember its current position as computed by 3376 so remember its current position as computed by
3380 tty_menu_display. */ 3377 tty_menu_display. */
@@ -3393,10 +3390,13 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3393 item, so that screen readers and other accessibility aids 3390 item, so that screen readers and other accessibility aids
3394 know where the active region is. */ 3391 know where the active region is. */
3395 cursor_to (sf, row, col); 3392 cursor_to (sf, row, col);
3396 tty_hide_cursor (tty);
3397 fflush (tty->output);
3398 prev_menu_help_message = menu_help_message; 3393 prev_menu_help_message = menu_help_message;
3399 } 3394 }
3395 /* Both tty_menu_display and help_callback invoke update_end,
3396 which calls tty_show_cursor. Re-hide it, so it doesn't show
3397 through the menus. */
3398 tty_hide_cursor (tty);
3399 fflush (tty->output);
3400 } 3400 }
3401 3401
3402 sf->mouse_moved = 0; 3402 sf->mouse_moved = 0;