aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Möllmann2024-11-16 13:52:17 +0100
committerGerd Möllmann2024-11-16 13:52:17 +0100
commite7359fbbc40bbf714fb5b4bffc256b455fbe9a6c (patch)
tree0339ad3723caba83d7630fce95a936290a3cc56d
parente5a2bc740dc43de63acb6e9603ad1905fac1e2c6 (diff)
downloademacs-e7359fbbc40bbf714fb5b4bffc256b455fbe9a6c.tar.gz
emacs-e7359fbbc40bbf714fb5b4bffc256b455fbe9a6c.zip
Revert "Don't pause display for pending input"
This reverts commit f62d70f52f4f6b7ed158d618bf790df21f171172.
-rw-r--r--lisp/subr.el1
-rw-r--r--src/dispextern.h9
-rw-r--r--src/dispnew.c543
-rw-r--r--src/keyboard.c3
-rw-r--r--src/minibuf.c4
-rw-r--r--src/xdisp.c199
6 files changed, 497 insertions, 262 deletions
diff --git a/lisp/subr.el b/lisp/subr.el
index 648e6f0f38f..6472c9d6916 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1990,6 +1990,7 @@ be a list of the form returned by `event-start' and `event-end'."
1990 ;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25, 1990 ;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25,
1991 ;; but it's only been marked for compilation warnings since Emacs-29. 1991 ;; but it's only been marked for compilation warnings since Emacs-29.
1992 "25.1") 1992 "25.1")
1993(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
1993(make-obsolete-variable 'operating-system-release nil "28.1") 1994(make-obsolete-variable 'operating-system-release nil "28.1")
1994(make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1") 1995(make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1")
1995 1996
diff --git a/src/dispextern.h b/src/dispextern.h
index 47afc48bb60..cb43d330b86 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1322,6 +1322,9 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int);
1322 1322
1323extern struct glyph space_glyph; 1323extern struct glyph space_glyph;
1324 1324
1325/* True means last display completed. False means it was preempted. */
1326
1327extern bool display_completed;
1325 1328
1326/************************************************************************ 1329/************************************************************************
1327 Glyph Strings 1330 Glyph Strings
@@ -3803,7 +3806,7 @@ extern Lisp_Object marginal_area_string (struct window *, enum window_part,
3803 Lisp_Object *, 3806 Lisp_Object *,
3804 int *, int *, int *, int *); 3807 int *, int *, int *, int *);
3805extern void redraw_frame (struct frame *); 3808extern void redraw_frame (struct frame *);
3806void update_frame (struct frame *, bool); 3809extern bool update_frame (struct frame *, bool, bool);
3807extern void update_frame_with_menu (struct frame *, int, int); 3810extern void update_frame_with_menu (struct frame *, int, int);
3808extern int update_mouse_position (struct frame *, int, int); 3811extern int update_mouse_position (struct frame *, int, int);
3809extern void bitch_at_user (void); 3812extern void bitch_at_user (void);
@@ -3922,8 +3925,8 @@ Lisp_Object frames_in_reverse_z_order (struct frame *f, bool visible);
3922bool is_tty_frame (struct frame *f); 3925bool is_tty_frame (struct frame *f);
3923bool is_tty_child_frame (struct frame *f); 3926bool is_tty_child_frame (struct frame *f);
3924bool is_tty_root_frame (struct frame *f); 3927bool is_tty_root_frame (struct frame *f);
3925void combine_updates (Lisp_Object root_frames, bool inhibit_id_p); 3928bool combine_updates (Lisp_Object root_frames, bool force_p, bool inhibit_id_p);
3926void combine_updates_for_frame (struct frame *f, bool inhibit_id_p); 3929bool combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_id_p);
3927void tty_raise_lower_frame (struct frame *f, bool raise); 3930void tty_raise_lower_frame (struct frame *f, bool raise);
3928int max_child_z_order (struct frame *parent); 3931int max_child_z_order (struct frame *parent);
3929 3932
diff --git a/src/dispnew.c b/src/dispnew.c
index 37ec37b752e..d473a77e3ad 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -93,10 +93,10 @@ static void check_matrix_pointers (struct glyph_matrix *,
93 struct glyph_matrix *); 93 struct glyph_matrix *);
94#endif 94#endif
95static void mirror_line_dance (struct window *, int, int, int *, char *); 95static void mirror_line_dance (struct window *, int, int, int *, char *);
96static void update_window_tree (struct window *); 96static bool update_window_tree (struct window *, bool);
97static void update_window (struct window *); 97static bool update_window (struct window *, bool);
98static void write_matrix (struct frame *, bool, bool, bool); 98static bool write_matrix (struct frame *, bool, bool, bool, bool);
99static void scrolling (struct frame *); 99static bool scrolling (struct frame *);
100static void set_window_cursor_after_update (struct window *); 100static void set_window_cursor_after_update (struct window *);
101static void adjust_frame_glyphs_for_window_redisplay (struct frame *); 101static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
102static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); 102static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
@@ -116,6 +116,10 @@ check_rows (struct frame *f)
116} 116}
117#endif 117#endif
118 118
119/* True means last display completed. False means it was preempted. */
120
121bool display_completed;
122
119/* True means SIGWINCH happened when not safe. */ 123/* True means SIGWINCH happened when not safe. */
120 124
121static bool delayed_size_change; 125static bool delayed_size_change;
@@ -171,10 +175,11 @@ static uintmax_t history_tick;
171 175
172/* Add to the redisplay history how window W has been displayed. 176/* Add to the redisplay history how window W has been displayed.
173 MSG is a trace containing the information how W's glyph matrix 177 MSG is a trace containing the information how W's glyph matrix
174 has been constructed. */ 178 has been constructed. PAUSED_P means that the update
179 has been interrupted for pending input. */
175 180
176static void 181static void
177add_window_display_history (struct window *w, const char *msg) 182add_window_display_history (struct window *w, const char *msg, bool paused_p)
178{ 183{
179 char *buf; 184 char *buf;
180 void *ptr = w; 185 void *ptr = w;
@@ -185,13 +190,14 @@ add_window_display_history (struct window *w, const char *msg)
185 ++history_idx; 190 ++history_idx;
186 191
187 snprintf (buf, sizeof redisplay_history[0].trace, 192 snprintf (buf, sizeof redisplay_history[0].trace,
188 "%"PRIuMAX": window %p %s\n%s", 193 "%"PRIuMAX": window %p (%s)%s\n%s",
189 history_tick++, 194 history_tick++,
190 ptr, 195 ptr,
191 ((BUFFERP (w->contents) 196 ((BUFFERP (w->contents)
192 && STRINGP (BVAR (XBUFFER (w->contents), name))) 197 && STRINGP (BVAR (XBUFFER (w->contents), name)))
193 ? SSDATA (BVAR (XBUFFER (w->contents), name)) 198 ? SSDATA (BVAR (XBUFFER (w->contents), name))
194 : "???"), 199 : "???"),
200 paused_p ? " ***paused***" : "",
195 msg); 201 msg);
196} 202}
197 203
@@ -2130,7 +2136,8 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
2130 current matrix over a call to adjust_glyph_matrix, we must 2136 current matrix over a call to adjust_glyph_matrix, we must
2131 make a copy of the current glyphs, and restore the current 2137 make a copy of the current glyphs, and restore the current
2132 matrix' contents from that copy. */ 2138 matrix' contents from that copy. */
2133 if (!FRAME_GARBAGED_P (f) 2139 if (display_completed
2140 && !FRAME_GARBAGED_P (f)
2134 && matrix_dim.width == f->current_matrix->matrix_w 2141 && matrix_dim.width == f->current_matrix->matrix_w
2135 && matrix_dim.height == f->current_matrix->matrix_h 2142 && matrix_dim.height == f->current_matrix->matrix_h
2136 /* For some reason, the frame glyph matrix gets corrupted if 2143 /* For some reason, the frame glyph matrix gets corrupted if
@@ -2675,7 +2682,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2675 frame and window share glyphs. */ 2682 frame and window share glyphs. */
2676 2683
2677 strcpy (w->current_matrix->method, w->desired_matrix->method); 2684 strcpy (w->current_matrix->method, w->desired_matrix->method);
2678 add_window_display_history (w, w->current_matrix->method); 2685 add_window_display_history (w, w->current_matrix->method, 0);
2679#endif 2686#endif
2680 } 2687 }
2681 2688
@@ -3771,7 +3778,7 @@ update_bar_window (Lisp_Object window, Lisp_Object *current,
3771 struct window *w = XWINDOW (window); 3778 struct window *w = XWINDOW (window);
3772 if (w->must_be_updated_p) 3779 if (w->must_be_updated_p)
3773 { 3780 {
3774 update_window (w); 3781 update_window (w, true);
3775 w->must_be_updated_p = false; 3782 w->must_be_updated_p = false;
3776 Lisp_Object tem = *current; 3783 Lisp_Object tem = *current;
3777 *current = *desired; 3784 *current = *desired;
@@ -3801,8 +3808,8 @@ update_tool_bar (struct frame *f)
3801#endif 3808#endif
3802} 3809}
3803 3810
3804static void 3811static bool
3805update_window_frame (struct frame *f) 3812update_window_frame (struct frame *f, bool force_p)
3806{ 3813{
3807 eassert (FRAME_WINDOW_P (f)); 3814 eassert (FRAME_WINDOW_P (f));
3808 update_begin (f); 3815 update_begin (f);
@@ -3810,17 +3817,19 @@ update_window_frame (struct frame *f)
3810 update_tab_bar (f); 3817 update_tab_bar (f);
3811 update_tool_bar (f); 3818 update_tool_bar (f);
3812 struct window *root_window = XWINDOW (f->root_window); 3819 struct window *root_window = XWINDOW (f->root_window);
3813 update_window_tree (root_window); 3820 bool paused_p = update_window_tree (root_window, force_p);
3814 update_end (f); 3821 update_end (f);
3815 set_window_update_flags (root_window, false); 3822 set_window_update_flags (root_window, false);
3823 return paused_p;
3816} 3824}
3817 3825
3818static void 3826static bool
3819update_initial_frame (struct frame *f) 3827update_initial_frame (struct frame *f, bool force_p)
3820{ 3828{
3821 build_frame_matrix (f); 3829 build_frame_matrix (f);
3822 struct window *root_window = XWINDOW (f->root_window); 3830 struct window *root_window = XWINDOW (f->root_window);
3823 set_window_update_flags (root_window, false); 3831 set_window_update_flags (root_window, false);
3832 return false;
3824} 3833}
3825 3834
3826static void 3835static void
@@ -3831,10 +3840,11 @@ flush_terminal (struct frame *f)
3831 fflush (FRAME_TTY (f)->output); 3840 fflush (FRAME_TTY (f)->output);
3832} 3841}
3833 3842
3834static void 3843static bool
3835update_tty_frame (struct frame *f) 3844update_tty_frame (struct frame *f, bool force_p)
3836{ 3845{
3837 build_frame_matrix (f); 3846 build_frame_matrix (f);
3847 return false;
3838} 3848}
3839 3849
3840/* Return the cursor position of the selected window of frame F, in 3850/* Return the cursor position of the selected window of frame F, in
@@ -3942,8 +3952,8 @@ terminal_cursor_magic (struct frame *root, struct frame *topmost_child)
3942 } 3952 }
3943} 3953}
3944 3954
3945void 3955bool
3946combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) 3956combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
3947{ 3957{
3948 struct frame *root = root_frame (f); 3958 struct frame *root = root_frame (f);
3949 eassert (FRAME_VISIBLE_P (root)); 3959 eassert (FRAME_VISIBLE_P (root));
@@ -3959,12 +3969,13 @@ combine_updates_for_frame (struct frame *f, bool inhibit_scrolling)
3959 } 3969 }
3960 3970
3961 update_begin (root); 3971 update_begin (root);
3962 write_matrix (root, inhibit_scrolling, 1, false); 3972 bool paused = write_matrix (root, force_p, inhibit_scrolling, 1, false);
3963 make_matrix_current (root); 3973 if (!paused)
3974 make_matrix_current (root);
3964 update_end (root); 3975 update_end (root);
3965 3976
3966 /* If a child is displayed, and the cursor is displayed in another 3977 /* If a child is displayed, and the cursor is displayed in another
3967 frame, the child might lay above the cursor, so that it appears to 3978 frame, the child might lay above the cursor, so that it appers to
3968 "shine through" the child. Avoid that because it's confusing. */ 3979 "shine through" the child. Avoid that because it's confusing. */
3969 if (topmost_child) 3980 if (topmost_child)
3970 terminal_cursor_magic (root, topmost_child); 3981 terminal_cursor_magic (root, topmost_child);
@@ -3981,33 +3992,66 @@ combine_updates_for_frame (struct frame *f, bool inhibit_scrolling)
3981 add_frame_display_history (f, false); 3992 add_frame_display_history (f, false);
3982#endif 3993#endif
3983 } 3994 }
3995
3996 return paused;
3984} 3997}
3985 3998
3986/* Update on the screen all root frames ROOTS. Called from 3999/* Update on the screen all root frames ROOTS. Called from
3987 redisplay_internal as the last step of redisplaying. */ 4000 redisplay_internal as the last step of redisplaying. */
3988 4001
3989void 4002bool
3990combine_updates (Lisp_Object roots, bool inhibit_scrolling) 4003combine_updates (Lisp_Object roots, bool force_p, bool inhibit_scrolling)
3991{ 4004{
4005 if (redisplay_dont_pause)
4006 force_p = true;
4007
3992 for (; CONSP (roots); roots = XCDR (roots)) 4008 for (; CONSP (roots); roots = XCDR (roots))
3993 { 4009 {
3994 struct frame *root = XFRAME (XCAR (roots)); 4010 struct frame *root = XFRAME (XCAR (roots));
3995 combine_updates_for_frame (root, inhibit_scrolling); 4011 if (combine_updates_for_frame (root, force_p, inhibit_scrolling))
4012 {
4013 display_completed = false;
4014 return true;
4015 }
3996 } 4016 }
4017
4018 display_completed = true;
4019 return false;
3997} 4020}
3998 4021
3999/* Update frame F based on the data in desired matrices. 4022/* Update frame F based on the data in desired matrices.
4000 If INHIBIT_SCROLLING, don't try scrolling. */
4001 4023
4002void 4024 If FORCE_P, don't let redisplay be stopped by detecting pending input.
4003update_frame (struct frame *f, bool inhibit_scrolling) 4025 If INHIBIT_SCROLLING, don't try scrolling.
4026
4027 Value is true if redisplay was stopped due to pending input. */
4028
4029bool
4030update_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
4004{ 4031{
4032 struct window *root_window = XWINDOW (f->root_window);
4033
4034 if (redisplay_dont_pause)
4035 force_p = true;
4036 else if (!force_p && detect_input_pending_ignore_squeezables ())
4037 {
4038 /* Reset flags indicating that a window should be updated. */
4039 set_window_update_flags (root_window, false);
4040 display_completed = false;
4041 return true;
4042 }
4043
4044 bool paused;
4005 if (FRAME_WINDOW_P (f)) 4045 if (FRAME_WINDOW_P (f))
4006 update_window_frame (f); 4046 paused = update_window_frame (f, force_p);
4007 else if (FRAME_INITIAL_P (f)) 4047 else if (FRAME_INITIAL_P (f))
4008 update_initial_frame (f); 4048 paused = update_initial_frame (f, force_p);
4009 else 4049 else
4010 update_tty_frame (f); 4050 paused = update_tty_frame (f, force_p);
4051
4052 if (paused)
4053 display_completed = false;
4054 return paused;
4011} 4055}
4012 4056
4013/* Update a TTY frame F that has a menu dropped down over some of its 4057/* Update a TTY frame F that has a menu dropped down over some of its
@@ -4033,7 +4077,7 @@ update_frame_with_menu (struct frame *f, int row, int col)
4033 cursor_at_point_p = !(row >= 0 && col >= 0); 4077 cursor_at_point_p = !(row >= 0 && col >= 0);
4034 /* Do not stop due to pending input, and do not try scrolling. This 4078 /* Do not stop due to pending input, and do not try scrolling. This
4035 means that write_glyphs will always return false. */ 4079 means that write_glyphs will always return false. */
4036 write_matrix (f, 1, cursor_at_point_p, true); 4080 write_matrix (f, 1, 1, cursor_at_point_p, true);
4037 make_matrix_current (f); 4081 make_matrix_current (f);
4038 clear_desired_matrices (f); 4082 clear_desired_matrices (f);
4039 /* ROW and COL tell us where in the menu to position the cursor, so 4083 /* ROW and COL tell us where in the menu to position the cursor, so
@@ -4056,6 +4100,7 @@ update_frame_with_menu (struct frame *f, int row, int col)
4056 4100
4057 /* Reset flags indicating that a window should be updated. */ 4101 /* Reset flags indicating that a window should be updated. */
4058 set_window_update_flags (root_window, false); 4102 set_window_update_flags (root_window, false);
4103 display_completed = true;
4059} 4104}
4060 4105
4061/* Update the mouse position for a frame F. This handles both 4106/* Update the mouse position for a frame F. This handles both
@@ -4111,24 +4156,30 @@ properties or updating the help echo text. */)
4111 Window-based updates 4156 Window-based updates
4112 ************************************************************************/ 4157 ************************************************************************/
4113 4158
4114/* Perform updates in window tree rooted at W. */ 4159/* Perform updates in window tree rooted at W.
4160 If FORCE_P, don't stop updating if input is pending. */
4115 4161
4116static void 4162static bool
4117update_window_tree (struct window *w) 4163update_window_tree (struct window *w, bool force_p)
4118{ 4164{
4119 while (w) 4165 bool paused_p = 0;
4166
4167 while (w && !paused_p)
4120 { 4168 {
4121 if (WINDOWP (w->contents)) 4169 if (WINDOWP (w->contents))
4122 update_window_tree (XWINDOW (w->contents)); 4170 paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
4123 else if (w->must_be_updated_p) 4171 else if (w->must_be_updated_p)
4124 update_window (w); 4172 paused_p |= update_window (w, force_p);
4125 4173
4126 w = NILP (w->next) ? 0 : XWINDOW (w->next); 4174 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4127 } 4175 }
4176
4177 return paused_p;
4128} 4178}
4129 4179
4130 4180
4131/* Update window W if its flag must_be_updated_p is set. */ 4181/* Update window W if its flag must_be_updated_p is set.
4182 If FORCE_P, don't stop updating if input is pending. */
4132 4183
4133void 4184void
4134update_single_window (struct window *w) 4185update_single_window (struct window *w)
@@ -4139,7 +4190,7 @@ update_single_window (struct window *w)
4139 4190
4140 /* Update W. */ 4191 /* Update W. */
4141 update_begin (f); 4192 update_begin (f);
4142 update_window (w); 4193 update_window (w, true);
4143 update_end (f); 4194 update_end (f);
4144 4195
4145 /* Reset flag in W. */ 4196 /* Reset flag in W. */
@@ -4279,12 +4330,15 @@ check_current_matrix_flags (struct window *w)
4279#endif /* GLYPH_DEBUG */ 4330#endif /* GLYPH_DEBUG */
4280 4331
4281 4332
4282/* Update display of window W. */ 4333/* Update display of window W.
4334 If FORCE_P, don't stop updating when input is pending. */
4283 4335
4284static void 4336static bool
4285update_window (struct window *w) 4337update_window (struct window *w, bool force_p)
4286{ 4338{
4287 struct glyph_matrix *desired_matrix = w->desired_matrix; 4339 struct glyph_matrix *desired_matrix = w->desired_matrix;
4340 bool paused_p;
4341 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
4288#ifdef HAVE_WINDOW_SYSTEM 4342#ifdef HAVE_WINDOW_SYSTEM
4289 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); 4343 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4290#endif 4344#endif
@@ -4293,200 +4347,224 @@ update_window (struct window *w)
4293 eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w)))); 4347 eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
4294#endif 4348#endif
4295 4349
4350 /* Check pending input the first time so that we can quickly return. */
4351 if (!force_p)
4352 detect_input_pending_ignore_squeezables ();
4353
4296 /* If forced to complete the update, no input is pending, or we are 4354 /* If forced to complete the update, no input is pending, or we are
4297 tracking the mouse, do the update. */ 4355 tracking the mouse, do the update. */
4298 struct glyph_row *row, *end; 4356 if (force_p || !input_pending || !NILP (track_mouse))
4299 struct glyph_row *mode_line_row; 4357 {
4300 struct glyph_row *tab_line_row; 4358 struct glyph_row *row, *end;
4301 struct glyph_row *header_line_row; 4359 struct glyph_row *mode_line_row;
4302 int yb; 4360 struct glyph_row *tab_line_row;
4303 bool changed_p = 0, mouse_face_overwritten_p = 0; 4361 struct glyph_row *header_line_row;
4304 bool invisible_rows_marked = false; 4362 int yb;
4363 bool changed_p = 0, mouse_face_overwritten_p = 0;
4364 int n_updated = 0;
4365 bool invisible_rows_marked = false;
4305 4366
4306#ifdef HAVE_WINDOW_SYSTEM 4367#ifdef HAVE_WINDOW_SYSTEM
4307 gui_update_window_begin (w); 4368 gui_update_window_begin (w);
4308#else 4369#else
4309 (void) changed_p; 4370 (void) changed_p;
4310#endif 4371#endif
4311 yb = window_text_bottom_y (w); 4372 yb = window_text_bottom_y (w);
4312 row = MATRIX_ROW (desired_matrix, 0); 4373 row = MATRIX_ROW (desired_matrix, 0);
4313 end = MATRIX_MODE_LINE_ROW (desired_matrix); 4374 end = MATRIX_MODE_LINE_ROW (desired_matrix);
4314
4315 /* Take note of the tab line, if there is one. We will
4316 update it below, after updating all of the window's lines. */
4317 if (row->mode_line_p && row->tab_line_p)
4318 {
4319 tab_line_row = row;
4320 ++row;
4321 }
4322 else
4323 tab_line_row = NULL;
4324 4375
4325 /* Take note of the header line, if there is one. We will 4376 /* Take note of the tab line, if there is one. We will
4326 update it below, after updating all of the window's lines. */ 4377 update it below, after updating all of the window's lines. */
4327 if (row->mode_line_p) 4378 if (row->mode_line_p && row->tab_line_p)
4328 { 4379 {
4329 header_line_row = row; 4380 tab_line_row = row;
4330 ++row; 4381 ++row;
4331 } 4382 }
4332 else 4383 else
4333 header_line_row = NULL; 4384 tab_line_row = NULL;
4334
4335 /* Update the mode line, if necessary. */
4336 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
4337 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
4338 {
4339 mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
4340 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
4341 desired_matrix),
4342 &mouse_face_overwritten_p);
4343 }
4344 4385
4345 /* Find first enabled row. Optimizations in redisplay_internal 4386 /* Take note of the header line, if there is one. We will
4346 may lead to an update with only one row enabled. There may 4387 update it below, after updating all of the window's lines. */
4347 be also completely empty matrices. */ 4388 if (row->mode_line_p)
4348 while (row < end && !row->enabled_p) 4389 {
4349 ++row; 4390 header_line_row = row;
4391 ++row;
4392 }
4393 else
4394 header_line_row = NULL;
4350 4395
4351 /* Try reusing part of the display by copying. */ 4396 /* Update the mode line, if necessary. */
4352 if (row < end && !desired_matrix->no_scrolling_p) 4397 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
4353 { 4398 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
4354 int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
4355 + (header_line_row != NULL ? 1 : 0));
4356 if (rc < 0)
4357 { 4399 {
4358 /* All rows were found to be equal. */ 4400 mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
4359 goto set_cursor; 4401 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
4402 desired_matrix),
4403 &mouse_face_overwritten_p);
4360 } 4404 }
4361 else if (rc > 0) 4405
4406 /* Find first enabled row. Optimizations in redisplay_internal
4407 may lead to an update with only one row enabled. There may
4408 be also completely empty matrices. */
4409 while (row < end && !row->enabled_p)
4410 ++row;
4411
4412 /* Try reusing part of the display by copying. */
4413 if (row < end && !desired_matrix->no_scrolling_p)
4362 { 4414 {
4363 /* We've scrolled the display. */ 4415 int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
4364 changed_p = 1; 4416 + (header_line_row != NULL ? 1 : 0));
4417 if (rc < 0)
4418 {
4419 /* All rows were found to be equal. */
4420 paused_p = 0;
4421 goto set_cursor;
4422 }
4423 else if (rc > 0)
4424 {
4425 /* We've scrolled the display. */
4426 force_p = 1;
4427 changed_p = 1;
4428 }
4365 } 4429 }
4366 }
4367 4430
4368 /* Update the rest of the lines. */ 4431 /* Update the rest of the lines. */
4369 for (; row < end; ++row) 4432 for (; row < end && (force_p || !input_pending); ++row)
4370 /* scrolling_window resets the enabled_p flag of the rows it 4433 /* scrolling_window resets the enabled_p flag of the rows it
4371 reuses from current_matrix. */ 4434 reuses from current_matrix. */
4372 if (row->enabled_p) 4435 if (row->enabled_p)
4373 {
4374 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
4375 int i;
4376
4377 changed_p |= update_window_line (w, vpos,
4378 &mouse_face_overwritten_p);
4379
4380 /* Mark all rows below the last visible one in the current
4381 matrix as invalid. This is necessary because of
4382 variable line heights. Consider the case of three
4383 successive redisplays, where the first displays 5
4384 lines, the second 3 lines, and the third 5 lines again.
4385 If the second redisplay wouldn't mark rows in the
4386 current matrix invalid, the third redisplay might be
4387 tempted to optimize redisplay based on lines displayed
4388 in the first redisplay. */
4389 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
4390 { 4436 {
4391 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i) 4437 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
4392 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); 4438 int i;
4393 invisible_rows_marked = true; 4439
4440 /* We'll have to play a little bit with when to
4441 detect_input_pending. If it's done too often,
4442 scrolling large windows with repeated scroll-up
4443 commands will too quickly pause redisplay. */
4444 if (!force_p && ++n_updated % preempt_count == 0)
4445 detect_input_pending_ignore_squeezables ();
4446 changed_p |= update_window_line (w, vpos,
4447 &mouse_face_overwritten_p);
4448
4449 /* Mark all rows below the last visible one in the current
4450 matrix as invalid. This is necessary because of
4451 variable line heights. Consider the case of three
4452 successive redisplays, where the first displays 5
4453 lines, the second 3 lines, and the third 5 lines again.
4454 If the second redisplay wouldn't mark rows in the
4455 current matrix invalid, the third redisplay might be
4456 tempted to optimize redisplay based on lines displayed
4457 in the first redisplay. */
4458 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
4459 {
4460 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
4461 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
4462 invisible_rows_marked = true;
4463 }
4394 } 4464 }
4395 }
4396 4465
4397 /* If the window doesn't display its mode line, make sure the 4466 /* If the window doesn't display its mode line, make sure the
4398 corresponding row of the current glyph matrix is disabled, so 4467 corresponding row of the current glyph matrix is disabled, so
4399 that if and when the mode line is displayed again, it will be 4468 that if and when the mode line is displayed again, it will be
4400 cleared and completely redrawn. */ 4469 cleared and completely redrawn. */
4401 if (!window_wants_mode_line (w)) 4470 if (!window_wants_mode_line (w))
4402 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, 4471 SET_MATRIX_ROW_ENABLED_P (w->current_matrix,
4403 w->current_matrix->nrows - 1, false); 4472 w->current_matrix->nrows - 1, false);
4404 4473
4405 if (!invisible_rows_marked) 4474 /* Was display preempted? */
4406 { 4475 paused_p = row < end;
4407 /* If we didn't mark the invisible rows in the current 4476
4408 matrix as invalid above, do that now. This can happen if 4477 if (!paused_p && !invisible_rows_marked)
4409 scrolling_window updates the last visible rows of the
4410 current matrix, in which case the above loop doesn't get
4411 to examine the last visible row. */
4412 int i;
4413 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
4414 { 4478 {
4415 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i); 4479 /* If we didn't mark the invisible rows in the current
4416 if (current_row->enabled_p 4480 matrix as invalid above, do that now. This can happen if
4417 && MATRIX_ROW_BOTTOM_Y (current_row) >= yb) 4481 scrolling_window updates the last visible rows of the
4482 current matrix, in which case the above loop doesn't get
4483 to examine the last visible row. */
4484 int i;
4485 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
4418 { 4486 {
4419 for (++i ; i < w->current_matrix->nrows - 1; ++i) 4487 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i);
4420 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); 4488 if (current_row->enabled_p
4489 && MATRIX_ROW_BOTTOM_Y (current_row) >= yb)
4490 {
4491 for (++i ; i < w->current_matrix->nrows - 1; ++i)
4492 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
4493 }
4421 } 4494 }
4422 } 4495 }
4423 }
4424 4496
4425 set_cursor: 4497 set_cursor:
4426 4498
4427 /* Update the tab line after scrolling because a new tab 4499 /* Update the tab line after scrolling because a new tab
4428 line would otherwise overwrite lines at the top of the window 4500 line would otherwise overwrite lines at the top of the window
4429 that can be scrolled. */ 4501 that can be scrolled. */
4430 if (tab_line_row && tab_line_row->enabled_p) 4502 if (tab_line_row && tab_line_row->enabled_p)
4431 { 4503 {
4432 tab_line_row->y = 0; 4504 tab_line_row->y = 0;
4433 update_window_line (w, 0, &mouse_face_overwritten_p); 4505 update_window_line (w, 0, &mouse_face_overwritten_p);
4434 } 4506 }
4435
4436 /* Update the header line after scrolling because a new header
4437 line would otherwise overwrite lines at the top of the window
4438 that can be scrolled. */
4439 if (header_line_row && header_line_row->enabled_p)
4440 {
4441 header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
4442 update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
4443 }
4444 4507
4445 /* Fix the appearance of overlapping/overlapped rows. */ 4508 /* Update the header line after scrolling because a new header
4446 if (!w->pseudo_window_p) 4509 line would otherwise overwrite lines at the top of the window
4447 { 4510 that can be scrolled. */
4448#ifdef HAVE_WINDOW_SYSTEM 4511 if (header_line_row && header_line_row->enabled_p)
4449 if (changed_p && rif->fix_overlapping_area)
4450 { 4512 {
4451 redraw_overlapped_rows (w, yb); 4513 header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
4452 redraw_overlapping_rows (w, yb); 4514 update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
4453 } 4515 }
4516
4517 /* Fix the appearance of overlapping/overlapped rows. */
4518 if (!paused_p && !w->pseudo_window_p)
4519 {
4520#ifdef HAVE_WINDOW_SYSTEM
4521 if (changed_p && rif->fix_overlapping_area)
4522 {
4523 redraw_overlapped_rows (w, yb);
4524 redraw_overlapping_rows (w, yb);
4525 }
4454#endif 4526#endif
4455 4527
4456 /* Make cursor visible at cursor position of W. */ 4528 /* Make cursor visible at cursor position of W. */
4457 set_window_cursor_after_update (w); 4529 set_window_cursor_after_update (w);
4458 4530
4459#if 0 /* Check that current matrix invariants are satisfied. This is 4531#if 0 /* Check that current matrix invariants are satisfied. This is
4460 for debugging only. See the comment of check_matrix_invariants. */ 4532 for debugging only. See the comment of check_matrix_invariants. */
4461 IF_DEBUG (check_matrix_invariants (w)); 4533 IF_DEBUG (check_matrix_invariants (w));
4462#endif 4534#endif
4463 } 4535 }
4464 4536
4465#ifdef GLYPH_DEBUG 4537#ifdef GLYPH_DEBUG
4466 /* Remember the redisplay method used to display the matrix. */ 4538 /* Remember the redisplay method used to display the matrix. */
4467 strcpy (w->current_matrix->method, w->desired_matrix->method); 4539 strcpy (w->current_matrix->method, w->desired_matrix->method);
4468#endif 4540#endif
4469 4541
4470#ifdef HAVE_WINDOW_SYSTEM 4542#ifdef HAVE_WINDOW_SYSTEM
4471 update_window_fringes (w, 0); 4543 update_window_fringes (w, 0);
4472 4544
4473 /* End the update of window W. Don't set the cursor if we 4545 /* End the update of window W. Don't set the cursor if we
4474 paused updating the display because in this case, 4546 paused updating the display because in this case,
4475 set_window_cursor_after_update hasn't been called, and 4547 set_window_cursor_after_update hasn't been called, and
4476 W->output_cursor doesn't contain the cursor location. */ 4548 W->output_cursor doesn't contain the cursor location. */
4477 gui_update_window_end (w, true, mouse_face_overwritten_p); 4549 gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
4478#endif 4550#endif
4479 /* If the update wasn't interrupted, this window has been 4551 /* If the update wasn't interrupted, this window has been
4480 completely updated. */ 4552 completely updated. */
4481 w->must_be_updated_p = false; 4553 if (!paused_p)
4554 w->must_be_updated_p = false;
4555 }
4556 else
4557 paused_p = 1;
4482 4558
4483#ifdef GLYPH_DEBUG 4559#ifdef GLYPH_DEBUG
4484 /* check_current_matrix_flags (w); */ 4560 /* check_current_matrix_flags (w); */
4485 add_window_display_history (w, w->current_matrix->method); 4561 add_window_display_history (w, w->current_matrix->method, paused_p);
4486#endif 4562#endif
4487 4563
4488 xwidget_end_redisplay (w, w->current_matrix); 4564 xwidget_end_redisplay (w, w->current_matrix);
4489 clear_glyph_matrix (desired_matrix); 4565 clear_glyph_matrix (desired_matrix);
4566
4567 return paused_p;
4490} 4568}
4491 4569
4492#ifdef HAVE_WINDOW_SYSTEM 4570#ifdef HAVE_WINDOW_SYSTEM
@@ -5619,13 +5697,20 @@ tty_set_cursor (void)
5619} 5697}
5620 5698
5621/* Write desired matix of tty frame F and make it current. 5699/* Write desired matix of tty frame F and make it current.
5700
5701 FORCE_P means that the update should not be stopped by pending input.
5622 INHIBIT_ID_P means that scrolling by insert/delete should not be tried. 5702 INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
5623 SET_CURSOR_P false means do not set cursor at point in selected window. */ 5703 SET_CURSOR_P false means do not set cursor at point in selected window.
5624 5704
5625static void 5705 Value is true if update was stopped due to pending input. */
5626write_matrix (struct frame *f, bool inhibit_id_p, 5706
5707static bool
5708write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
5627 bool set_cursor_p, bool updating_menu_p) 5709 bool set_cursor_p, bool updating_menu_p)
5628{ 5710{
5711 if (!force_p && detect_input_pending_ignore_squeezables ())
5712 return true;
5713
5629 /* If we cannot insert/delete lines, it's no use trying it. */ 5714 /* If we cannot insert/delete lines, it's no use trying it. */
5630 if (!FRAME_LINE_INS_DEL_OK (f)) 5715 if (!FRAME_LINE_INS_DEL_OK (f))
5631 inhibit_id_p = true; 5716 inhibit_id_p = true;
@@ -5637,7 +5722,7 @@ write_matrix (struct frame *f, bool inhibit_id_p,
5637 i/d line if just want cursor motion. */ 5722 i/d line if just want cursor motion. */
5638 int first_row = first_enabled_row (f->desired_matrix); 5723 int first_row = first_enabled_row (f->desired_matrix);
5639 if (!inhibit_id_p && first_row >= 0) 5724 if (!inhibit_id_p && first_row >= 0)
5640 scrolling (f); 5725 force_p |= scrolling (f);
5641 5726
5642 /* Update the individual lines as needed. Do bottom line first. This 5727 /* Update the individual lines as needed. Do bottom line first. This
5643 is done so that messages are made visible when pausing. */ 5728 is done so that messages are made visible when pausing. */
@@ -5645,19 +5730,36 @@ write_matrix (struct frame *f, bool inhibit_id_p,
5645 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row)) 5730 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row))
5646 write_row (f, last_row, updating_menu_p); 5731 write_row (f, last_row, updating_menu_p);
5647 5732
5733 bool pause_p = false;
5648 if (first_row >= 0) 5734 if (first_row >= 0)
5649 for (int i = first_row; i < last_row; ++i) 5735 {
5650 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i)) 5736 const int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
5651 write_row (f, i, updating_menu_p); 5737
5738 for (int i = first_row, n = 0; i < last_row; ++i)
5739 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
5740 {
5741 if (!force_p && n % preempt_count == 0
5742 && detect_input_pending_ignore_squeezables ())
5743 {
5744 pause_p = true;
5745 break;
5746 }
5747
5748 write_row (f, i, updating_menu_p);
5749 ++n;
5750 }
5751 }
5652 5752
5653 /* Now just clean up termcap drivers and set cursor, etc. */ 5753 /* Now just clean up termcap drivers and set cursor, etc. */
5654 if (set_cursor_p) 5754 if (!pause_p && set_cursor_p)
5655 tty_set_cursor (); 5755 tty_set_cursor ();
5756
5757 return pause_p;
5656} 5758}
5657 5759
5658/* Do line insertions/deletions on frame F for frame-based redisplay. */ 5760/* Do line insertions/deletions on frame F for frame-based redisplay. */
5659 5761
5660static void 5762static bool
5661scrolling (struct frame *frame) 5763scrolling (struct frame *frame)
5662{ 5764{
5663 /* In fact this code should never be reached at all under 5765 /* In fact this code should never be reached at all under
@@ -5694,7 +5796,7 @@ scrolling (struct frame *frame)
5694 if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) 5796 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
5695 { 5797 {
5696 SAFE_FREE (); 5798 SAFE_FREE ();
5697 return; 5799 return false;
5698 } 5800 }
5699 old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i)); 5801 old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i));
5700 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i)) 5802 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
@@ -5725,7 +5827,7 @@ scrolling (struct frame *frame)
5725 || unchanged_at_bottom == height) 5827 || unchanged_at_bottom == height)
5726 { 5828 {
5727 SAFE_FREE (); 5829 SAFE_FREE ();
5728 return; 5830 return true;
5729 } 5831 }
5730 5832
5731 window_size = (height - unchanged_at_top 5833 window_size = (height - unchanged_at_top
@@ -5755,6 +5857,7 @@ scrolling (struct frame *frame)
5755 5857
5756 SAFE_FREE (); 5858 SAFE_FREE ();
5757#endif 5859#endif
5860 return false;
5758} 5861}
5759 5862
5760 5863
@@ -6886,18 +6989,27 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
6886 6989
6887 6990
6888DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0, 6991DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
6889 doc : /* Perform redisplay. 6992 doc: /* Perform redisplay.
6890Optional arg FORCE exists for historical reasons and is ignored. 6993Optional arg FORCE, if non-nil, prevents redisplay from being
6891Value is t if redisplay has been performed, nil if executing a 6994preempted by arriving input, even if `redisplay-dont-pause' is nil.
6892keyboard macro. */) 6995If `redisplay-dont-pause' is non-nil (the default), redisplay is never
6996preempted by arriving input, so FORCE does nothing.
6997
6998Return t if redisplay was performed, nil if redisplay was preempted
6999immediately by pending input. */)
6893 (Lisp_Object force) 7000 (Lisp_Object force)
6894{ 7001{
6895 swallow_events (true); 7002 swallow_events (true);
6896 if (!NILP (Vexecuting_kbd_macro)) 7003 if ((detect_input_pending_run_timers (1)
7004 && NILP (force) && !redisplay_dont_pause)
7005 || !NILP (Vexecuting_kbd_macro))
6897 return Qnil; 7006 return Qnil;
6898 7007
7008 specpdl_ref count = SPECPDL_INDEX ();
7009 if (!NILP (force) && !redisplay_dont_pause)
7010 specbind (Qredisplay_dont_pause, Qt);
6899 redisplay_preserve_echo_area (2); 7011 redisplay_preserve_echo_area (2);
6900 return Qt; 7012 return unbind_to (count, Qt);
6901} 7013}
6902 7014
6903 7015
@@ -7350,6 +7462,8 @@ syms_of_display (void)
7350 /* This is the "purpose" slot of a display table. */ 7462 /* This is the "purpose" slot of a display table. */
7351 DEFSYM (Qdisplay_table, "display-table"); 7463 DEFSYM (Qdisplay_table, "display-table");
7352 DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp"); 7464 DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp");
7465
7466 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
7353 DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor"); 7467 DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor");
7354 7468
7355 DEFVAR_INT ("baud-rate", baud_rate, 7469 DEFVAR_INT ("baud-rate", baud_rate,
@@ -7431,6 +7545,17 @@ It is also used for standard output and error streams.
7431See `buffer-display-table' for more information. */); 7545See `buffer-display-table' for more information. */);
7432 Vstandard_display_table = Qnil; 7546 Vstandard_display_table = Qnil;
7433 7547
7548 DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
7549 doc: /* Nil means display update is paused when input is detected. */);
7550 /* Contrary to expectations, a value of "false" can be detrimental to
7551 responsiveness since aborting a redisplay throws away some of the
7552 work already performed. It's usually more efficient (and gives
7553 more prompt feedback to the user) to let the redisplay terminate,
7554 and just completely skip the next command's redisplay (which is
7555 done regardless of this setting if there's pending input at the
7556 beginning of the next redisplay). */
7557 redisplay_dont_pause = true;
7558
7434 DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout, 7559 DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout,
7435 doc: /* The default timeout (in seconds) for `x-show-tip'. */); 7560 doc: /* The default timeout (in seconds) for `x-show-tip'. */);
7436 Vx_show_tooltip_timeout = make_fixnum (5); 7561 Vx_show_tooltip_timeout = make_fixnum (5);
diff --git a/src/keyboard.c b/src/keyboard.c
index fe485a3efd6..bfb5fd3592b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2663,7 +2663,8 @@ read_char (int commandflag, Lisp_Object map,
2663 swallow_events (false); /* May clear input_pending. */ 2663 swallow_events (false); /* May clear input_pending. */
2664 2664
2665 /* Redisplay if no pending input. */ 2665 /* Redisplay if no pending input. */
2666 while (!(input_pending && input_was_pending)) 2666 while (!(input_pending
2667 && (input_was_pending || !redisplay_dont_pause)))
2667 { 2668 {
2668 input_was_pending = input_pending; 2669 input_was_pending = input_pending;
2669 if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window)) 2670 if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window))
diff --git a/src/minibuf.c b/src/minibuf.c
index 390db0d31fa..c8267045397 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -914,9 +914,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
914 XWINDOW (minibuf_window)->cursor.x = 0; 914 XWINDOW (minibuf_window)->cursor.x = 0;
915 XWINDOW (minibuf_window)->must_be_updated_p = true; 915 XWINDOW (minibuf_window)->must_be_updated_p = true;
916 struct frame *sf = XFRAME (selected_frame); 916 struct frame *sf = XFRAME (selected_frame);
917 update_frame (sf, true); 917 update_frame (sf, true, true);
918 if (is_tty_frame (sf)) 918 if (is_tty_frame (sf))
919 combine_updates_for_frame (sf, true); 919 combine_updates_for_frame (sf, true, true);
920 920
921#ifndef HAVE_NTGUI 921#ifndef HAVE_NTGUI
922 flush_frame (XFRAME (XWINDOW (minibuf_window)->frame)); 922 flush_frame (XFRAME (XWINDOW (minibuf_window)->frame));
diff --git a/src/xdisp.c b/src/xdisp.c
index 3364c6870cf..8196d1236ba 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1116,6 +1116,7 @@ static void set_iterator_to_next (struct it *, bool);
1116static void mark_window_display_accurate_1 (struct window *, bool); 1116static void mark_window_display_accurate_1 (struct window *, bool);
1117static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t); 1117static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
1118static bool cursor_row_p (struct glyph_row *); 1118static bool cursor_row_p (struct glyph_row *);
1119static int redisplay_mode_lines (Lisp_Object, bool);
1119 1120
1120static void handle_line_prefix (struct it *); 1121static void handle_line_prefix (struct it *);
1121 1122
@@ -13510,6 +13511,24 @@ echo_area_display (bool update_frame_p)
13510 here could cause confusion. */ 13511 here could cause confusion. */
13511 if (update_frame_p && !redisplaying_p) 13512 if (update_frame_p && !redisplaying_p)
13512 { 13513 {
13514 int n = 0;
13515
13516 /* If the display update has been interrupted by pending
13517 input, update mode lines in the frame. Due to the
13518 pending input, it might have been that redisplay hasn't
13519 been called, so that mode lines above the echo area are
13520 garbaged. This looks odd, so we prevent it here. */
13521 if (!display_completed)
13522 {
13523 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
13524
13525#ifdef HAVE_WINDOW_SYSTEM
13526 if (FRAME_WINDOW_P (f)
13527 && FRAME_RIF (f)->clear_under_internal_border)
13528 FRAME_RIF (f)->clear_under_internal_border (f);
13529#endif
13530 }
13531
13513 if (window_height_changed_p 13532 if (window_height_changed_p
13514 /* Don't do this if Emacs is shutting down. Redisplay 13533 /* Don't do this if Emacs is shutting down. Redisplay
13515 needs to run hooks. */ 13534 needs to run hooks. */
@@ -13518,10 +13537,13 @@ echo_area_display (bool update_frame_p)
13518 /* Must update other windows. Likewise as in other 13537 /* Must update other windows. Likewise as in other
13519 cases, don't let this update be interrupted by 13538 cases, don't let this update be interrupted by
13520 pending input. */ 13539 pending input. */
13540 specpdl_ref count = SPECPDL_INDEX ();
13541 specbind (Qredisplay_dont_pause, Qt);
13521 fset_redisplay (f); 13542 fset_redisplay (f);
13522 redisplay_internal (); 13543 redisplay_internal ();
13544 unbind_to (count, Qnil);
13523 } 13545 }
13524 else if (FRAME_WINDOW_P (f)) 13546 else if (FRAME_WINDOW_P (f) && n == 0)
13525 { 13547 {
13526 /* Window configuration is the same as before. 13548 /* Window configuration is the same as before.
13527 Can do with a display update of the echo area, 13549 Can do with a display update of the echo area,
@@ -13531,9 +13553,9 @@ echo_area_display (bool update_frame_p)
13531 } 13553 }
13532 else 13554 else
13533 { 13555 {
13534 update_frame (f, true); 13556 update_frame (f, true, true);
13535 if (is_tty_frame (f)) 13557 if (is_tty_frame (f))
13536 combine_updates_for_frame (f, true); 13558 combine_updates_for_frame (f, true, true);
13537 } 13559 }
13538 13560
13539 /* If cursor is in the echo area, make sure that the next 13561 /* If cursor is in the echo area, make sure that the next
@@ -16916,6 +16938,7 @@ redisplay_internal (void)
16916 struct window *w = XWINDOW (selected_window); 16938 struct window *w = XWINDOW (selected_window);
16917 struct window *sw; 16939 struct window *sw;
16918 struct frame *fr; 16940 struct frame *fr;
16941 bool pending;
16919 bool must_finish = false, match_p; 16942 bool must_finish = false, match_p;
16920 struct text_pos tlbufpos, tlendpos; 16943 struct text_pos tlbufpos, tlendpos;
16921 int number_of_visible_frames; 16944 int number_of_visible_frames;
@@ -17001,6 +17024,7 @@ redisplay_internal (void)
17001 /* Remember the currently selected window. */ 17024 /* Remember the currently selected window. */
17002 sw = w; 17025 sw = w;
17003 17026
17027 pending = false;
17004 forget_escape_and_glyphless_faces (); 17028 forget_escape_and_glyphless_faces ();
17005 17029
17006 inhibit_free_realized_faces = false; 17030 inhibit_free_realized_faces = false;
@@ -17566,7 +17590,7 @@ redisplay_internal (void)
17566 unrequest_sigio (); 17590 unrequest_sigio ();
17567 STOP_POLLING; 17591 STOP_POLLING;
17568 17592
17569 update_frame (f, false); 17593 pending |= update_frame (f, false, false);
17570 /* On some platforms (at least MS-Windows), the 17594 /* On some platforms (at least MS-Windows), the
17571 scroll_run_hook called from scrolling_window 17595 scroll_run_hook called from scrolling_window
17572 called from update_frame could set the frame's 17596 called from update_frame could set the frame's
@@ -17588,24 +17612,27 @@ redisplay_internal (void)
17588 } 17612 }
17589 17613
17590 if (CONSP (tty_root_frames)) 17614 if (CONSP (tty_root_frames))
17591 combine_updates (tty_root_frames, false); 17615 pending |= combine_updates (tty_root_frames, false, false);
17592 17616
17593 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); 17617 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
17594 17618
17595 /* Do the mark_window_display_accurate after all windows have 17619 if (!pending)
17596 been redisplayed because this call resets flags in buffers
17597 which are needed for proper redisplay. */
17598 FOR_EACH_FRAME (tail, frame)
17599 { 17620 {
17600 struct frame *f = XFRAME (frame); 17621 /* Do the mark_window_display_accurate after all windows have
17601 if (f->updated_p) 17622 been redisplayed because this call resets flags in buffers
17602 { 17623 which are needed for proper redisplay. */
17603 f->redisplay = false; 17624 FOR_EACH_FRAME (tail, frame)
17604 f->garbaged = false; 17625 {
17605 mark_window_display_accurate (f->root_window, true); 17626 struct frame *f = XFRAME (frame);
17606 if (FRAME_TERMINAL (f)->frame_up_to_date_hook) 17627 if (f->updated_p)
17607 FRAME_TERMINAL (f)->frame_up_to_date_hook (f); 17628 {
17608 } 17629 f->redisplay = false;
17630 f->garbaged = false;
17631 mark_window_display_accurate (f->root_window, true);
17632 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
17633 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
17634 }
17635 }
17609 } 17636 }
17610 } 17637 }
17611 else if (FRAME_REDISPLAY_P (sf)) 17638 else if (FRAME_REDISPLAY_P (sf))
@@ -17669,10 +17696,10 @@ redisplay_internal (void)
17669 } 17696 }
17670 17697
17671 XWINDOW (selected_window)->must_be_updated_p = true; 17698 XWINDOW (selected_window)->must_be_updated_p = true;
17672 update_frame (sf, false); 17699 pending = update_frame (sf, false, false);
17673 17700
17674 if (is_tty_frame (sf)) 17701 if (is_tty_frame (sf))
17675 combine_updates_for_frame (sf, false); 17702 pending |= combine_updates_for_frame (sf, false, false);
17676 17703
17677 sf->cursor_type_changed = false; 17704 sf->cursor_type_changed = false;
17678 sf->inhibit_clear_image_cache = false; 17705 sf->inhibit_clear_image_cache = false;
@@ -17689,11 +17716,11 @@ redisplay_internal (void)
17689 if (mini_frame != sf) 17716 if (mini_frame != sf)
17690 { 17717 {
17691 XWINDOW (mini_window)->must_be_updated_p = true; 17718 XWINDOW (mini_window)->must_be_updated_p = true;
17692 update_frame (mini_frame, false); 17719 pending |= update_frame (mini_frame, false, false);
17693 if (is_tty_frame (mini_frame)) 17720 if (is_tty_frame (mini_frame))
17694 combine_updates_for_frame (mini_frame, false); 17721 pending |= combine_updates_for_frame (mini_frame, false, false);
17695 mini_frame->cursor_type_changed = false; 17722 mini_frame->cursor_type_changed = false;
17696 if (hscroll_retries <= MAX_HSCROLL_RETRIES 17723 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
17697 && hscroll_windows (mini_window)) 17724 && hscroll_windows (mini_window))
17698 { 17725 {
17699 hscroll_retries++; 17726 hscroll_retries++;
@@ -17702,26 +17729,47 @@ redisplay_internal (void)
17702 } 17729 }
17703 } 17730 }
17704 17731
17705 if (!consider_all_windows_p) 17732 /* If display was paused because of pending input, make sure we do a
17733 thorough update the next time. */
17734 if (pending)
17706 { 17735 {
17707 /* This has already been done above if 17736 /* Prevent the optimization at the beginning of
17708 consider_all_windows_p is set. */ 17737 redisplay_internal that tries a single-line update of the
17709 if (XBUFFER (w->contents)->text->redisplay 17738 line containing the cursor in the selected window. */
17710 && buffer_window_count (XBUFFER (w->contents)) > 1) 17739 CHARPOS (this_line_start_pos) = 0;
17711 /* This can happen if b->text->redisplay was set during
17712 jit-lock. */
17713 propagate_buffer_redisplay ();
17714 mark_window_display_accurate_1 (w, true);
17715 17740
17716 /* Say overlay arrows are up to date. */ 17741 /* Let the overlay arrow be updated the next time. */
17717 update_overlay_arrows (1); 17742 update_overlay_arrows (0);
17718 17743
17719 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0) 17744 /* If we pause after scrolling, some rows in the current
17720 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf); 17745 matrices of some windows are not valid. */
17746 if (!WINDOW_FULL_WIDTH_P (w)
17747 && !FRAME_WINDOW_P (XFRAME (w->frame)))
17748 update_mode_lines = 36;
17721 } 17749 }
17750 else
17751 {
17752 if (!consider_all_windows_p)
17753 {
17754 /* This has already been done above if
17755 consider_all_windows_p is set. */
17756 if (XBUFFER (w->contents)->text->redisplay
17757 && buffer_window_count (XBUFFER (w->contents)) > 1)
17758 /* This can happen if b->text->redisplay was set during
17759 jit-lock. */
17760 propagate_buffer_redisplay ();
17761 mark_window_display_accurate_1 (w, true);
17722 17762
17723 update_mode_lines = 0; 17763 /* Say overlay arrows are up to date. */
17724 windows_or_buffers_changed = 0; 17764 update_overlay_arrows (1);
17765
17766 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
17767 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
17768 }
17769
17770 update_mode_lines = 0;
17771 windows_or_buffers_changed = 0;
17772 }
17725 17773
17726 /* Start SIGIO interrupts coming again. Having them off during the 17774 /* Start SIGIO interrupts coming again. Having them off during the
17727 code above makes it less likely one will discard output, but not 17775 code above makes it less likely one will discard output, but not
@@ -17737,23 +17785,26 @@ redisplay_internal (void)
17737 redisplay constructing glyphs, so simply exposing a frame won't 17785 redisplay constructing glyphs, so simply exposing a frame won't
17738 display anything in this case. So, we have to display these 17786 display anything in this case. So, we have to display these
17739 frames here explicitly. */ 17787 frames here explicitly. */
17740 int new_count = 0; 17788 if (!pending)
17741
17742 FOR_EACH_FRAME (tail, frame)
17743 { 17789 {
17744 if (FRAME_REDISPLAY_P (XFRAME (frame))) 17790 int new_count = 0;
17745 new_count++; 17791
17746 } 17792 FOR_EACH_FRAME (tail, frame)
17793 {
17794 if (FRAME_REDISPLAY_P (XFRAME (frame)))
17795 new_count++;
17796 }
17747 17797
17748 if (new_count != number_of_visible_frames) 17798 if (new_count != number_of_visible_frames)
17749 windows_or_buffers_changed = 52; 17799 windows_or_buffers_changed = 52;
17800 }
17750 17801
17751 /* Change frame size now if a change is pending. */ 17802 /* Change frame size now if a change is pending. */
17752 do_pending_window_change (true); 17803 do_pending_window_change (true);
17753 17804
17754 /* If we just did a pending size change, or have additional 17805 /* If we just did a pending size change, or have additional
17755 visible frames, or selected_window changed, redisplay again. */ 17806 visible frames, or selected_window changed, redisplay again. */
17756 if (windows_or_buffers_changed 17807 if ((windows_or_buffers_changed && !pending)
17757 || (WINDOWP (selected_window) 17808 || (WINDOWP (selected_window)
17758 && (w = XWINDOW (selected_window)) != sw)) 17809 && (w = XWINDOW (selected_window)) != sw))
17759 goto retry; 17810 goto retry;
@@ -27343,6 +27394,60 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
27343 Mode Line 27394 Mode Line
27344 ***********************************************************************/ 27395 ***********************************************************************/
27345 27396
27397/* Redisplay mode lines in the window tree whose root is WINDOW.
27398 If FORCE, redisplay mode lines unconditionally.
27399 Otherwise, redisplay only mode lines that are garbaged. Value is
27400 the number of windows whose mode lines were redisplayed. */
27401
27402static int
27403redisplay_mode_lines (Lisp_Object window, bool force)
27404{
27405 int nwindows = 0;
27406
27407 while (!NILP (window))
27408 {
27409 struct window *w = XWINDOW (window);
27410
27411 if (WINDOWP (w->contents))
27412 nwindows += redisplay_mode_lines (w->contents, force);
27413 else if (force
27414 || FRAME_GARBAGED_P (XFRAME (w->frame))
27415 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
27416 {
27417 struct text_pos lpoint;
27418 struct buffer *old = current_buffer;
27419
27420 /* Set the window's buffer for the mode line display. */
27421 SET_TEXT_POS (lpoint, PT, PT_BYTE);
27422 set_buffer_internal_1 (XBUFFER (w->contents));
27423
27424 /* Point refers normally to the selected window. For any
27425 other window, set up appropriate value. */
27426 if (!EQ (window, selected_window))
27427 {
27428 struct text_pos pt;
27429
27430 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
27431 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
27432 }
27433
27434 /* Display mode lines. */
27435 clear_glyph_matrix (w->desired_matrix);
27436 if (display_mode_lines (w))
27437 ++nwindows;
27438
27439 /* Restore old settings. */
27440 set_buffer_internal_1 (old);
27441 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
27442 }
27443
27444 window = w->next;
27445 }
27446
27447 return nwindows;
27448}
27449
27450
27346/* Display the mode line, the header line, and the tab-line of window 27451/* Display the mode line, the header line, and the tab-line of window
27347 W. Value is the sum number of mode lines, header lines, and tab 27452 W. Value is the sum number of mode lines, header lines, and tab
27348 lines actually displayed. */ 27453 lines actually displayed. */