aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2022-02-04 15:50:50 +0200
committerEli Zaretskii2022-02-04 15:50:50 +0200
commit9a8796f067d1f9d5d0c2c1285dc86b2f577f4f27 (patch)
tree0c1eb9d82581c1b12149101e70d359194c38b618 /src
parent38ffb828f26d630cf7e10b7e8554aea98e299f1b (diff)
downloademacs-9a8796f067d1f9d5d0c2c1285dc86b2f577f4f27.tar.gz
emacs-9a8796f067d1f9d5d0c2c1285dc86b2f577f4f27.zip
Fix infloop in redisplay_window due to fix of bug#14582
* src/xdisp.c (window_start_acceptable_p): New function. (redisplay_window): Call 'window_start_acceptable_p' to determine whether a given window-start point is acceptable, including when the window's force_start flag is set -- this fixes infloop in redisplay_window in that case.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 20b0d97b975..db9bc512a98 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -18739,6 +18739,34 @@ set_horizontal_scroll_bar (struct window *w)
18739 (w, portion, whole, start); 18739 (w, portion, whole, start);
18740} 18740}
18741 18741
18742/* Subroutine of redisplay_window, to determine whether a window-start
18743 point STARTP of WINDOW should be rejected. */
18744static bool
18745window_start_acceptable_p (Lisp_Object window, ptrdiff_t startp)
18746{
18747 if (!make_window_start_visible)
18748 return true;
18749
18750 struct window *w = XWINDOW (window);
18751 struct frame *f = XFRAME (w->frame);
18752 Lisp_Object startpos = make_fixnum (startp);
18753 Lisp_Object invprop, disp_spec;
18754 struct text_pos ignored;
18755
18756 /* Is STARTP in invisible text? */
18757 if (startp > BEGV
18758 && ((invprop = Fget_char_property (startpos, Qinvisible, window)),
18759 TEXT_PROP_MEANS_INVISIBLE (invprop) != 0))
18760 return false;
18761
18762 /* Is STARTP covered by a replacing 'display' property? */
18763 if (!NILP (disp_spec = Fget_char_property (startpos, Qdisplay, window))
18764 && handle_display_spec (NULL, disp_spec, Qnil, Qnil, &ignored, startp,
18765 FRAME_WINDOW_P (f)) > 0)
18766 return false;
18767
18768 return true;
18769}
18742 18770
18743/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only 18771/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
18744 selected_window is redisplayed. 18772 selected_window is redisplayed.
@@ -19036,9 +19064,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19036 force_start: 19064 force_start:
19037 19065
19038 /* Handle case where place to start displaying has been specified, 19066 /* Handle case where place to start displaying has been specified,
19039 unless the specified location is outside the accessible range, or 19067 unless the specified location is outside the accessible range. */
19040 the buffer wants the window-start point to be always visible. */ 19068 if (w->force_start)
19041 if (w->force_start && !make_window_start_visible)
19042 { 19069 {
19043 /* We set this later on if we have to adjust point. */ 19070 /* We set this later on if we have to adjust point. */
19044 int new_vpos = -1; 19071 int new_vpos = -1;
@@ -19071,6 +19098,11 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19071 else if (CHARPOS (startp) > ZV) 19098 else if (CHARPOS (startp) > ZV)
19072 SET_TEXT_POS (startp, ZV, ZV_BYTE); 19099 SET_TEXT_POS (startp, ZV, ZV_BYTE);
19073 19100
19101 /* Reject the specified start location if it is invisible, and
19102 the buffer wants it always visible. */
19103 if (!window_start_acceptable_p (window, CHARPOS (startp)))
19104 goto ignore_start;
19105
19074 /* Redisplay, then check if cursor has been set during the 19106 /* Redisplay, then check if cursor has been set during the
19075 redisplay. Give up if new fonts were loaded. */ 19107 redisplay. Give up if new fonts were loaded. */
19076 /* We used to issue a CHECK_MARGINS argument to try_window here, 19108 /* We used to issue a CHECK_MARGINS argument to try_window here,
@@ -19228,8 +19260,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19228 goto done; 19260 goto done;
19229 } 19261 }
19230 19262
19231 Lisp_Object iprop, dspec; 19263 ignore_start:
19232 struct text_pos ignored; 19264
19233 /* Handle case where text has not changed, only point, and it has 19265 /* Handle case where text has not changed, only point, and it has
19234 not moved off the frame, and we are not retrying after hscroll. 19266 not moved off the frame, and we are not retrying after hscroll.
19235 (current_matrix_up_to_date_p is true when retrying.) */ 19267 (current_matrix_up_to_date_p is true when retrying.) */
@@ -19253,26 +19285,10 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19253 /* If current starting point was originally the beginning of a line 19285 /* If current starting point was originally the beginning of a line
19254 but no longer is, or if the starting point is invisible but the 19286 but no longer is, or if the starting point is invisible but the
19255 buffer wants it always visible, find a new starting point. */ 19287 buffer wants it always visible, find a new starting point. */
19256 else if (w->start_at_line_beg 19288 else if ((w->start_at_line_beg
19257 && (!(CHARPOS (startp) <= BEGV 19289 && !(CHARPOS (startp) <= BEGV
19258 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n') 19290 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
19259 || (make_window_start_visible 19291 || !window_start_acceptable_p (window, CHARPOS (startp)))
19260 /* Is window-start in invisible text? */
19261 && ((CHARPOS (startp) > BEGV
19262 && ((iprop =
19263 Fget_char_property
19264 (make_fixnum (CHARPOS (startp) - 1), Qinvisible,
19265 window)),
19266 TEXT_PROP_MEANS_INVISIBLE (iprop) != 0))
19267 /* Is window-start covered by a replacing
19268 'display' property? */
19269 || (!NILP (dspec =
19270 Fget_char_property
19271 (make_fixnum (CHARPOS (startp)), Qdisplay,
19272 window))
19273 && handle_display_spec (NULL, dspec, Qnil, Qnil,
19274 &ignored, CHARPOS (startp),
19275 FRAME_WINDOW_P (f)) > 0)))))
19276 { 19292 {
19277#ifdef GLYPH_DEBUG 19293#ifdef GLYPH_DEBUG
19278 debug_method_add (w, "recenter 1"); 19294 debug_method_add (w, "recenter 1");
@@ -19348,14 +19364,10 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19348 goto force_start; 19364 goto force_start;
19349 } 19365 }
19350 19366
19351 /* Don't use the same window-start if it is covered by a 19367 /* Don't use the same window-start if it is invisible or covered
19352 replacing 'display' property and the buffer requested the 19368 by a replacing 'display' property and the buffer requested
19353 window-start to be always visible. */ 19369 the window-start to be always visible. */
19354 if (make_window_start_visible 19370 if (!window_start_acceptable_p (window, CHARPOS (startp)))
19355 && !NILP (dspec = Fget_char_property (make_fixnum (CHARPOS (startp)),
19356 Qdisplay, window))
19357 && handle_display_spec (NULL, dspec, Qnil, Qnil, &ignored,
19358 CHARPOS (startp), FRAME_WINDOW_P (f)) > 0)
19359 { 19371 {
19360#ifdef GLYPH_DEBUG 19372#ifdef GLYPH_DEBUG
19361 debug_method_add (w, "recenter 2"); 19373 debug_method_add (w, "recenter 2");