summaryrefslogtreecommitdiff
path: root/src/xdisp.c
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2013-11-28 17:43:09 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2013-11-28 17:43:09 -0500
commit655ab9a380068143cfb9a31d01488e83676d81c1 (patch)
treec703f4b96ca26edb6200cd08d6415fb6ece04560 /src/xdisp.c
parent698c0f24f170025470f3dcda51c11290062d78c4 (diff)
Refine redisplay optimizations to only redisplay *some* frames/windows
rather than all of them. * src/xdisp.c (REDISPLAY_SOME): New constant. (redisplay_other_windows, wset_redisplay, fset_redisplay) (bset_redisplay, bset_update_mode_line): New functions. (message_dolog): Use bset_redisplay. (clear_garbaged_frames): Use fset_redisplay. (echo_area_display): Use wset_redisplay. (buffer_shared_and_changed): Remove. (prepare_menu_bars): Call Vpre_redisplay_function before updating frame titles. Compute the actual set of windows redisplayed. Don't update frame titles and menu bars for frames that don't need to be redisplayed. (propagate_buffer_redisplay): New function. (AINC): New macro. (redisplay_internal): Use it. Be more selective in the set of windows we redisplay. Propagate windows_or_buffers_changed to update_mode_lines a bit later to simplify the code. (mark_window_display_accurate_1): Reset window and buffer's `redisplay' flag. (redisplay_window): Do nothing if neither the window nor the buffer nor the frame needs redisplay. * src/window.h (struct window): Add `redisplay' field. (wset_redisplay, fset_redisplay, bset_redisplay, bset_update_mode_line) (redisplay_other_windows, window_list): New declarations. * src/window.c (select_window, Fset_window_start): Use wset_redisplay. (window_list): Not static any more. (grow_mini_window, shrink_mini_window): Use fset_redisplay. * src/minibuf.c (read_minibuf_unwind): Don't redisplay everything. * src/insdel.c (prepare_to_modify_buffer_1): Use bset_redisplay. * src/frame.c (Fmake_frame_visible): Don't redisplay everything. * src/frame.h (struct frame): Add `redisplay' field. Move `external_menu_bar' bitfield next to other bit-fields. (SET_FRAME_GARBAGED): Use fset_redisplay. (SET_FRAME_VISIBLE): Don't garbage the frame; Use redisplay_other_windows. * src/buffer.h (struct buffer): Add `redisplay' field. * src/buffer.c (Fforce_mode_line_update): Pay attention to the `all' flag. (modify_overlay): Use bset_redisplay. * src/alloc.c (gc_sweep): Don't unmark strings while sweeping symbols. * lisp/doc-view.el (doc-view-goto-page): Update mode-line.
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c318
1 files changed, 201 insertions, 117 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 47855a1de3..319481573c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -502,12 +502,20 @@ static Lisp_Object Vmessage_stack;
static bool message_enable_multibyte;
-/* Nonzero if we should redraw the mode lines on the next redisplay. */
+/* Nonzero if we should redraw the mode lines on the next redisplay.
+ If it has value REDISPLAY_SOME, then only redisplay the mode lines where
+ the `redisplay' bit has been set. Otherwise, redisplay all mode lines
+ (the number used is then only used to track down the cause for this
+ full-redisplay). */
int update_mode_lines;
-/* Nonzero if window sizes or contents have changed since last
- redisplay that finished. */
+/* Nonzero if window sizes or contents other than selected-window have changed
+ since last redisplay that finished.
+ If it has value REDISPLAY_SOME, then only redisplay the windows where
+ the `redisplay' bit has been set. Otherwise, redisplay all windows
+ (the number used is then only used to track down the cause for this
+ full-redisplay). */
int windows_or_buffers_changed;
@@ -599,6 +607,49 @@ bool help_echo_showing_p;
CACHE = NULL; \
} while (0)
+/* Functions to mark elements as needing redisplay. */
+enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
+
+void redisplay_other_windows (void)
+{
+ if (!windows_or_buffers_changed)
+ windows_or_buffers_changed = REDISPLAY_SOME;
+}
+
+void wset_redisplay (struct window *w)
+{
+ redisplay_other_windows ();
+ w->redisplay = true;
+}
+
+void fset_redisplay (struct frame *f)
+{
+ redisplay_other_windows ();
+ f->redisplay = true;
+}
+
+void bset_redisplay (struct buffer *b)
+{
+ int count = buffer_window_count (b);
+ if (count > 0)
+ {
+ /* ... it's visible in other window than selected, */
+ if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
+ redisplay_other_windows ();
+ /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
+ so that if we later set windows_or_buffers_changed, this buffer will
+ not be omitted. */
+ b->text->redisplay = true;
+ }
+}
+
+extern void bset_update_mode_line (struct buffer *b)
+{
+ if (!update_mode_lines)
+ update_mode_lines = REDISPLAY_SOME;
+ b->text->redisplay = true;
+}
+
#ifdef GLYPH_DEBUG
/* Non-zero means print traces of redisplay if compiled with
@@ -9468,7 +9519,6 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
ptrdiff_t point_at_end = 0;
ptrdiff_t zv_at_end = 0;
Lisp_Object old_deactivate_mark;
- bool shown;
struct gcpro gcpro1;
old_deactivate_mark = Vdeactivate_mark;
@@ -9482,8 +9532,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
- if (newbuffer &&
- !NILP (Ffboundp (intern ("messages-buffer-mode"))))
+ if (newbuffer
+ && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
call0 (intern ("messages-buffer-mode"));
}
@@ -9625,18 +9675,17 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
unchain_marker (XMARKER (oldbegv));
unchain_marker (XMARKER (oldzv));
- shown = buffer_window_count (current_buffer) > 0;
- set_buffer_internal (oldbuf);
/* We called insert_1_both above with its 5th argument (PREPARE)
zero, which prevents insert_1_both from calling
prepare_to_modify_buffer, which in turns prevents us from
incrementing windows_or_buffers_changed even if *Messages* is
- shown in some window. So we must manually incrementing
+ shown in some window. So we must manually set
windows_or_buffers_changed here to make up for that. */
- if (shown)
- windows_or_buffers_changed = 41;
- else
windows_or_buffers_changed = old_windows_or_buffers_changed;
+ bset_redisplay (current_buffer);
+
+ set_buffer_internal (oldbuf);
+
message_log_need_newline = !nlflag;
Vdeactivate_mark = old_deactivate_mark;
}
@@ -10325,15 +10374,8 @@ resize_echo_area_exactly (void)
&& WINDOWP (echo_area_window))
{
struct window *w = XWINDOW (echo_area_window);
- int resized_p;
- Lisp_Object resize_exactly;
-
- if (minibuf_level == 0)
- resize_exactly = Qt;
- else
- resize_exactly = Qnil;
-
- resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
+ Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
+ int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
(intptr_t) w, resize_exactly);
if (resized_p)
{
@@ -10714,7 +10756,6 @@ clear_garbaged_frames (void)
if (frame_garbaged)
{
Lisp_Object tail, frame;
- int changed_count = 0;
FOR_EACH_FRAME (tail, frame)
{
@@ -10726,15 +10767,13 @@ clear_garbaged_frames (void)
redraw_frame (f);
else
clear_current_matrices (f);
- changed_count++;
- f->garbaged = 0;
- f->resized_p = 0;
+ fset_redisplay (f);
+ f->garbaged = false;
+ f->resized_p = false;
}
}
- frame_garbaged = 0;
- if (changed_count)
- windows_or_buffers_changed = 43;
+ frame_garbaged = false;
}
}
@@ -10822,11 +10861,11 @@ echo_area_display (int update_frame_p)
redisplay displays the minibuffer, so that the cursor will
be replaced with what the minibuffer wants. */
if (cursor_in_echo_area)
- windows_or_buffers_changed = 45;
+ wset_redisplay (XWINDOW (mini_window));
}
}
else if (!EQ (mini_window, selected_window))
- windows_or_buffers_changed = 46;
+ wset_redisplay (XWINDOW (mini_window));
/* Last displayed message is now the current message. */
echo_area_buffer[1] = echo_area_buffer[0];
@@ -10842,16 +10881,6 @@ echo_area_display (int update_frame_p)
return window_height_changed_p;
}
-/* Nonzero if the current window's buffer is shown in more than one
- window and was modified since last redisplay. */
-
-static int
-buffer_shared_and_changed (void)
-{
- return (buffer_window_count (current_buffer) > 1
- && UNCHANGED_MODIFIED < MODIFF);
-}
-
/* Nonzero if W's buffer was changed but not saved. */
static int
@@ -11171,9 +11200,13 @@ x_consider_frame_title (Lisp_Object frame)
static void
prepare_menu_bars (void)
{
- int all_windows;
+ bool all_windows = windows_or_buffers_changed || update_mode_lines;
+ bool some_windows
+ = (windows_or_buffers_changed == 0
+ || windows_or_buffers_changed == REDISPLAY_SOME)
+ && (update_mode_lines == 0
+ || update_mode_lines == REDISPLAY_SOME);
struct gcpro gcpro1, gcpro2;
- struct frame *f;
Lisp_Object tooltip_frame;
#ifdef HAVE_WINDOW_SYSTEM
@@ -11182,17 +11215,45 @@ prepare_menu_bars (void)
tooltip_frame = Qnil;
#endif
+ if (FUNCTIONP (Vpre_redisplay_function))
+ {
+ Lisp_Object windows = all_windows ? Qt : Qnil;
+ if (all_windows && some_windows)
+ {
+ Lisp_Object ws = window_list ();
+ for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
+ {
+ Lisp_Object this = XCAR (ws);
+ struct window *w = XWINDOW (this);
+ if (w->redisplay
+ || XFRAME (w->frame)->redisplay
+ || XBUFFER (w->contents)->text->redisplay)
+ {
+ windows = Fcons (this, windows);
+ }
+ }
+ }
+ safe_call1 (Vpre_redisplay_function, windows);
+ }
+
/* Update all frame titles based on their buffer names, etc. We do
this before the menu bars so that the buffer-menu will show the
up-to-date frame titles. */
#ifdef HAVE_WINDOW_SYSTEM
- if (windows_or_buffers_changed || update_mode_lines)
+ if (all_windows)
{
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
{
- f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
+ struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+ if (some_windows
+ && !f->redisplay
+ && !w->redisplay
+ && !XBUFFER (w->contents)->text->redisplay)
+ continue;
+
if (!EQ (frame, tooltip_frame)
&& (FRAME_ICONIFIED_P (f)
|| FRAME_VISIBLE_P (f) == 1
@@ -11213,12 +11274,6 @@ prepare_menu_bars (void)
/* Update the menu bar item lists, if appropriate. This has to be
done before any actual redisplay or generation of display lines. */
- all_windows = (update_mode_lines
- || buffer_shared_and_changed ()
- || windows_or_buffers_changed);
-
- if (FUNCTIONP (Vpre_redisplay_function))
- safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
if (all_windows)
{
@@ -11232,12 +11287,19 @@ prepare_menu_bars (void)
FOR_EACH_FRAME (tail, frame)
{
- f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
+ struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
/* Ignore tooltip frame. */
if (EQ (frame, tooltip_frame))
continue;
+ if (some_windows
+ && !f->redisplay
+ && !w->redisplay
+ && !XBUFFER (w->contents)->text->redisplay)
+ continue;
+
/* If a window on this frame changed size, report that to
the user and clear the size-change flag. */
if (FRAME_WINDOW_SIZES_CHANGED (f))
@@ -12860,6 +12922,27 @@ reconsider_clip_changes (struct window *w)
}
}
+void propagate_buffer_redisplay (void)
+{ /* Resetting b->text->redisplay is problematic!
+ We can't just reset it in the case that some window that displays
+ it has not been redisplayed; and such a window can stay
+ unredisplayed for a long time if it's currently invisible.
+ But we do want to reset it at the end of redisplay otherwise
+ its displayed windows will keep being redisplayed over and over
+ again.
+ So we copy all b->text->redisplay flags up to their windows here,
+ such that mark_window_display_accurate can safely reset
+ b->text->redisplay. */
+ Lisp_Object ws = window_list ();
+ for (; CONSP (ws); ws = XCDR (ws))
+ {
+ struct window *thisw = XWINDOW (XCAR (ws));
+ struct buffer *thisb = XBUFFER (thisw->contents);
+ if (thisb->text->redisplay)
+ thisw->redisplay = true;
+ }
+}
+
#define STOP_POLLING \
do { if (! polling_stopped_here) stop_polling (); \
polling_stopped_here = 1; } while (0)
@@ -12956,7 +13039,6 @@ redisplay_internal (void)
/* Since frames on a single ASCII terminal share the same
display area, displaying a different frame means redisplay
the whole thing. */
- windows_or_buffers_changed = 48;
SET_FRAME_GARBAGED (sf);
#ifndef DOS_NT
set_tty_color_mode (FRAME_TTY (sf), sf);
@@ -13005,9 +13087,6 @@ redisplay_internal (void)
if (NILP (Vmemory_full))
prepare_menu_bars ();
- if (windows_or_buffers_changed && !update_mode_lines)
- update_mode_lines = 32;
-
reconsider_clip_changes (w);
/* In most cases selected window displays current buffer. */
@@ -13016,27 +13095,12 @@ redisplay_internal (void)
{
/* Detect case that we need to write or remove a star in the mode line. */
if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
- {
w->update_mode_line = 1;
- if (buffer_shared_and_changed ())
- update_mode_lines = 33;
- }
if (mode_line_update_needed (w))
w->update_mode_line = 1;
}
- consider_all_windows_p = (update_mode_lines
- || buffer_shared_and_changed ());
-
- /* If specs for an arrow have changed, do thorough redisplay
- to ensure we remove any arrow that should no longer exist. */
- if (overlay_arrows_changed_p ())
- {
- consider_all_windows_p = true;
- windows_or_buffers_changed = 49;
- }
-
/* Normally the message* functions will have already displayed and
updated the echo area, but the frame may have been trashed, or
the update may have been preempted, so display the echo area
@@ -13066,8 +13130,6 @@ redisplay_internal (void)
if (window_height_changed_p)
{
- consider_all_windows_p = true;
- update_mode_lines = 34;
windows_or_buffers_changed = 50;
/* If window configuration was changed, frames may have been
@@ -13083,13 +13145,6 @@ redisplay_internal (void)
/* Resized active mini-window to fit the size of what it is
showing if its contents might have changed. */
must_finish = 1;
- /* FIXME: this causes all frames to be updated, which seems unnecessary
- since only the current frame needs to be considered. This function
- needs to be rewritten with two variables, consider_all_windows and
- consider_all_frames. */
- consider_all_windows_p = true;
- windows_or_buffers_changed = 51;
- update_mode_lines = 35;
/* If window configuration was changed, frames may have been
marked garbaged. Clear them or we will experience
@@ -13097,23 +13152,29 @@ redisplay_internal (void)
clear_garbaged_frames ();
}
- if (VECTORP (Vredisplay__all_windows_cause)
- && windows_or_buffers_changed >= 0
- && windows_or_buffers_changed < ASIZE (Vredisplay__all_windows_cause)
- && INTEGERP (AREF (Vredisplay__all_windows_cause,
- windows_or_buffers_changed)))
- ASET (Vredisplay__all_windows_cause, windows_or_buffers_changed,
- make_number (1 + XINT (AREF (Vredisplay__all_windows_cause,
- windows_or_buffers_changed))));
-
- if (VECTORP (Vredisplay__mode_lines_cause)
- && update_mode_lines >= 0
- && update_mode_lines < ASIZE (Vredisplay__mode_lines_cause)
- && INTEGERP (AREF (Vredisplay__mode_lines_cause,
- update_mode_lines)))
- ASET (Vredisplay__mode_lines_cause, update_mode_lines,
- make_number (1 + XINT (AREF (Vredisplay__mode_lines_cause,
- update_mode_lines))));
+ if (windows_or_buffers_changed && !update_mode_lines)
+ /* Code that sets windows_or_buffers_changed doesn't distinguish whether
+ only the windows's contents needs to be refreshed, or whether the
+ mode-lines also need a refresh. */
+ update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
+ ? REDISPLAY_SOME : 32);
+
+ /* If specs for an arrow have changed, do thorough redisplay
+ to ensure we remove any arrow that should no longer exist. */
+ if (overlay_arrows_changed_p ())
+ /* Apparently, this is the only case where we update other windows,
+ without updating other mode-lines. */
+ windows_or_buffers_changed = 49;
+
+ consider_all_windows_p = (update_mode_lines
+ || windows_or_buffers_changed);
+
+#define AINC(a,i) \
+ if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
+ ASET (a, i, make_number (1 + XINT (AREF (a, i))))
+
+ AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
+ AINC (Vredisplay__mode_lines_cause, update_mode_lines);
/* Optimize the case that only the line containing the cursor in the
selected window has changed. Variables starting with this_ are
@@ -13330,6 +13391,8 @@ redisplay_internal (void)
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->updated_p = 0;
+ propagate_buffer_redisplay ();
+
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
@@ -13344,9 +13407,12 @@ redisplay_internal (void)
if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
+ bool gcscrollbars
+ /* Only GC scollbars when we redisplay the whole frame. */
+ = f->redisplay || windows_or_buffers_changed != REDISPLAY_SOME;
/* Mark all the scroll bars to be removed; we'll redeem
the ones we want when we redisplay their windows. */
- if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+ if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
@@ -13358,7 +13424,7 @@ redisplay_internal (void)
/* Any scroll bars which redisplay_windows should have
nuked should now go away. */
- if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+ if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
@@ -13413,6 +13479,7 @@ redisplay_internal (void)
struct frame *f = XFRAME (frame);
if (f->updated_p)
{
+ f->redisplay = false;
mark_window_display_accurate (f->root_window, 1);
if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
@@ -13502,6 +13569,11 @@ redisplay_internal (void)
{
/* 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, 1);
/* Say overlay arrows are up to date. */
@@ -13535,12 +13607,7 @@ redisplay_internal (void)
FOR_EACH_FRAME (tail, frame)
{
- int this_is_visible = 0;
-
if (XFRAME (frame)->visible)
- this_is_visible = 1;
-
- if (this_is_visible)
new_count++;
}
@@ -13639,8 +13706,13 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
if (accurate_p)
{
- b->clip_changed = 0;
- b->prevent_redisplay_optimizations_p = 0;
+ b->clip_changed = false;
+ b->prevent_redisplay_optimizations_p = false;
+ eassert (buffer_window_count (b) > 0);
+ /* Resetting b->text->redisplay is problematic!
+ In order to make it safer to do it here, redisplay_internal must
+ have copied all b->text->redisplay to their respective windows. */
+ b->text->redisplay = false;
BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
@@ -13659,9 +13731,11 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
else
w->last_point = marker_position (w->pointm);
- w->window_end_valid = 1;
- w->update_mode_line = 0;
+ w->window_end_valid = true;
+ w->update_mode_line = false;
}
+
+ w->redisplay = !accurate_p;
}
@@ -14314,9 +14388,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
occlude point. Only set w->cursor if we found a better
approximation to the cursor position than we have from previously
examined candidate rows belonging to the same continued line. */
- if (/* we already have a candidate row */
+ if (/* We already have a candidate row. */
w->cursor.vpos >= 0
- /* that candidate is not the row we are processing */
+ /* That candidate is not the row we are processing. */
&& MATRIX_ROW (matrix, w->cursor.vpos) != row
/* Make sure cursor.vpos specifies a row whose start and end
charpos occlude point, and it is valid candidate for being a
@@ -14327,30 +14401,30 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
&& pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
&& cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
{
- struct glyph *g1 =
- MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
+ struct glyph *g1
+ = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
/* Don't consider glyphs that are outside TEXT_AREA. */
if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
return 0;
/* Keep the candidate whose buffer position is the closest to
point or has the `cursor' property. */
- if (/* previous candidate is a glyph in TEXT_AREA of that row */
+ if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
w->cursor.hpos >= 0
&& w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
&& ((BUFFERP (g1->object)
- && (g1->charpos == pt_old /* an exact match always wins */
+ && (g1->charpos == pt_old /* An exact match always wins. */
|| (BUFFERP (glyph->object)
&& eabs (g1->charpos - pt_old)
< eabs (glyph->charpos - pt_old))))
- /* previous candidate is a glyph from a string that has
- a non-nil `cursor' property */
+ /* Previous candidate is a glyph from a string that has
+ a non-nil `cursor' property. */
|| (STRINGP (g1->object)
&& (!NILP (Fget_char_property (make_number (g1->charpos),
Qcursor, g1->object))
- /* previous candidate is from the same display
+ /* Previous candidate is from the same display
string as this one, and the display string
- came from a text property */
+ came from a text property. */
|| (EQ (g1->object, glyph->object)
&& string_from_text_prop)
/* this candidate is from newline and its
@@ -15329,6 +15403,16 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
*w->desired_matrix->method = 0;
#endif
+ if (!just_this_one_p
+ && (update_mode_lines == REDISPLAY_SOME
+ || update_mode_lines == 0)
+ && (windows_or_buffers_changed == REDISPLAY_SOME
+ || windows_or_buffers_changed == 0)
+ && !w->redisplay
+ && !f->redisplay
+ && !buffer->text->redisplay)
+ return;
+
/* Make sure that both W's markers are valid. */
eassert (XMARKER (w->start)->buffer == buffer);
eassert (XMARKER (w->pointm)->buffer == buffer);