diff options
author | Eli Zaretskii <eliz@gnu.org> | 2017-07-18 19:13:58 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2017-07-18 19:13:58 +0300 |
commit | c2049489090141311bf8f460bf366d9784950861 (patch) | |
tree | 62b4d82b13cbe427ee2afa5c4f2a7cadbfed2ca7 | |
parent | 3d432a180b3ac867d1d028af17cee14d481cfc01 (diff) | |
download | emacs-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.c | 13 |
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; } |