Subject: bug#14825: 24.3.50; split-window-below miscounts window lines

From: Eli Zaretskii <[email-masked]>
Date: Fri, 12 Jul 2013 12:09:45 +0300

> Date: Fri, 12 Jul 2013 10:21:41 +0200
> From: martin rudalics <[email-masked]>
> CC: [email-masked]
> 
>  > These are externally visible, documented APIs; we cannot say they
>  > measure in line units, while in fact they measure in some other
>  > obscure units.  And please note that someone who is not privy to the
>  > Emacs internals (on the C level) will not be able to get to the bottom
>  > of this once they bump into the problems this creates.  The truth is
>  > buried deep behind macros and accessor functions whose names are as
>  > misleading as those of the APIs that expose them.
>  >
>  > This must be rectified.  We can either fix the doc strings, or
>  > (better) introduce a separate set of APIs that counts lines in units
>  > of the default face.
> 
>  From the Elisp manual:
> 
>        Emacs provides several functions for finding the height and width of
>     a window.  Except where noted, Emacs reports window heights and widths
>     as integer numbers of lines and columns, respectively.  On a graphical
>     display, each "line" and "column" actually corresponds to the height
>     and width of a "default" character specified by the frame's default
>     font.  Thus, if a window is displaying text with a different font or
>     size, the reported height and width for that window may differ from the
>     actual number of text lines or columns displayed within it.

Yes, I know.  But note that this extended explanation is also
misleading, because it silently assumes that the default face was not
remapped.  If the default face _is_ remapped, then "the frame's
default font" is ambiguous at best, since '(face-font 'default)' will
return a font whose size is not the one meant by the above
description.

> If we want to put this explanation into the doc-strings, we'd probably
> have to change the doc-strings of frame functions too.

We could just have a warning there about not using these functions to
count text lines in a window.

> I still have to understand what you conisder a misconception here: IIUC
> you say that if a buffer has a default face that differs from the
> default face of the frame it is shown on, the height of any window
> showing that buffer should be calculated in terms of that buffer's face.

Yes, but it's not only about the default face.  Did you try setting
line-spacing to something non-nil lately?  Try it: it's a lot of fun
looking at what window-text-height and its ilk return in that case.

> So when you show another buffer in that window, the window's height
> might change nominally although it does not change visually.

Right.

> Now if the window is the only one on its frame, you would have to change
> the frame's nominal height as well

The number of lines in the frame does not necessarily need to change,
because a frame has other elements, even if it has only one window --
the mode line, the menu bar, the tool bar, etc.  What matters is the
root window, not the frame.  So we can still measure a frame in
canonical units.

> If OTOH the frame contains more than one window, we would have a
> hard time to relate the height of these windows to that of the
> frame.

The only reliable way of doing that is in pixels anyway.

> Lifting the present relationship without providing a viable alternative
> would be a misconception IMO.

That's why I suggested to introduce a separate set of APIs.

> My apologies if what I say here doesn't fit your expectations.  But
> doing ad hoc changes to code that has evolved over decades is over my
> head.

I didn't suggest that.  My suggestion pols down to this:

 . Say in the doc strings of all these functions that their return
   values should NOT be used to count lines or columns of text in a
   window;

 . Add a separate set of APIs for counting the number of default-face
   text lines and characters in a window.