Subject: Re: bug#14233: 24.3; Don't constrain frame size to character multiples

From: martin rudalics <[email-masked]>
Date: Fri, 26 Apr 2013 09:42:06 +0200

>> ... but the display margins were always included in the window
 >> dimensions ...
 >
 > Yes, and that might explain why so are the fringes.

... but the fringes never were ...

 >>  > but OTOH the fringes separate the window into 2 disjoint
 >>  > areas.
 >>
 >> ... so what am I missing?  All I want is to maintain fringes exclusively
 >> inside the frame's root window.
 >
 > I don't know anymore who misses what.  You said:
 >
 >>  >> When you remove the scrollbars the Emacs frame shrinks.  When you
 >>  >> remove the fringes it does not shrink.  Yet, when changing frame
 >>  >> sizes we are expected to handle fringes and scrollbars alike: They
 >>  >> are no text, they are no windows and therefore should not be counted
 >>  >> in the width of the frame's text area.
 >
 > which to me means that you want fringes to NOT be included in the
 > window text area.  Therefore, I tried to explain what was (or could
 > be) the motivation to INCLUDE fringes in the text area: because
 > otherwise, the display margins, which ARE part of text area, would
 > become disjoint from the rest of the window's text area by the fringes
 > that are in-between.

You misread.  There's a difference between what I want to do and what
has to be done to fix an existing bug.  Let me start with the latter
first.

------

An Emacs frame contains a text area and a non-text area, both of which
are not necessarily contiguous.  Traditionally, the text area contains
the displayed buffer texts, the display margins, the minibuffer window,
the toolbar window and the menubar window.  The non-text area contains
the scrollbars and vertical divider lines, the fringes, and the internal
borders of the frame.

In addition, a frame usually has parts maintained externally like an
external toolbar, menubar, decorations and external borders.  Parts
maintained externally are not directly controlled by Emacs, their sizes
and appearances are subject to negotiations with the operating system's
window manager.

Part of this traditional convention is that when certain aspects of the
appearance of a frame change, Emacs tries to keep the size of the
displayed buffer text unchanged in terms of lines and columns.  This
implies that when we add/remove/change the size of a scrollbar or a
fringe, the size of the frame as a whole has to change to keep the
number of columns in the text area (which is already an abstraction of
the displayed buffer text due to the presence of display margins)
constant.  We also resize the frame when we change its default font or
the internal border width.

We do not change the frame size when we modify the buffer text, change
the height of the minibuffer window, a toolbar window, a menubar window,
or the size of display margins.

I don't know whether changing parts maintained externally (like removing
an external toolbar or setting the operating system's default font for
menubar items), may affect the size of the rest of the frame.  I guess
that usually the OS/window manager tries to keep the size of the entire
frame (inlcuding the external parts) constant, but this might not be
always the case.  I'd be glad if someone informed me about the behavior
of Emacs in this regard on the various platforms we maintain.

The traditional concept works well for frames that contain one window
only.  It fails already, where a frame is built from two windows one
above the other where one of these windows comprises two side-by-side
windows.  In this case, changing a scrollbar or a fringe will invalidate
the attempt to keep the number of columns/lines of displayed buffer text
(the text areas) unchanged.

In addition, the concept sketched above has been softened with the
addition of window/buffer-local fringes and scrollbars.  Changing these
affect the window(s) displaying a certain buffer only and do not change
the size of the frame.

Note that with side-by-side windows frame-local fringe/scrollbar widths
have been practically eradicated - they continue to live virtually only
(mainly serving as a default value for windows and buffers that don't
define their own).

Unfortunately, later changes clashed with the earlier defined concepts
in a number of ways.  Here I shall sketch two of them:

(1) Over the time, the fringe handling code has been rewritten (in a
     routine called compute_fringe_widths) such that changing a frame's
     fringes will not cause the frame to get resized immediately but
     stores the new values in the corresponding frame parameter only.

     This behavior is the immediate cause of bug#14222 and should be
     fixed, either by sending a resize request to the OS (which might be
     tricky) or by having fringes become part of the frame's text area.

(2) Maximized/fullscreen frames do not play nicely with keeping the
     numbers of columns/lines unchanged.  Emacs should not resize such a
     frame when changing default font or parts of the non-text area.

This concludes my assessment of how Emacs frames traditionally behave
and what should be done to fix some shortcomings.  It's by no means
related to the introduction of pixelwise resizing and/or to how I want
Emacs frames to behave.

-----------------------

What I _want_ to do is no less than to remove the aim to keep the number
of columns/lines unchanged when changing aspects that control the
appearance of frames like scrollbars, fringes, or internal borders.
And, as Jan remarked, we should also try to keep the combined size of an
Emacs frame + its externally maintained parts unchanged when, for
example, removing an external toolbar (unless the window manager handles
this case already as it apparently already does when resizing an
external menubar).

This aim has two immediate consequences:

(1) We do not distinguish between a frame's text and non-text areas any
     more.  The frame size changes only when explicitly requested.  This
     also means that we don't have to contact the OS/window manager when
     adding/removing scrollbars/internal borders or changing the default
     font.

(2) In some case we may now have to contact the OS/window manager, for
     example, when removing an external toolbar, we may have to issue a
     request to fill the freed screen space with the to-be-enlarged Emacs
     frame.  Whether and where this is necessary is beyond my knowledge
     though.

I'm still uncertain whether this behavior should be applied to textual
frames too.

-----------

Finally note that I do not intend to implement any of the things I
sketched here in my pixelwise implementation of frame/window resizing.
This implementation will emulate the current behavior (with all its bugs
and shortcomings) as closely as possible.

martin