summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2017-07-18 19:13:58 +0300
committerEli Zaretskii <eliz@gnu.org>2017-07-18 19:13:58 +0300
commitc2049489090141311bf8f460bf366d9784950861 (patch)
tree62b4d82b13cbe427ee2afa5c4f2a7cadbfed2ca7
parent3d432a180b3ac867d1d028af17cee14d481cfc01 (diff)
downloademacs-c2049489090141311bf8f460bf366d9784950861.tar.gz
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)
-rw-r--r--src/xdisp.c13
1 files changed, 13 insertions, 0 deletions
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;
}