Subject: Re: bug#32848: 26.1; follow-mode cursor move breaks with frame-resize-pixelwise

From: Alan Mackenzie <[email-masked]>
Date: Sat, 29 Sep 2018 14:48:46 +0000

Hello, Eli.

On Sat, Sep 29, 2018 at 16:47:16 +0300, Eli Zaretskii wrote:
> > Date: Sat, 29 Sep 2018 11:25:20 +0000
> > Cc: [email-masked], [email-masked], [email-masked]
> > From: Alan Mackenzie <[email-masked]>

> > I think my proposal from my last post is also safe and simple, it being
> > a mere 5 lines (not counting comments) in one place in follow.el, and
> > which is self contained.  It ranks in complexity between your two
> > proposals.

> It isn't anywhere near safe in my book, sorry.  Futzing with
> window-start and other related variables is a minefield we better not
> go into on the release branch.

My patch doesn't do anything like that.  It merely has a test, and if
that test signals t, moves point by one line, away from the danger area.
The messing around with window-start has been in follow mode for ever.
I think it's time to post that patch:

diff --git a/lisp/follow.el b/lisp/follow.el
index fd397c077b..7d6204b08e 100644
--- a/lisp/follow.el
+++ b/lisp/follow.el
@@ -1385,7 +1385,15 @@ follow-adjust-window
 	  (unless (eq win (selected-window))
 	    (let ((p (window-point win)))
 	      (set-window-start win (window-start win) nil)
-	      (set-window-point win p))))
+	      (set-window-point win p)
+              (if (and frame-resize-pixelwise
+                       make-cursor-line-fully-visible
+                       ;; Check for cursor being in partially displayed line.
+                       (nth 2 (pos-visible-in-window-p p win t)))
+                  ;; If so, move point away from this disaster line,
+                  ;; preventing scrolling.
+                  (with-selected-window win
+                    (forward-line -1))))))
 
 	(unless visible
 	  ;; If point may not be visible in the selected window,

Please reconsider it, now you can see how little it actually does.

> So if you don't think turning off make-cursor-line-fully-visible in
> follow-mode buffers is an okay solution, the solution will have to
> wait till Emacs 27, sorry.

Turning off m-c-l-f-v I can live with, and if you definitely reject my
approach above, I'm willing to implement it.  It can't be difficult, just
creating a buffer local variable and setting it to nil.  ;-)

[ .... ]

> Users of follow-mode can choose whether they want the buggy behavior
> we see now or give up fully-visible last line in the last window under
> some rare situations (I couldn't even simulate those situations, btw).

Fair enough!  We are rather arguing about things which will rarely, if
ever, happen.

> > > Why is this better than what I proposed?

> > It is simpler than allowing m-c-l-f-v be a function (which would involve
> > amendments in xdisp.c, I think)

> The changes in xdisp.c are a no-brainer, we already call several Lisp
> functions in several places, and there's infrastructure ready for
> that.

OK.  But it will be more complex than my 5-line patch above.  But I have
no objections to this change (making that variable optionally a
function).

> > > I proposed to allow make-cursor-line-fully-visible to have a value
> > > that is a function, and let follow-mode define that function
> > > accordingly, to make Emacs behave as if the last window in the group
> > > had make-cursor-line-fully-visible set to the default or what the user
> > > set it, and nil in all other windows under follow-mode.  I think that
> > > every solution that lets the display engine do the job is cleaner than
> > > trying to force the display engine do that same job.

> > Maybe.  But follow mode is already a big fight with the display engine.

> This one won't be a "fight" in any sense, just a call to a Lisp
> function from C, that's all.  And it happens in only one place.

> > > Besides, your proposal has the annoying effect of causing a
> > > micro-scroll near the end of the window.

> > I don't see this (on GNU/Linux/X with GTK+ 3.22.30).

> What, you mean you change the window-start and the text doesn't get
> scrolled up to display starting from the new window-start?  How can
> that be?

No, my patch doesn't change anything.  Follow mode already does this:

    (set-window-start win (window-start win) nil)

, which it does solely to prevent redisplay scrolling that buffer.  It
does not change window-start here.  This is what I meant by follow mode
and redisplay fighting.

> Or maybe by "it" you meant move point?  Then moving point is a side
> effect I think we should avoid in this case.

Point cannot stay in that partially displayed line.  Follow mode moving
it away prevents redisplay from scrolling the window.

> > I was also thinking of amending the doc for set-window-start, to alert
> > users to the possibility of a nil NOFORCE argument failing to prevent
> > scrolling.  If make-cursor-line-fully-visible were to become,
> > optionally, a function there would be more reason to document it in the
> > manual.

> Fine with me, although saying in the docs that something doesn't have
> to happen with 100% probability doesn't strike me as very helpful.

The current docs imply NOFORCE being nil always works.  If the docs had
mentioned the exception, it's possible we wouldn't now be dealing with
this bug.

-- 
Alan Mackenzie (Nuremberg, Germany).