Subject: Re: bug#18912: 24.4; mode-line corruption on graphical frames in dual-headed display

From: Eli Zaretskii <[email-masked]>
Date: Tue, 04 Nov 2014 18:16:49 +0200

> Date: Tue, 04 Nov 2014 08:25:38 -0200
> From: Bruno Félix Rezende Ribeiro <[email-masked]>
> CC: [email-masked]
> 
> > Elsewhere you asked to "please, provide a way to make Emacs 
> > optionally redraw the mode-line after any scroll operation".  How 
> > does scrolling enter here?
> 
> After getting the mode-line right by refreshing the frame, only
> scrolling can possibly corrupt the mode-line again.

What do you mean by "scrolling", exactly?  Which Emacs commands?

In any case, the initial display of "C-x d" doesn't involve any
scrolling, so it's not a "scrolling problem".

> After creating the frame with 'emacs -Q', typing 'C-x d /dev RET'
> takes me to a Dired buffer with a corrupted mode-line as shown in the
> picture attached to the original bug report.  There, typing 'M-!
> xrefresh RET' repaints the whole frame and the mode-line is shown
> normally as one would expect.  Scrolling the text up with 'C-v'
> corrupts the mode-line again.

What about moving cursor so it exits the visible portion of the
window, which also induces scrolling?  And what about using the scroll
bar?  Or just "M-x goto-char RET"?  Are you saying these don't produce
a corrupted mode line?

> > I don't have the slightest idea why the mode line would _not_ be
> > redrawn after scrolling but maybe there's some optimization here.  In
> > any case with emacs -Q moving the window's point from one line to
> > another should redraw the mode line to show the new line number.
> 
> If it redraws the mode-line, it does so while corrupting the mode-line
> again

When you move to a different line, Emacs only redraws the line number
part of the mode line.  Does that at least remove the corruption in
that area, or doesn't it?

In general, Emacs always redraws only the parts of the screen that
were changed.  If you tell it to redraw, and nothing changed, it will
normally not redraw anything at all.

> because, by observation, updating the line number doesn't trigger
> the same kind of redraw that the 'xrefresh' command does.

Of course, it doesn't!  Emacs doesn't use the technique used by
xrefresh, because Emacs tries to redraw as little as possible, not as
much as possible!  xrefresh was coded specifically to force portions
of the screen to be completely redrawn, which is almost the
anti-thesis of the Emacs display engine.

Is there _any_ Emacs action that succeeds in redrawing the mode line
or its parts in a way that eliminates the corruption?  I already asked
above about whether moving to a different line does that in the
portion that displays the line number.  How about hovering the mouse
pointer over mouse-sensitive portions of the mode line, like the
buffer name and the major/minor mode indications? do they successfully
redraw the corresponding parts of the mode line?

What about "M-x redraw-display RET" -- does it fix the display of the
mode line?

If none of these helps, then I don't think Emacs can do anything at
all to help you work around the problem.

(And btw, why disabling the acceleration permanently isn't _the_
solution?)

> > BTW, suppose you evaluate
> > 
> > (set-frame-parameter nil 'bottom-divider-width 8)
> > 
> > Does that impact the appearance of the bug in any way?
> 
> Yes, it does.  The mode-line still gets corrupt but this time by the
> lower half (approximately) of the line above the one that corrupted it
> originally.
> 
> Interesting enough,
> 
> (set-frame-parameter nil 'bottom-divider-width 1)
> 
> fixes the problem for the original frame.  Unfortunately when
> in full-screen the mode-line is corrupted again; what is fixed in the
> VGA1 output by
> 
> (set-frame-parameter nil 'bottom-divider-width 7)
> 
> and in the LVDS1 output by
> 
> (set-frame-parameter nil 'bottom-divider-width 12)

Any change in window height that causes it to be an exact integral
multiple of the font height will eliminate the problem.  The problem
is evidently caused by incorrect clipping of partially-visible lines.
That's why you see what you see.