Subject: Re: bug#12600: 24.2.50; linum-mode: line numbers in fringe do not refresh when resizing frame

From: martin rudalics <[email-masked]>
Date: Fri, 12 Oct 2012 17:42:32 +0200

>> Problems arise when the window handling code is supposed to change them.
 >
 > Like where and when?

Currently it does reset last_modified and last_overlay_modified in
Fset_window_start, set_window_buffer, window_resize_apply,
grow_mini_window, shrink_mini_window, window_scroll_pixel_based,
window_scroll_line_based and Fset_window_configuration.  I meanwhile
assume that I should do that in Fdelete_other_windows_internal too.

OTOH Frecenter, Fset_window_fringes and Fset_window_scroll_bars do set
window_end_valid but leave w->last_modified and w->last_overlay_modified
alone.

 >> That's exactly what I had in mind: Either something that corresponds
 >> textually to what is used in buffer.h or just mention the name of the
 >> corresponding field used in buffer.h.
 >
 > OK, will do.

And if possible add for each of these an advice like "Code that may
change the start/end position of a buffer in the window is supposed to
reset the value of this to Qnil/0". Please keep in mind that not very
many people currently have an idea what these fields are used for.  So
even if your advices are sloppy they will help to keep one's attention.

 >>  > Not necessarily.  It depends on what is recorded in the buffer's
 >>  > BUF_MODIFF slot.
 >>
 >> IIUC this can only increase monotonously
 >
 > But BUF_MODIFF could also change, no?

I meant BUF_MODIFF.

 > And a window can display
 > another buffer, can't it?

This would obviously have to be caught elsewhere since currently you
don't check for buffer identities either when you do

	   && w->last_modified >= MODIFF

in redisplay_internal (you probably did that before, but in some
independent way).  In any case, set_window_buffer would set
last_modifed_flag as well so again there's no reason for a counter.

 >> When last_modifed_flag is set, the window must be redisplayed.
 >
 > Not exactly, but OK.

You mean that in some cases we could get away without redisplaying it?
That's what I tried to address below.

 >> OTOH when the buffer iself is modified it has to be
 >> redisplayed anyway because we hardly know where the change happened.
 >
 > If course, we know: we know where the window begins and ends.

But we don't necessarily know where any buffer change(s) happened at the
time we redisplay.

 >> So I don't see why such a comparison of counters is useful.  But
 >> maybe I'm missing something.
 >
 > We probably both are, but what's the bottom line here?

That I still don't see why comparing last_modifed and MODIFF is useful
and why we have to assign two or three integer/Lisp fields instead of
one boolean.

 >>  > Because changes in overlays do not constitute changes in buffer
 >>  > contents, and are done via yet another set of primitives, yet they do
 >>  > require redisplay.  Also because each one of these can allow and
 >>  > disallow certain distinct redisplay optimizations, at least in
 >>  > principle.
 >>
 >> I doubt whether such optimizations exist.
 >
 > What, you mean in theory?  That's a strange opinion, as there are any
 > number of ways of optimizing redisplay.  In fact, there are comments
 > today in the display code that describe optimizations that could be
 > implemented, but never were.

Could you lay out one possible way where using a counter for
last_overlay_modified would allow an optimization?  I certainly would
not question any other optimizations.

 >> Suppose we could exclude a change to happen within the bounds of a
 >> window as for example a buffer displayed with a window starting at M
 >> and ending at N and an overlay modified at some position < M or > N.
 >> Wouldn't this require to associate each single overlay with a
 >> modification counter?
 >
 > Maybe, but I doubt that would allow any gains.  To make use of these
 > counters, you'd have to examine every overlay; but as soon as you have
 > an overlay in hand, its buffer position is as easy to access as its
 > counter.
 >
 > The problem with overlays is that overlays-at, next-overlay-change,
 > etc. are slow, not that we lack some info in the overlays themselves.
 >
 > Anyway, it would seem to be bad design to have a _window_ flag that
 > would change when some text or overlay in a buffer is modified.  Emacs
 > separates between display-related structures and buffer-related
 > structures for a number of good reasons, the most important being that
 > they are modified and examined independently, and there's no 1:1
 > relation between buffers and windows.

I agree with everything you say here.  Only that my conclusion is that
using a counter in last_overlay_modified is pretty much useless.

 >> I think that a correct implementation would have for each window w
 >>
 >> (w->last_modified < MODIFF) => (NOT (w->window_end_valid))
 >>
 >> but strongly doubt that this implication holds currently.
 >
 > You could try putting assertions like that in the code and see if they
 > fire.

Why bother?  You would have helped me by telling that such an assertion
_should_ hold.  If so, I can easily fill in the details.

 >> I don't intend to make any cleanups.  I'd like to have a simple routine
 >> we can use to reset any such structur members within window.c and have
 >> that DTRT.
 >
 > Under what circumstances does window.c need to do that?

In the cases I cited at the beginning of this post.  And maybe in some
cases I'm not aware of.

 >> Currently, `window-end' is clearly broken and we should fix it.
 >
 > An optimization that sometimes does the wrong thing is easy to fix:
 > either discover a condition under which the optimization works, or
 > simply disable the optimization.

If the underlying implementation defies the optimization, we should fix
that implementation.  But for that I'd have to understand the semantics
of the optimization first.

martin