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

From: martin rudalics <[email-masked]>
Date: Wed, 01 May 2013 11:15:14 +0200

> But it does not change proportionately wrt the font change.
 >
 > With font size 25 I see fringe of width 15 (ratio: 1.667)
 >                13                        8 (ratio: 1.625)
 >                 9                       10 (ratio: 1.111)
 >
 > And the last two lines really make one wonder.  Anyway, you are correct that the
 > fringe does get resized.  But zooming the font does not zoom the fringe
 > similarly.

All this happens in a routine called compute_fringe_widths in fringe.c.
And it's a real pain because it tries to reconcile things like fixed
fringe widths (encoded via negative values), asymmetric resizing, and
rounding to character widths.  All this is not really harmful per se but
can eventually affect the width of the displayed frame and _when_ that
happens is pretty unpredictable.  Finally, frame fringes have to be
somewhere reconciled with buffer-local and window-local fringes.

 > Anyway, let's not won't worry too much about the fringe behavior, for now.

Well, I do.

 > Large sizes of the font?  I just tried up to size 200 (chars several cm high),
 > and the scroll bar stayed (visibly) the same.  (I didn't check the parameter
 > values.)

Conceptually x_new_font in w32term.c changes fringes and scrollbars
thusly

   compute_fringe_widths (f, 1);

   /* Compute the scroll bar width in character columns.  */
   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
     {
       int wid = FRAME_COLUMN_WIDTH (f);
       FRAME_CONFIG_SCROLL_BAR_COLS (f)
	= (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
     }
   else
     {
       int wid = FRAME_COLUMN_WIDTH (f);
       FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
     }

If we don't see an effect, it might be due to some rounding or a missing
request to the window manager.

 >> I could experiment further but it's too annoying because my
 >> frame always gets larger than my screen.
 >
 > Try going smaller rather than larger.

Then I won't see anything any more.

 >>  > My concerns, which I'm sure you understand, are these:
 >>  >
 >>  > a. `modify-frame-parameters' should not be changed so that
 >>  > it affects future behavior.
 >>
 >> My concern is that it should be changed.
 >
 > Why should it?  Why should modifying one frame affect all future frames?  That
 > makes no sense to me.  If you make one frame background light blue, do you
 > expect all future frames to also have a light blue background?  If so, why?

I thought "future behavior" referred to the future behavior of Emacs in
this regard.  And I would like to change that indeed.  But I obviously
agree with you that modifying a specific frame's parameters via
`modify-frame-parameters' should never affect other or future frames.
Whether "setting the default font" via the menu should affect one frame,
all existing frames, or future frames is an issue that should be
discussed separately.

 > Much as I could be persuaded wrt whether `modify-frame-parameters' should zoom
 > the frame size when you zoom the `font' parameter, I do not see any
 > justification for `modify-frame-parameters' affecting other than the targeted
 > frame.  That just sounds perverse to me, and I expect it would lead to all kinds
 > of unwelcome behavior.

Fully agreed.

 >>  > b. Changing the `font' parameter of a frame should also
 >>  > shrink/enlarge the frame, as it does today.  That is,
 >>  > shrink/enlarge in terms of screen size (pixels), but not
 >>  > in terms of number of lines/cols.  IOW, the frame size should
 >>  > keep the same number of lines/cols.
 >>
 >> I'd prefer the frame + external objects to keep the same
 >> number of pixels.
 >
 > As I said, the choice should be up to the user.  Different users will have
 > different use cases (and preferences), and the same user will have different use
 > cases at different times.

Agreed again.

 > Why is it necessary for `modify-frame-parameters' to behave like
 > `set-frame-size' with a non-nil (thus non-default) KEEP-SIZE argument, and wrong
 > for `modify-frame-parameters' to behave like `set-frame-size' with a nil (thus
 > default) KEEP-SIZE argument?

Because it incredibly complicates the implementation of setting a font
on a specific frame.  With emacs 24.3 we conceptually

(1) set the font which changes the appearance of text within the frame
     and the number of pixels used for the display margins,

(2) set the frame size proportionally to the font and rounded which may
     cause resizing the frame,

(3) set the sizes of fringes proportionally to the font and rounded
     which may cause another resizing of the frame, and

(4) set the sizes of the scrollbars proportionally to the font and
     rounded which may cause yet another resizing of the frame.

Now I think that all these steps are really useful to get a nice frame,
after all, a large font does look bad with narrow scrollbars and tiny
fringes.  But the problem is that these steps must be implemented via
recursive calls to `modify-frame-parameters'.  And these cause
conflicts, for example, when a user also issues a request to set the
size of the frame in the same `modify-frame-parameters' call that
changes the font or a request to maximize the frame.

So I think that a separate function should be provided to do such frame
zooming in a pretty and obviously pixelwise fashion where a user should
be also allowed to specify things like a sizing factor (which allows to
resize the frame more/less agressively wrt the font change) and some
upper and lower bounds which guarantee for example that the frame never
exceeds the size of the screen and/or obscurs the taskbar and a separate
options which allows to zoom only text or images as well.

 >> When you change the frame size you have to contact your window
 >> manager, wait till it gets back to you, and then you have to
 >> fit all your objects into the space alloted by the window manager.
 >> Now, obviously you have to do all these things also when you just
 >> resize the frame.  But in that case you didn't change the font.
 >> Or if you did, you did it without intending to change the frame
 >> size with it.
 >
 > I cannot speak to the implementation concerns.  I'm speaking in user terms.

My concerns are implementation concerns only.  We're asking too much
from that function `modify-frame-parameters'

 > For the kind of zooming I'm talking about, either zooming larger would no longer
 > be available once the maximum size is reached or it would be available beyond
 > the "maximum", which is really just the screen size.  The latter is the case
 > today, BTW: you can zoom a frame larger than the screen.

Which is useless IMO.

 > In the end, you will probably do what you're suggesting, and I will probably end
 > up using `set-frame-font' instead of `modify-frame-parameters' to continue to
 > get the effect I want.  (For Emacs 20 & 21 there was no KEEP-SIZE parameter, so
 > I'll need to use `modify-frame-parameters' for those cases.)

I now think we need a more intelligent function than `set-frame-font'
much like the one I sketched above.

 > For example, when zooming a frame (which for me, again, means shrinking both its
 > content and its size), if it contains images then I would want to be able to
 > shrink the images as well (modulo losing resolution, of course), in such a way
 > that what appears in the frame remains essentially the same (unlike the case of
 > a web browser, for example).

A user must be able to choose between text-based zooming and
text+image-based zooming.  But I have no idea how image positions
correlate to text positions so I don't know how zooming affects the
relative positions of text mixed with images.

 >> Are you sure?  What if toolbars have accompanying text?
 >
 > I meant the toolbar images.

Some toolbars can have accompanying text and that text is AFAICT subject
to frame font changes.

 >>  > Changing the frame `font' size zooms only the text.
 >>
 >> Not here.
 >
 > For me, on MS Windows, changing option `tool-bar-style' to include text has no
 > effect: I never see any text, just images.  And the doc string says this:
 >
 >   This variable only affects the GTK+ toolkit version of Emacs.

So the font changing code has to handle that.

 > OK.  But my concern is that we not lose something that users have today.  Wrt
 > font zooming also zooming frame size, I guess we won't lose, since we can use
 > `set-frame-font' with nil `KEEP-SIZE'.

Which as you said should be probably fixed.  But I still find it better
to rewrite such a function from scratch.

martin