From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Alan Mackenzie <acm@muc.de>
Newsgroups: gmane.emacs.bugs
Subject: bug#51590: follow-mode is broken with header-line and tab-line
Date: Fri, 5 Nov 2021 21:45:32 +0000
Message-ID: <YYWl/FgcizlBrKKB@ACM>
References: <86bl31xfl9.fsf@mail.linkov.net> <83h7ctgk93.fsf@gnu.org>
 <86pmrf3l9m.fsf_-_@mail.linkov.net> <835yt7g3my.fsf@gnu.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="15685"; mail-complaints-to="usenet@ciao.gmane.io"
Cc: 51590@debbugs.gnu.org, Juri Linkov <juri@linkov.net>
To: Eli Zaretskii <eliz@gnu.org>
Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Nov 05 22:46:12 2021
Return-path: <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>
Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>)
	id 1mj72K-0003rF-0Z
	for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 05 Nov 2021 22:46:12 +0100
Original-Received: from localhost ([::1]:43820 helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>)
	id 1mj72H-0004Bg-Mw
	for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 05 Nov 2021 17:46:09 -0400
Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50970)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1mj72B-0004BY-PM
 for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 17:46:03 -0400
Original-Received: from debbugs.gnu.org ([209.51.188.43]:35945)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1mj72A-0003lE-6e
 for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 17:46:03 -0400
Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1mj72A-0004iP-4z
 for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 17:46:02 -0400
X-Loop: help-debbugs@gnu.org
Resent-From: Alan Mackenzie <acm@muc.de>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces@debbugs.gnu.org>
Resent-CC: bug-gnu-emacs@gnu.org
Resent-Date: Fri, 05 Nov 2021 21:46:02 +0000
Resent-Message-ID: <handler.51590.B51590.163614874018093@debbugs.gnu.org>
Resent-Sender: help-debbugs@gnu.org
X-GNU-PR-Message: followup 51590
X-GNU-PR-Package: emacs
Original-Received: via spool by 51590-submit@debbugs.gnu.org id=B51590.163614874018093
 (code B ref 51590); Fri, 05 Nov 2021 21:46:02 +0000
Original-Received: (at 51590) by debbugs.gnu.org; 5 Nov 2021 21:45:40 +0000
Original-Received: from localhost ([127.0.0.1]:47491 helo=debbugs.gnu.org)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <debbugs-submit-bounces@debbugs.gnu.org>)
 id 1mj71o-0004hk-EW
 for submit@debbugs.gnu.org; Fri, 05 Nov 2021 17:45:40 -0400
Original-Received: from colin.muc.de ([193.149.48.1]:60383 helo=mail.muc.de)
 by debbugs.gnu.org with smtp (Exim 4.84_2)
 (envelope-from <acm@muc.de>) id 1mj71m-0004hX-Lx
 for 51590@debbugs.gnu.org; Fri, 05 Nov 2021 17:45:39 -0400
Original-Received: (qmail 67536 invoked by uid 3782); 5 Nov 2021 21:45:32 -0000
Original-Received: from acm.muc.de (p4fe15881.dip0.t-ipconnect.de [79.225.88.129])
 (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP;
 Fri, 05 Nov 2021 22:45:32 +0100
Original-Received: (qmail 5233 invoked by uid 1000); 5 Nov 2021 21:45:32 -0000
Content-Disposition: inline
In-Reply-To: <835yt7g3my.fsf@gnu.org>
X-Submission-Agent: TMDA/1.3.x (Ph3nix)
X-Primary-Address: acm@muc.de
X-BeenThere: debbugs-submit@debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
X-BeenThere: bug-gnu-emacs@gnu.org
List-Id: "Bug reports for GNU Emacs,
 the Swiss army knife of text editors" <bug-gnu-emacs.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/bug-gnu-emacs>
List-Post: <mailto:bug-gnu-emacs@gnu.org>
List-Help: <mailto:bug-gnu-emacs-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=subscribe>
Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org
Original-Sender: "bug-gnu-emacs"
 <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>
Xref: news.gmane.io gmane.emacs.bugs:219027
Archived-At: <http://permalink.gmane.org/gmane.emacs.bugs/219027>

Hello, Eli and Juri.

On Thu, Nov 04, 2021 at 20:46:45 +0200, Eli Zaretskii wrote:
> > From: Juri Linkov <juri@linkov.net>
> > Cc: 51590@debbugs.gnu.org
> > Date: Thu, 04 Nov 2021 19:29:28 +0200

> > After trial and error, I arrived to the following patch that completely
> > fixes these problems.  However, I can't explain how it works.

> Alan, any comments?

Yes.  There's a bug in posn-at-x-y, in that either the function or the
documentation is wrong.

The doc says, rather unhelpfully, "By default, X and Y are relative to
[the] text area of the selected window.".  What does "[the] text area"
mean?  In other places, it means the same as "the body" of a window,
which is the area of text not including the mode line, header line or
tab-bar line.

In posn-at-x-y, "the text area" _INCLUDES_ THE HEADER LINE.  This can be
verified, in a GUI Emacs with

    M-: (posn-point (posn-at-x-y 0 18))
                                   ^^
This returns the buffer position of the earliest character in the
window.  The "18" means 18 pixels after the top of the header line.
Surely it ought to mean 18 pixels after the top of the first buffer line
in the window, i.e. the second window line.

This is a bug.

It has unfortunate consequences in (the current) follow-calc-win-end:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun follow-calc-win-end (&optional win)
  "Calculate the end position for window WIN.
Return (END-POS END-OF-BUFFER).

Actually, the position returned is the start of the line after
the last fully-visible line in WIN.  END-OF-BUFFER is t when EOB
is fully-visible in WIN.  If WIN is nil, the selected window is
used."
  (let* ((win (or win (selected-window)))
         (edges (window-inside-pixel-edges win))
         (ht (- (nth 3 edges) (nth 1 edges)))                 <======= 1
         (last-line-pos (posn-point (posn-at-x-y 0 (1- ht) win)))) <== 2
    (if (pos-visible-in-window-p last-line-pos win)           <======= 3
        (let ((end (window-end win t)))
          (list end (pos-visible-in-window-p (point-max) win)))
      (list last-line-pos nil))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

At 1, ht "the height" is the height of the "body" of the window, i.e.
all lines not including the header-line or mode-line.

At 2, posn-point intends to find the bottom pixel in the text part of
the window.  If there is a partial line there, posn-at-x-y will be in
the partial line, otherwise it will be in the last line of the window.
last-line-pos is the buffer position of whichever line that was.

At 3, pos-visible-in-window-p will return nil for the partial line or t
for the full line.  In the nil case, the function result is the partial
line, in the t case, it's (window-end ...).

This is all well and good.  But because of the bug in posn-at-x-y, when
there's a partial line there, at 2 last-line-pos is set one line too
far towards point-max.  Thus, at 3, pos-visible-in-window-p spuriously
returns t.  (window-end) now returns the line after the partial line,
which is wrong.

It would appear this behaviour of posn-at-x-y is also in Emacs 27.2.  It
would probably be catastrophic to fix posn-at-x-y, since so many
programs will have compensated for this bug.  So, we should probably fix
the doc of the function.

But we can fix follow-calc-win-end, by replacing the form at 2 with:

    (last-line-pos (posn-point (+ (posn-at-x-y 0 (1- ht) win)
                                  (window-header-line-height win))))

And I think we (probably me ;-) should go through the elisp manual and
doc strings replacing vague phrases like "the text area of the window"
with explicit descriptions involving "the header line", etc.

Juri, I'm sorry I haven't looked at the first hunk of your patch yet,
the one in follow-scroll-down.

-- 
Alan Mackenzie (Nuremberg, Germany).