From c2049489090141311bf8f460bf366d9784950861 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 18 Jul 2017 19:13:58 +0300 Subject: [PATCH] Avoid infloop due to Eshell's "smart" redisplay * src/xdisp.c (pos_visible_p): Save and restore the window's mode-line and header-line height. (Bug#27752) --- src/xdisp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/xdisp.c b/src/xdisp.c index a3bc5a5fccd..c415bf2131f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1326,6 +1326,15 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, if (charpos >= 0 && CHARPOS (top) > charpos) return visible_p; + /* Some Lisp hook could call us in the middle of redisplaying this + very window. If, by some bad luck, we are retrying redisplay + because we found that the mode-line height and/or header-line + height needs to be updated, the assignment of mode_line_height + and header_line_height below could disrupt that, due to the + selected/nonselected window dance during mode-line display, and + we could infloop. Avoid that. */ + int prev_mode_line_height = w->mode_line_height; + int prev_header_line_height = w->header_line_height; /* Compute exact mode line heights. */ if (window_wants_mode_line (w)) { @@ -1672,6 +1681,10 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll); #endif + /* Restore potentially overwritten values. */ + w->mode_line_height = prev_mode_line_height; + w->header_line_height = prev_header_line_height; + return visible_p; } -- 2.39.2