[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Window tree and window's internal height

From: martin rudalics
Subject: Re: Window tree and window's internal height
Date: Sat, 17 Nov 2018 19:39:36 +0100

> First, we have this in the ELisp manual:
>       A minibuffer window (*note Minibuffer Windows::) is not part of its
>    frame’s window tree unless the frame is a minibuffer-only frame.
>    Nonetheless, most of the functions in this section accept the minibuffer
>    window as an argument.  Also, the function ‘window-tree’ described at
>    the end of this section lists the minibuffer window alongside the actual
>    window tree.
> The first sentence is incorrect, isn't it?  Because Emacs disagrees:
>    emacs -Q
>    M-: (window-next-sibling) RET
>     => #<window 4 on  *Minibuf-0*>
> And if that sentence is incorrect, we don't need the next two
> "exceptions", right?

Right, graph theoretically.  For a long time, however, the Elisp manual
has used the term "root", for example, in Emacs 22 as follows

     The return value is a list of the form `(ROOT MINI)', where ROOT
     represents the window tree of the frame's root window, and MINI is
     the frame's minibuffer window.

which implies that Emacs' window tree is not free but a "rooted tree"
and in a rooted tree every node except the root must have a unique
parent node.  But the minibuffer window does not have a parent so we
would have two nodes without parent.

Which means that our window tree concept per se is valid but using
'window-next-sibling' to get the minibuffer window from the root
window is an incorrect naming convention.  It's simply there because
'window-next-sibling' is a 1-to-1 reflection of the w->next field of
the window structure in window.h.

> Next, please have a look at the function window_internal_height:
>    /* Return number of lines of text (not counting mode lines) in W.  */
>    int
>    window_internal_height (struct window *w)
>    {
>      int ht = w->total_lines;
>      if (!MINI_WINDOW_P (w))
>        {
>    if (!NILP (w->parent)
>        || WINDOWP (w->contents)
>        || !NILP (w->next)
>        || !NILP (w->prev)
>        || window_wants_mode_line (w))
>      --ht;
>    if (window_wants_header_line (w))
>      --ht;
>        }
>      return ht;
>    }
> I don't understand any of the conditions except window_wants_mode_line
> when we decide whether to decrease the height due to the mode line.
> What do the other conditions have to do with the window's height?  I
> could perhaps understand the "WINDOWP (w->contents)" part, as some
> kind of optimization for non-leaf windows, which assumes the default
> of having the mode line, but the rest seem simply wrong, don't they?
> (The WINDOWP condition is not really interesting, as I don't see any
> call of this function for a non-leaf window.)

Whatever these three conditions were meant for is beyond my
imagination.  window_internal_height was always off-limit for me.  I
wonder how these miscalculations would affect window_scroll_line_based
(I hardly ever use modeline-less windows) though.

> This is the immediate cause of bug#33363, which I could fix either by
> a local change in try_window_id, or by modifying
> window_internal_height to leave only the window_wants_mode_line
> condition there.  If the latter might be unsafe, maybe I should do the
> former on the release branch and the latter on master.  WDYT?

I would call window_body_height on the release branch and on master.
And I would use window_body_height in window_scroll_line_based too.
It should then take care of dividers and horizontal scroll bars on GUI
windows as well.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]