Don't pause display for pending input

* src/dispnew.c: Remove display_completed, redisplay_dont_pause,
redisplay-dont-pause was declared obsolete in Emacs 24.  Remove anything
checking pending input, change function signatures accordingly, and so
on.

* src/keyboard.c (read_char): Don't use redisplay_dont_pause.
* src/minibuf.c (read_minibuf): Use new function signatures.
* src/xdisp.c: Don't check display_completed. Use new API.

* lisp/subr.el (redisplay-dont-pause): Remove declaration.
This commit is contained in:
Gerd Möllmann 2024-11-15 13:34:55 +01:00
parent 4da9abe653
commit f62d70f52f
6 changed files with 291 additions and 526 deletions

View file

@ -1990,7 +1990,6 @@ be a list of the form returned by `event-start' and `event-end'."
;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25,
;; but it's only been marked for compilation warnings since Emacs-29.
"25.1")
(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
(make-obsolete-variable 'operating-system-release nil "28.1")
(make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1")

View file

@ -1322,9 +1322,6 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int);
extern struct glyph space_glyph;
/* True means last display completed. False means it was preempted. */
extern bool display_completed;
/************************************************************************
Glyph Strings
@ -3805,7 +3802,7 @@ extern Lisp_Object marginal_area_string (struct window *, enum window_part,
Lisp_Object *,
int *, int *, int *, int *);
extern void redraw_frame (struct frame *);
extern bool update_frame (struct frame *, bool, bool);
void update_frame (struct frame *, bool);
extern void update_frame_with_menu (struct frame *, int, int);
extern int update_mouse_position (struct frame *, int, int);
extern void bitch_at_user (void);
@ -3924,8 +3921,8 @@ Lisp_Object frames_in_reverse_z_order (struct frame *f, bool visible);
bool is_tty_frame (struct frame *f);
bool is_tty_child_frame (struct frame *f);
bool is_tty_root_frame (struct frame *f);
bool combine_updates (Lisp_Object root_frames, bool force_p, bool inhibit_id_p);
bool combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_id_p);
void combine_updates (Lisp_Object root_frames, bool inhibit_id_p);
void combine_updates_for_frame (struct frame *f, bool inhibit_id_p);
void tty_raise_lower_frame (struct frame *f, bool raise);
int max_child_z_order (struct frame *parent);

View file

@ -93,10 +93,10 @@ static void check_matrix_pointers (struct glyph_matrix *,
struct glyph_matrix *);
#endif
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 write_matrix (struct frame *, bool, bool, bool, bool);
static bool scrolling (struct frame *);
static void update_window_tree (struct window *);
static void update_window (struct window *);
static void write_matrix (struct frame *, bool, bool, bool);
static void scrolling (struct frame *);
static void set_window_cursor_after_update (struct window *);
static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
@ -116,10 +116,6 @@ check_rows (struct frame *f)
}
#endif
/* True means last display completed. False means it was preempted. */
bool display_completed;
/* True means SIGWINCH happened when not safe. */
static bool delayed_size_change;
@ -175,11 +171,10 @@ static uintmax_t history_tick;
/* Add to the redisplay history how window W has been displayed.
MSG is a trace containing the information how W's glyph matrix
has been constructed. PAUSED_P means that the update
has been interrupted for pending input. */
has been constructed. */
static void
add_window_display_history (struct window *w, const char *msg, bool paused_p)
add_window_display_history (struct window *w, const char *msg)
{
char *buf;
void *ptr = w;
@ -190,14 +185,13 @@ add_window_display_history (struct window *w, const char *msg, bool paused_p)
++history_idx;
snprintf (buf, sizeof redisplay_history[0].trace,
"%"PRIuMAX": window %p (%s)%s\n%s",
"%"PRIuMAX": window %p %s\n%s",
history_tick++,
ptr,
((BUFFERP (w->contents)
&& STRINGP (BVAR (XBUFFER (w->contents), name)))
? SSDATA (BVAR (XBUFFER (w->contents), name))
: "???"),
paused_p ? " ***paused***" : "",
msg);
}
@ -2136,8 +2130,7 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
current matrix over a call to adjust_glyph_matrix, we must
make a copy of the current glyphs, and restore the current
matrix' contents from that copy. */
if (display_completed
&& !FRAME_GARBAGED_P (f)
if (!FRAME_GARBAGED_P (f)
&& matrix_dim.width == f->current_matrix->matrix_w
&& matrix_dim.height == f->current_matrix->matrix_h
/* For some reason, the frame glyph matrix gets corrupted if
@ -2682,7 +2675,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
frame and window share glyphs. */
strcpy (w->current_matrix->method, w->desired_matrix->method);
add_window_display_history (w, w->current_matrix->method, 0);
add_window_display_history (w, w->current_matrix->method);
#endif
}
@ -3778,7 +3771,7 @@ update_bar_window (Lisp_Object window, Lisp_Object *current,
struct window *w = XWINDOW (window);
if (w->must_be_updated_p)
{
update_window (w, true);
update_window (w);
w->must_be_updated_p = false;
Lisp_Object tem = *current;
*current = *desired;
@ -3808,8 +3801,8 @@ update_tool_bar (struct frame *f)
#endif
}
static bool
update_window_frame (struct frame *f, bool force_p)
static void
update_window_frame (struct frame *f)
{
eassert (FRAME_WINDOW_P (f));
update_begin (f);
@ -3817,19 +3810,17 @@ update_window_frame (struct frame *f, bool force_p)
update_tab_bar (f);
update_tool_bar (f);
struct window *root_window = XWINDOW (f->root_window);
bool paused_p = update_window_tree (root_window, force_p);
update_window_tree (root_window);
update_end (f);
set_window_update_flags (root_window, false);
return paused_p;
}
static bool
update_initial_frame (struct frame *f, bool force_p)
static void
update_initial_frame (struct frame *f)
{
build_frame_matrix (f);
struct window *root_window = XWINDOW (f->root_window);
set_window_update_flags (root_window, false);
return false;
}
static void
@ -3840,11 +3831,10 @@ flush_terminal (struct frame *f)
fflush (FRAME_TTY (f)->output);
}
static bool
update_tty_frame (struct frame *f, bool force_p)
static void
update_tty_frame (struct frame *f)
{
build_frame_matrix (f);
return false;
}
/* Return the cursor position of the selected window of frame F, in
@ -3952,8 +3942,8 @@ terminal_cursor_magic (struct frame *root, struct frame *topmost_child)
}
}
bool
combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
void
combine_updates_for_frame (struct frame *f, bool inhibit_scrolling)
{
struct frame *root = root_frame (f);
eassert (FRAME_VISIBLE_P (root));
@ -3969,13 +3959,12 @@ combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling
}
update_begin (root);
bool paused = write_matrix (root, force_p, inhibit_scrolling, 1, false);
if (!paused)
make_matrix_current (root);
write_matrix (root, inhibit_scrolling, 1, false);
make_matrix_current (root);
update_end (root);
/* If a child is displayed, and the cursor is displayed in another
frame, the child might lay above the cursor, so that it appers to
frame, the child might lay above the cursor, so that it appears to
"shine through" the child. Avoid that because it's confusing. */
if (topmost_child)
terminal_cursor_magic (root, topmost_child);
@ -3992,66 +3981,33 @@ combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling
add_frame_display_history (f, false);
#endif
}
return paused;
}
/* Update on the screen all root frames ROOTS. Called from
redisplay_internal as the last step of redisplaying. */
bool
combine_updates (Lisp_Object roots, bool force_p, bool inhibit_scrolling)
void
combine_updates (Lisp_Object roots, bool inhibit_scrolling)
{
if (redisplay_dont_pause)
force_p = true;
for (; CONSP (roots); roots = XCDR (roots))
{
struct frame *root = XFRAME (XCAR (roots));
if (combine_updates_for_frame (root, force_p, inhibit_scrolling))
{
display_completed = false;
return true;
}
combine_updates_for_frame (root, inhibit_scrolling);
}
display_completed = true;
return false;
}
/* Update frame F based on the data in desired matrices.
If INHIBIT_SCROLLING, don't try scrolling. */
If FORCE_P, don't let redisplay be stopped by detecting pending input.
If INHIBIT_SCROLLING, don't try scrolling.
Value is true if redisplay was stopped due to pending input. */
bool
update_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
void
update_frame (struct frame *f, bool inhibit_scrolling)
{
struct window *root_window = XWINDOW (f->root_window);
if (redisplay_dont_pause)
force_p = true;
else if (!force_p && detect_input_pending_ignore_squeezables ())
{
/* Reset flags indicating that a window should be updated. */
set_window_update_flags (root_window, false);
display_completed = false;
return true;
}
bool paused;
if (FRAME_WINDOW_P (f))
paused = update_window_frame (f, force_p);
update_window_frame (f);
else if (FRAME_INITIAL_P (f))
paused = update_initial_frame (f, force_p);
update_initial_frame (f);
else
paused = update_tty_frame (f, force_p);
if (paused)
display_completed = false;
return paused;
update_tty_frame (f);
}
/* Update a TTY frame F that has a menu dropped down over some of its
@ -4077,7 +4033,7 @@ update_frame_with_menu (struct frame *f, int row, int col)
cursor_at_point_p = !(row >= 0 && col >= 0);
/* Do not stop due to pending input, and do not try scrolling. This
means that write_glyphs will always return false. */
write_matrix (f, 1, 1, cursor_at_point_p, true);
write_matrix (f, 1, cursor_at_point_p, true);
make_matrix_current (f);
clear_desired_matrices (f);
/* ROW and COL tell us where in the menu to position the cursor, so
@ -4100,7 +4056,6 @@ update_frame_with_menu (struct frame *f, int row, int col)
/* Reset flags indicating that a window should be updated. */
set_window_update_flags (root_window, false);
display_completed = true;
}
/* Update the mouse position for a frame F. This handles both
@ -4156,30 +4111,24 @@ properties or updating the help echo text. */)
Window-based updates
************************************************************************/
/* Perform updates in window tree rooted at W.
If FORCE_P, don't stop updating if input is pending. */
/* Perform updates in window tree rooted at W. */
static bool
update_window_tree (struct window *w, bool force_p)
static void
update_window_tree (struct window *w)
{
bool paused_p = 0;
while (w && !paused_p)
while (w)
{
if (WINDOWP (w->contents))
paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
update_window_tree (XWINDOW (w->contents));
else if (w->must_be_updated_p)
paused_p |= update_window (w, force_p);
update_window (w);
w = NILP (w->next) ? 0 : XWINDOW (w->next);
}
return paused_p;
}
/* Update window W if its flag must_be_updated_p is set.
If FORCE_P, don't stop updating if input is pending. */
/* Update window W if its flag must_be_updated_p is set. */
void
update_single_window (struct window *w)
@ -4190,7 +4139,7 @@ update_single_window (struct window *w)
/* Update W. */
update_begin (f);
update_window (w, true);
update_window (w);
update_end (f);
/* Reset flag in W. */
@ -4330,15 +4279,12 @@ check_current_matrix_flags (struct window *w)
#endif /* GLYPH_DEBUG */
/* Update display of window W.
If FORCE_P, don't stop updating when input is pending. */
/* Update display of window W. */
static bool
update_window (struct window *w, bool force_p)
static void
update_window (struct window *w)
{
struct glyph_matrix *desired_matrix = w->desired_matrix;
bool paused_p;
int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
#ifdef HAVE_WINDOW_SYSTEM
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
#endif
@ -4347,224 +4293,200 @@ update_window (struct window *w, bool force_p)
eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
#endif
/* Check pending input the first time so that we can quickly return. */
if (!force_p)
detect_input_pending_ignore_squeezables ();
/* If forced to complete the update, no input is pending, or we are
tracking the mouse, do the update. */
if (force_p || !input_pending || !NILP (track_mouse))
{
struct glyph_row *row, *end;
struct glyph_row *mode_line_row;
struct glyph_row *tab_line_row;
struct glyph_row *header_line_row;
int yb;
bool changed_p = 0, mouse_face_overwritten_p = 0;
int n_updated = 0;
bool invisible_rows_marked = false;
struct glyph_row *row, *end;
struct glyph_row *mode_line_row;
struct glyph_row *tab_line_row;
struct glyph_row *header_line_row;
int yb;
bool changed_p = 0, mouse_face_overwritten_p = 0;
bool invisible_rows_marked = false;
#ifdef HAVE_WINDOW_SYSTEM
gui_update_window_begin (w);
gui_update_window_begin (w);
#else
(void) changed_p;
(void) changed_p;
#endif
yb = window_text_bottom_y (w);
row = MATRIX_ROW (desired_matrix, 0);
end = MATRIX_MODE_LINE_ROW (desired_matrix);
yb = window_text_bottom_y (w);
row = MATRIX_ROW (desired_matrix, 0);
end = MATRIX_MODE_LINE_ROW (desired_matrix);
/* Take note of the tab line, if there is one. We will
update it below, after updating all of the window's lines. */
if (row->mode_line_p && row->tab_line_p)
{
tab_line_row = row;
++row;
}
else
tab_line_row = NULL;
/* Take note of the header line, if there is one. We will
update it below, after updating all of the window's lines. */
if (row->mode_line_p)
{
header_line_row = row;
++row;
}
else
header_line_row = NULL;
/* Update the mode line, if necessary. */
mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
{
mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
desired_matrix),
&mouse_face_overwritten_p);
}
/* Find first enabled row. Optimizations in redisplay_internal
may lead to an update with only one row enabled. There may
be also completely empty matrices. */
while (row < end && !row->enabled_p)
++row;
/* Try reusing part of the display by copying. */
if (row < end && !desired_matrix->no_scrolling_p)
{
int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
+ (header_line_row != NULL ? 1 : 0));
if (rc < 0)
{
/* All rows were found to be equal. */
paused_p = 0;
goto set_cursor;
}
else if (rc > 0)
{
/* We've scrolled the display. */
force_p = 1;
changed_p = 1;
}
}
/* Update the rest of the lines. */
for (; row < end && (force_p || !input_pending); ++row)
/* scrolling_window resets the enabled_p flag of the rows it
reuses from current_matrix. */
if (row->enabled_p)
{
int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
int i;
/* We'll have to play a little bit with when to
detect_input_pending. If it's done too often,
scrolling large windows with repeated scroll-up
commands will too quickly pause redisplay. */
if (!force_p && ++n_updated % preempt_count == 0)
detect_input_pending_ignore_squeezables ();
changed_p |= update_window_line (w, vpos,
&mouse_face_overwritten_p);
/* Mark all rows below the last visible one in the current
matrix as invalid. This is necessary because of
variable line heights. Consider the case of three
successive redisplays, where the first displays 5
lines, the second 3 lines, and the third 5 lines again.
If the second redisplay wouldn't mark rows in the
current matrix invalid, the third redisplay might be
tempted to optimize redisplay based on lines displayed
in the first redisplay. */
if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
{
for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
invisible_rows_marked = true;
}
}
/* If the window doesn't display its mode line, make sure the
corresponding row of the current glyph matrix is disabled, so
that if and when the mode line is displayed again, it will be
cleared and completely redrawn. */
if (!window_wants_mode_line (w))
SET_MATRIX_ROW_ENABLED_P (w->current_matrix,
w->current_matrix->nrows - 1, false);
/* Was display preempted? */
paused_p = row < end;
if (!paused_p && !invisible_rows_marked)
{
/* If we didn't mark the invisible rows in the current
matrix as invalid above, do that now. This can happen if
scrolling_window updates the last visible rows of the
current matrix, in which case the above loop doesn't get
to examine the last visible row. */
int i;
for (i = 0; i < w->current_matrix->nrows - 1; ++i)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i);
if (current_row->enabled_p
&& MATRIX_ROW_BOTTOM_Y (current_row) >= yb)
{
for (++i ; i < w->current_matrix->nrows - 1; ++i)
SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
}
}
}
set_cursor:
/* Update the tab line after scrolling because a new tab
line would otherwise overwrite lines at the top of the window
that can be scrolled. */
if (tab_line_row && tab_line_row->enabled_p)
{
tab_line_row->y = 0;
update_window_line (w, 0, &mouse_face_overwritten_p);
}
/* Update the header line after scrolling because a new header
line would otherwise overwrite lines at the top of the window
that can be scrolled. */
if (header_line_row && header_line_row->enabled_p)
{
header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
}
/* Fix the appearance of overlapping/overlapped rows. */
if (!paused_p && !w->pseudo_window_p)
{
#ifdef HAVE_WINDOW_SYSTEM
if (changed_p && rif->fix_overlapping_area)
{
redraw_overlapped_rows (w, yb);
redraw_overlapping_rows (w, yb);
}
#endif
/* Make cursor visible at cursor position of W. */
set_window_cursor_after_update (w);
#if 0 /* Check that current matrix invariants are satisfied. This is
for debugging only. See the comment of check_matrix_invariants. */
IF_DEBUG (check_matrix_invariants (w));
#endif
}
#ifdef GLYPH_DEBUG
/* Remember the redisplay method used to display the matrix. */
strcpy (w->current_matrix->method, w->desired_matrix->method);
#endif
#ifdef HAVE_WINDOW_SYSTEM
update_window_fringes (w, 0);
/* End the update of window W. Don't set the cursor if we
paused updating the display because in this case,
set_window_cursor_after_update hasn't been called, and
W->output_cursor doesn't contain the cursor location. */
gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
#endif
/* If the update wasn't interrupted, this window has been
completely updated. */
if (!paused_p)
w->must_be_updated_p = false;
/* Take note of the tab line, if there is one. We will
update it below, after updating all of the window's lines. */
if (row->mode_line_p && row->tab_line_p)
{
tab_line_row = row;
++row;
}
else
paused_p = 1;
tab_line_row = NULL;
/* Take note of the header line, if there is one. We will
update it below, after updating all of the window's lines. */
if (row->mode_line_p)
{
header_line_row = row;
++row;
}
else
header_line_row = NULL;
/* Update the mode line, if necessary. */
mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
{
mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
desired_matrix),
&mouse_face_overwritten_p);
}
/* Find first enabled row. Optimizations in redisplay_internal
may lead to an update with only one row enabled. There may
be also completely empty matrices. */
while (row < end && !row->enabled_p)
++row;
/* Try reusing part of the display by copying. */
if (row < end && !desired_matrix->no_scrolling_p)
{
int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
+ (header_line_row != NULL ? 1 : 0));
if (rc < 0)
{
/* All rows were found to be equal. */
goto set_cursor;
}
else if (rc > 0)
{
/* We've scrolled the display. */
changed_p = 1;
}
}
/* Update the rest of the lines. */
for (; row < end; ++row)
/* scrolling_window resets the enabled_p flag of the rows it
reuses from current_matrix. */
if (row->enabled_p)
{
int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
int i;
changed_p |= update_window_line (w, vpos,
&mouse_face_overwritten_p);
/* Mark all rows below the last visible one in the current
matrix as invalid. This is necessary because of
variable line heights. Consider the case of three
successive redisplays, where the first displays 5
lines, the second 3 lines, and the third 5 lines again.
If the second redisplay wouldn't mark rows in the
current matrix invalid, the third redisplay might be
tempted to optimize redisplay based on lines displayed
in the first redisplay. */
if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
{
for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
invisible_rows_marked = true;
}
}
/* If the window doesn't display its mode line, make sure the
corresponding row of the current glyph matrix is disabled, so
that if and when the mode line is displayed again, it will be
cleared and completely redrawn. */
if (!window_wants_mode_line (w))
SET_MATRIX_ROW_ENABLED_P (w->current_matrix,
w->current_matrix->nrows - 1, false);
if (!invisible_rows_marked)
{
/* If we didn't mark the invisible rows in the current
matrix as invalid above, do that now. This can happen if
scrolling_window updates the last visible rows of the
current matrix, in which case the above loop doesn't get
to examine the last visible row. */
int i;
for (i = 0; i < w->current_matrix->nrows - 1; ++i)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i);
if (current_row->enabled_p
&& MATRIX_ROW_BOTTOM_Y (current_row) >= yb)
{
for (++i ; i < w->current_matrix->nrows - 1; ++i)
SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
}
}
}
set_cursor:
/* Update the tab line after scrolling because a new tab
line would otherwise overwrite lines at the top of the window
that can be scrolled. */
if (tab_line_row && tab_line_row->enabled_p)
{
tab_line_row->y = 0;
update_window_line (w, 0, &mouse_face_overwritten_p);
}
/* Update the header line after scrolling because a new header
line would otherwise overwrite lines at the top of the window
that can be scrolled. */
if (header_line_row && header_line_row->enabled_p)
{
header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
}
/* Fix the appearance of overlapping/overlapped rows. */
if (!w->pseudo_window_p)
{
#ifdef HAVE_WINDOW_SYSTEM
if (changed_p && rif->fix_overlapping_area)
{
redraw_overlapped_rows (w, yb);
redraw_overlapping_rows (w, yb);
}
#endif
/* Make cursor visible at cursor position of W. */
set_window_cursor_after_update (w);
#if 0 /* Check that current matrix invariants are satisfied. This is
for debugging only. See the comment of check_matrix_invariants. */
IF_DEBUG (check_matrix_invariants (w));
#endif
}
#ifdef GLYPH_DEBUG
/* Remember the redisplay method used to display the matrix. */
strcpy (w->current_matrix->method, w->desired_matrix->method);
#endif
#ifdef HAVE_WINDOW_SYSTEM
update_window_fringes (w, 0);
/* End the update of window W. Don't set the cursor if we
paused updating the display because in this case,
set_window_cursor_after_update hasn't been called, and
W->output_cursor doesn't contain the cursor location. */
gui_update_window_end (w, true, mouse_face_overwritten_p);
#endif
/* If the update wasn't interrupted, this window has been
completely updated. */
w->must_be_updated_p = false;
#ifdef GLYPH_DEBUG
/* check_current_matrix_flags (w); */
add_window_display_history (w, w->current_matrix->method, paused_p);
add_window_display_history (w, w->current_matrix->method);
#endif
xwidget_end_redisplay (w, w->current_matrix);
clear_glyph_matrix (desired_matrix);
return paused_p;
}
#ifdef HAVE_WINDOW_SYSTEM
@ -5697,20 +5619,13 @@ tty_set_cursor (void)
}
/* Write desired matix of tty frame F and make it current.
FORCE_P means that the update should not be stopped by pending input.
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.
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
write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
static void
write_matrix (struct frame *f, bool inhibit_id_p,
bool set_cursor_p, bool updating_menu_p)
{
if (!force_p && detect_input_pending_ignore_squeezables ())
return true;
/* If we cannot insert/delete lines, it's no use trying it. */
if (!FRAME_LINE_INS_DEL_OK (f))
inhibit_id_p = true;
@ -5722,7 +5637,7 @@ write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
i/d line if just want cursor motion. */
int first_row = first_enabled_row (f->desired_matrix);
if (!inhibit_id_p && first_row >= 0)
force_p |= scrolling (f);
scrolling (f);
/* Update the individual lines as needed. Do bottom line first. This
is done so that messages are made visible when pausing. */
@ -5730,36 +5645,19 @@ write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row))
write_row (f, last_row, updating_menu_p);
bool pause_p = false;
if (first_row >= 0)
{
const int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
for (int i = first_row, n = 0; i < last_row; ++i)
if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
{
if (!force_p && n % preempt_count == 0
&& detect_input_pending_ignore_squeezables ())
{
pause_p = true;
break;
}
write_row (f, i, updating_menu_p);
++n;
}
}
for (int i = first_row; i < last_row; ++i)
if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
write_row (f, i, updating_menu_p);
/* Now just clean up termcap drivers and set cursor, etc. */
if (!pause_p && set_cursor_p)
if (set_cursor_p)
tty_set_cursor ();
return pause_p;
}
/* Do line insertions/deletions on frame F for frame-based redisplay. */
static bool
static void
scrolling (struct frame *frame)
{
/* In fact this code should never be reached at all under
@ -5796,7 +5694,7 @@ scrolling (struct frame *frame)
if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
{
SAFE_FREE ();
return false;
return;
}
old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i));
if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
@ -5827,7 +5725,7 @@ scrolling (struct frame *frame)
|| unchanged_at_bottom == height)
{
SAFE_FREE ();
return true;
return;
}
window_size = (height - unchanged_at_top
@ -5857,7 +5755,6 @@ scrolling (struct frame *frame)
SAFE_FREE ();
#endif
return false;
}
@ -6989,27 +6886,18 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
doc: /* Perform redisplay.
Optional arg FORCE, if non-nil, prevents redisplay from being
preempted by arriving input, even if `redisplay-dont-pause' is nil.
If `redisplay-dont-pause' is non-nil (the default), redisplay is never
preempted by arriving input, so FORCE does nothing.
Return t if redisplay was performed, nil if redisplay was preempted
immediately by pending input. */)
doc : /* Perform redisplay.
Optional arg FORCE exists for historical reasons and is ignored.
Value is t if redisplay has been performed, nil if executing a
keyboard macro. */)
(Lisp_Object force)
{
swallow_events (true);
if ((detect_input_pending_run_timers (1)
&& NILP (force) && !redisplay_dont_pause)
|| !NILP (Vexecuting_kbd_macro))
if (!NILP (Vexecuting_kbd_macro))
return Qnil;
specpdl_ref count = SPECPDL_INDEX ();
if (!NILP (force) && !redisplay_dont_pause)
specbind (Qredisplay_dont_pause, Qt);
redisplay_preserve_echo_area (2);
return unbind_to (count, Qt);
return Qt;
}
@ -7462,8 +7350,6 @@ syms_of_display (void)
/* This is the "purpose" slot of a display table. */
DEFSYM (Qdisplay_table, "display-table");
DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp");
DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor");
DEFVAR_INT ("baud-rate", baud_rate,
@ -7545,17 +7431,6 @@ It is also used for standard output and error streams.
See `buffer-display-table' for more information. */);
Vstandard_display_table = Qnil;
DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
doc: /* Nil means display update is paused when input is detected. */);
/* Contrary to expectations, a value of "false" can be detrimental to
responsiveness since aborting a redisplay throws away some of the
work already performed. It's usually more efficient (and gives
more prompt feedback to the user) to let the redisplay terminate,
and just completely skip the next command's redisplay (which is
done regardless of this setting if there's pending input at the
beginning of the next redisplay). */
redisplay_dont_pause = true;
DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout,
doc: /* The default timeout (in seconds) for `x-show-tip'. */);
Vx_show_tooltip_timeout = make_fixnum (5);

View file

@ -2663,8 +2663,7 @@ read_char (int commandflag, Lisp_Object map,
swallow_events (false); /* May clear input_pending. */
/* Redisplay if no pending input. */
while (!(input_pending
&& (input_was_pending || !redisplay_dont_pause)))
while (!(input_pending && input_was_pending))
{
input_was_pending = input_pending;
if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window))

View file

@ -914,9 +914,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
XWINDOW (minibuf_window)->cursor.x = 0;
XWINDOW (minibuf_window)->must_be_updated_p = true;
struct frame *sf = XFRAME (selected_frame);
update_frame (sf, true, true);
update_frame (sf, true);
if (is_tty_frame (sf))
combine_updates_for_frame (sf, true, true);
combine_updates_for_frame (sf, true);
#ifndef HAVE_NTGUI
flush_frame (XFRAME (XWINDOW (minibuf_window)->frame));

View file

@ -1116,7 +1116,6 @@ static void set_iterator_to_next (struct it *, bool);
static void mark_window_display_accurate_1 (struct window *, bool);
static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
static bool cursor_row_p (struct glyph_row *);
static int redisplay_mode_lines (Lisp_Object, bool);
static void handle_line_prefix (struct it *);
@ -13511,24 +13510,6 @@ echo_area_display (bool update_frame_p)
here could cause confusion. */
if (update_frame_p && !redisplaying_p)
{
int n = 0;
/* If the display update has been interrupted by pending
input, update mode lines in the frame. Due to the
pending input, it might have been that redisplay hasn't
been called, so that mode lines above the echo area are
garbaged. This looks odd, so we prevent it here. */
if (!display_completed)
{
n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f)
&& FRAME_RIF (f)->clear_under_internal_border)
FRAME_RIF (f)->clear_under_internal_border (f);
#endif
}
if (window_height_changed_p
/* Don't do this if Emacs is shutting down. Redisplay
needs to run hooks. */
@ -13537,13 +13518,10 @@ echo_area_display (bool update_frame_p)
/* Must update other windows. Likewise as in other
cases, don't let this update be interrupted by
pending input. */
specpdl_ref count = SPECPDL_INDEX ();
specbind (Qredisplay_dont_pause, Qt);
fset_redisplay (f);
redisplay_internal ();
unbind_to (count, Qnil);
}
else if (FRAME_WINDOW_P (f) && n == 0)
else if (FRAME_WINDOW_P (f))
{
/* Window configuration is the same as before.
Can do with a display update of the echo area,
@ -13553,9 +13531,9 @@ echo_area_display (bool update_frame_p)
}
else
{
update_frame (f, true, true);
update_frame (f, true);
if (is_tty_frame (f))
combine_updates_for_frame (f, true, true);
combine_updates_for_frame (f, true);
}
/* If cursor is in the echo area, make sure that the next
@ -16938,7 +16916,6 @@ redisplay_internal (void)
struct window *w = XWINDOW (selected_window);
struct window *sw;
struct frame *fr;
bool pending;
bool must_finish = false, match_p;
struct text_pos tlbufpos, tlendpos;
int number_of_visible_frames;
@ -17024,7 +17001,6 @@ redisplay_internal (void)
/* Remember the currently selected window. */
sw = w;
pending = false;
forget_escape_and_glyphless_faces ();
inhibit_free_realized_faces = false;
@ -17590,7 +17566,7 @@ redisplay_internal (void)
unrequest_sigio ();
STOP_POLLING;
pending |= update_frame (f, false, false);
update_frame (f, false);
/* On some platforms (at least MS-Windows), the
scroll_run_hook called from scrolling_window
called from update_frame could set the frame's
@ -17612,27 +17588,24 @@ redisplay_internal (void)
}
if (CONSP (tty_root_frames))
pending |= combine_updates (tty_root_frames, false, false);
combine_updates (tty_root_frames, false);
eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
if (!pending)
/* Do the mark_window_display_accurate after all windows have
been redisplayed because this call resets flags in buffers
which are needed for proper redisplay. */
FOR_EACH_FRAME (tail, frame)
{
/* Do the mark_window_display_accurate after all windows have
been redisplayed because this call resets flags in buffers
which are needed for proper redisplay. */
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
if (f->updated_p)
{
f->redisplay = false;
f->garbaged = false;
mark_window_display_accurate (f->root_window, true);
if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
}
}
struct frame *f = XFRAME (frame);
if (f->updated_p)
{
f->redisplay = false;
f->garbaged = false;
mark_window_display_accurate (f->root_window, true);
if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
}
}
}
else if (FRAME_REDISPLAY_P (sf))
@ -17696,10 +17669,10 @@ redisplay_internal (void)
}
XWINDOW (selected_window)->must_be_updated_p = true;
pending = update_frame (sf, false, false);
update_frame (sf, false);
if (is_tty_frame (sf))
pending |= combine_updates_for_frame (sf, false, false);
combine_updates_for_frame (sf, false);
sf->cursor_type_changed = false;
sf->inhibit_clear_image_cache = false;
@ -17716,11 +17689,11 @@ redisplay_internal (void)
if (mini_frame != sf)
{
XWINDOW (mini_window)->must_be_updated_p = true;
pending |= update_frame (mini_frame, false, false);
update_frame (mini_frame, false);
if (is_tty_frame (mini_frame))
pending |= combine_updates_for_frame (mini_frame, false, false);
combine_updates_for_frame (mini_frame, false);
mini_frame->cursor_type_changed = false;
if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
if (hscroll_retries <= MAX_HSCROLL_RETRIES
&& hscroll_windows (mini_window))
{
hscroll_retries++;
@ -17729,47 +17702,26 @@ redisplay_internal (void)
}
}
/* If display was paused because of pending input, make sure we do a
thorough update the next time. */
if (pending)
if (!consider_all_windows_p)
{
/* Prevent the optimization at the beginning of
redisplay_internal that tries a single-line update of the
line containing the cursor in the selected window. */
CHARPOS (this_line_start_pos) = 0;
/* This has already been done above if
consider_all_windows_p is set. */
if (XBUFFER (w->contents)->text->redisplay
&& buffer_window_count (XBUFFER (w->contents)) > 1)
/* This can happen if b->text->redisplay was set during
jit-lock. */
propagate_buffer_redisplay ();
mark_window_display_accurate_1 (w, true);
/* Let the overlay arrow be updated the next time. */
update_overlay_arrows (0);
/* Say overlay arrows are up to date. */
update_overlay_arrows (1);
/* If we pause after scrolling, some rows in the current
matrices of some windows are not valid. */
if (!WINDOW_FULL_WIDTH_P (w)
&& !FRAME_WINDOW_P (XFRAME (w->frame)))
update_mode_lines = 36;
if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
}
else
{
if (!consider_all_windows_p)
{
/* This has already been done above if
consider_all_windows_p is set. */
if (XBUFFER (w->contents)->text->redisplay
&& buffer_window_count (XBUFFER (w->contents)) > 1)
/* This can happen if b->text->redisplay was set during
jit-lock. */
propagate_buffer_redisplay ();
mark_window_display_accurate_1 (w, true);
/* Say overlay arrows are up to date. */
update_overlay_arrows (1);
if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
}
update_mode_lines = 0;
windows_or_buffers_changed = 0;
}
update_mode_lines = 0;
windows_or_buffers_changed = 0;
/* Start SIGIO interrupts coming again. Having them off during the
code above makes it less likely one will discard output, but not
@ -17785,26 +17737,23 @@ redisplay_internal (void)
redisplay constructing glyphs, so simply exposing a frame won't
display anything in this case. So, we have to display these
frames here explicitly. */
if (!pending)
int new_count = 0;
FOR_EACH_FRAME (tail, frame)
{
int new_count = 0;
FOR_EACH_FRAME (tail, frame)
{
if (FRAME_REDISPLAY_P (XFRAME (frame)))
new_count++;
}
if (new_count != number_of_visible_frames)
windows_or_buffers_changed = 52;
if (FRAME_REDISPLAY_P (XFRAME (frame)))
new_count++;
}
if (new_count != number_of_visible_frames)
windows_or_buffers_changed = 52;
/* Change frame size now if a change is pending. */
do_pending_window_change (true);
/* If we just did a pending size change, or have additional
visible frames, or selected_window changed, redisplay again. */
if ((windows_or_buffers_changed && !pending)
if (windows_or_buffers_changed
|| (WINDOWP (selected_window)
&& (w = XWINDOW (selected_window)) != sw))
goto retry;
@ -27394,60 +27343,6 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
Mode Line
***********************************************************************/
/* Redisplay mode lines in the window tree whose root is WINDOW.
If FORCE, redisplay mode lines unconditionally.
Otherwise, redisplay only mode lines that are garbaged. Value is
the number of windows whose mode lines were redisplayed. */
static int
redisplay_mode_lines (Lisp_Object window, bool force)
{
int nwindows = 0;
while (!NILP (window))
{
struct window *w = XWINDOW (window);
if (WINDOWP (w->contents))
nwindows += redisplay_mode_lines (w->contents, force);
else if (force
|| FRAME_GARBAGED_P (XFRAME (w->frame))
|| !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
{
struct text_pos lpoint;
struct buffer *old = current_buffer;
/* Set the window's buffer for the mode line display. */
SET_TEXT_POS (lpoint, PT, PT_BYTE);
set_buffer_internal_1 (XBUFFER (w->contents));
/* Point refers normally to the selected window. For any
other window, set up appropriate value. */
if (!EQ (window, selected_window))
{
struct text_pos pt;
CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
}
/* Display mode lines. */
clear_glyph_matrix (w->desired_matrix);
if (display_mode_lines (w))
++nwindows;
/* Restore old settings. */
set_buffer_internal_1 (old);
TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
}
window = w->next;
}
return nwindows;
}
/* Display the mode line, the header line, and the tab-line of window
W. Value is the sum number of mode lines, header lines, and tab
lines actually displayed. */