From: Alan Mackenzie <acm@muc.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 51590@debbugs.gnu.org, Juri Linkov <juri@linkov.net>
Subject: bug#51590: follow-mode is broken with header-line and tab-line
Date: Fri, 5 Nov 2021 21:45:32 +0000 [thread overview]
Message-ID: <YYWl/FgcizlBrKKB@ACM> (raw)
In-Reply-To: <835yt7g3my.fsf@gnu.org>
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).
next prev parent reply other threads:[~2021-11-05 21:45 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-03 18:24 bug#51590: Tab-line breaks windows of follow-mode Juri Linkov
2021-11-03 18:35 ` Eli Zaretskii
2021-11-04 17:29 ` bug#51590: follow-mode is broken with header-line and tab-line Juri Linkov
2021-11-04 18:46 ` Eli Zaretskii
2021-11-04 19:06 ` Alan Mackenzie
2021-11-05 21:45 ` Alan Mackenzie [this message]
2021-11-06 7:00 ` Eli Zaretskii
2021-11-06 11:50 ` Alan Mackenzie
2021-11-06 12:12 ` Eli Zaretskii
2021-11-06 18:31 ` martin rudalics
2021-11-06 18:40 ` Eli Zaretskii
2021-11-08 15:36 ` martin rudalics
2021-11-08 17:32 ` martin rudalics
2021-11-08 18:47 ` Eli Zaretskii
2021-11-09 10:14 ` martin rudalics
2021-11-06 18:44 ` martin rudalics
2021-11-08 17:59 ` Alan Mackenzie
2021-11-08 18:23 ` Eli Zaretskii
2021-11-09 10:12 ` martin rudalics
2021-11-09 10:10 ` martin rudalics
2021-11-04 18:52 ` martin rudalics
2021-11-07 12:48 ` Alan Mackenzie
2021-11-07 13:14 ` Eli Zaretskii
2021-11-07 14:28 ` Alan Mackenzie
2021-11-07 17:46 ` Juri Linkov
2021-11-07 19:44 ` Alan Mackenzie
2021-11-07 19:56 ` Juri Linkov
2021-11-08 7:13 ` Alan Mackenzie
2021-11-05 7:42 ` Stefan Kangas
2021-11-05 8:55 ` Juri Linkov
2021-11-05 10:15 ` Stefan Kangas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YYWl/FgcizlBrKKB@ACM \
--to=acm@muc.de \
--cc=51590@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=juri@linkov.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).