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

From: Bruno Félix Rezende Ribeiro <[email-masked]>
Date: Tue, 04 Nov 2014 17:56:42 -0200

Eli Zaretskii wrote:

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

I mean by scroll the change of correspondence between window lines and
buffer lines.  It's not absolutely associated with any particular
Emacs command.  There are commands that are intended to directly cause
scrolling, but don't do so in particular cases (eg. 'C-v' at the
end of the buffer), and there are commands that are not directly
intended to cause scrolling but do so in particular cases
(eg. 'C-n' at the last visible line of a window).

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

You are right.  That's a particular case for which the rule of thumb
is: for newly created windows the mode-line should be drawn after the
buffer's content is drawn.  I think that would solve the problem.
From there forth, after any scrolling the mode-line should be
(optionally) drawn after the buffer's content is drawn.

> What about moving cursor so it exits the visible portion of the 
> window, which also induces scrolling?

It corrupts the mode-line as do 'C-l' typed multiple times.

> And what about using the scroll bar?

This too.

> Or just "M-x goto-char RET"?

Idem, as long as it causes scrolling and the new view has a buffer
line "under" the mode-line.  The same happens with the 'goto-line'
command.

> Are you saying these don't produce a corrupted mode line?

Nope, actually all of them are capable of corrupting the mode-line.

> 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?

It does in that very area.

> 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.

It would be wise to provide a way to force Emacs to redraw, because
there are factors beyond Emacs control and knowledge that could change
the aspect of the frame.  This bug is an example of that.

> 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.

Again, sometimes it's necessary to redraw more than Emacs think it
should.  I'm not advocating to make Emacs redraw the whole frame,
rather just the mode-line after very specific events.

> Is there _any_ Emacs action that succeeds in redrawing the mode line
>  or its parts in a way that eliminates the corruption?

Yes, there is.

> 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?

This also eliminates the corruption.

> do they successfully redraw the corresponding parts of the mode 
> line?

Yep.

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

Nope, because it draws the buffer's content after redrawing the
mode-line, overriding the mode-line refresh, in effect.

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

They in fact help!  So I think Emacs can do something to help me work
around the problem, if you help Emacs to help me. ;-)

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

Because the acceleration is not intended to cause that sort of
problem.  That's bug.  Moreover, if I disable acceleration I would
affect a lot more than just Emacs.  On the other hand, the Emacs
workaround I propose won't affect any other application or user of
Emacs, and will help everyone else experiencing similar problems.

From my perspective, it's an improvement to make Emacs aware that it
cannot know everything, and therefore we reserve the right to force it
to redraw some parts of its frames, even if it doesn't feel like it,
when we, the users, judge necessary.

In particular Emacs must know that when redrawing the frame's content,
it should first draw the buffer's content and only then the mode-line.

> 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.

That makes a lot of sense.

-- 
 ,= ,-_-. =.  Bruno Félix Rezende Ribeiro (oitofelix) [0x28D618AF]
((_/)o o(\_)) There is no system but GNU;
 `-'(. .)`-'  GNU Linux-Libre is one of its official kernels;
     \_/      All software must be free as in freedom;