unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* wanted: someone to integrate frame-resizing code
@ 2004-05-28 21:10 Drew Adams
  2004-05-28 22:08 ` Stefan Monnier
  0 siblings, 1 reply; 5+ messages in thread
From: Drew Adams @ 2004-05-28 21:10 UTC (permalink / raw)


RMS suggested I provide emacs-devel a summary of our conclusions regarding
some code I wrote to resize frames, and ask if there is anyone who would be
willing to integrate it (I do not have the resources to do that). I've
tested the code in Emacs 20 and 21.3.50 on Windows.

The code is especially useful when pop-up-frames is non-nil; that is, when
you use frames instead of Emacs windows by default. The code is here:

 - http://www.emacswiki.org/elisp/shrink-fit.el - a command,
shrink-frame-to-fit, that fits a frame to its selected window (should
probably be renamed resize-frame)

 - http://www.emacswiki.org/elisp/shrink-fit-all.el - provides automatic
frame resizing when appropriate

There are user variables to turn resizing on & off. Automatic resizing
applies only to one-window frames (the selected window is one-window-p).

Requirements -

  * Frames should be automatically resized:

    - When you create a new frame for a buffer.

    - When you read a different buffer into a frame.

    - When you display a buffer whose contents have changed since last
display.
      For instance, when a *Help* frame is raised, you want it to be the
right size each time.

  * Frames should *not* be automatically resized:

    - When the frame's buffer and its contents have not changed since last
display.
      This is the case, for instance, for *Occur* when the source buffer
doesn't change and you just redisplay it to access a different source line.

    - When a buffer is displayed before it has been filled.
      This is the case, for instance, for output buffers like *grep*.

Ideally, the code logic would follow these requirements exactly. My code is
not so sophisticated. If someone integrates the code it would be good to
consider a smarter implementation.

I simply added frame resizing to each of the basic display functions
(display-buffer, pop-to-buffer, switch-to-buffer). Without other changes
elsewhere this doesn't take into account the two requirements of *not*
resizing when inappropriate.

For instance, occur-* commands call pop-to-buffer, and if the user already
manually sized the source-code buffer (and wants it to stay put), resizing
it automatically would be annoying. Similarly, in compile, you want to
resize the frame explicitly after the buffer is full, not prematurely when
display-buffer is called on an empty output buffer.

The way I dealt with this was essentially a hack: In those places where
resizing would be inappropriate, I set a variable that inhibited resizing in
the basic display functions like pop-to-buffer. This is equivalent to having
two versions of each display function like pop-to-buffer, one that resizes
and one that doesn't, and calling the right one (analogy:
find-file-no-select vs find-file).

In practice, I only found two places where I needed to inhibit automatic
resizing: compile-internal and occur. However, I did not test exhaustively
with Emacs 21; there are perhaps other places where resizing should not be
done. I've used this with Emacs 20 for years with no inconvenience, but I
don't use all of Emacs.

For a more sophisticated solution, perhaps it would be possible to detect
(in resize-frame) whether or not the buffer had changed (either a different
buffer or changed content) since the last resizing of that frame (no matter
how it was resized: by the user or by program).

If someone decides to take this up, feel free to contact me with questions.
If no one has the time or interest to take up the automatic resizing,
consider at least adding command resize-frame to Emacs
(http://www.emacswiki.org/elisp/shrink-fit.el).

Thanks

  Drew

P.S. For more info:
http://www.emacswiki.org/cgi-bin/wiki/Shrink-Wrapping_Frames

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: wanted: someone to integrate frame-resizing code
  2004-05-28 21:10 wanted: someone to integrate frame-resizing code Drew Adams
@ 2004-05-28 22:08 ` Stefan Monnier
  2004-05-29  1:21   ` Drew Adams
  0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2004-05-28 22:08 UTC (permalink / raw)
  Cc: emacs-devel


I have no time to look into that and I'd rather wait for after-21.4 to
integrate any such functionality.  In any case, I do use a setup whee this
would be useful, so here are my comments:

- if special-display-buffer-names or special-display-regexp specifies
  specific sizes, it should still be obeyed.

- resizing existing frames is risky: you want to make sure you don't undo
  what the user did manually.  So I'd refrain from doing it except for
  frames where the user specifically asked for it.  Maybe you could allow
  resizing existing frames when they get deiconified, but even that sounds
  risky.

- resizing frames showing the content of a file is probably not
  a great idea.  More generally, if the elisp code doesn't call
  shrink-window-if-larger-than-buffer, it's likely that the frame's size
  shouldn't be changed either.

- don't enlarge the frame to be larger than the user's screen (which might
  be significantly smaller than what x-display-pixel-height claims).


        Stefan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: wanted: someone to integrate frame-resizing code
  2004-05-28 22:08 ` Stefan Monnier
@ 2004-05-29  1:21   ` Drew Adams
  2004-05-30 21:11     ` Stefan Monnier
  0 siblings, 1 reply; 5+ messages in thread
From: Drew Adams @ 2004-05-29  1:21 UTC (permalink / raw)
  Cc: emacs-devel

Stefan wrote:

 > - if special-display-buffer-names or special-display-regexp specifies
 >   specific sizes, it should still be obeyed.

Absolutely. There are several ways this can be done, depending on how the
automatic resizing is implemented.

If the built-in display functions (display-buffer etc.) do the automatic
resizing (my implementation), users can just make sure their
special-display-function (or the function in the
special-display-buffer-names arg) inhibits resizing (a la inhibit-read-only)
when calling display-buffer or whatever.

Or, if we provide separate no-resize versions of the display functions (a la
find-file-noselect), users can just make sure to call one of those.

BTW, the same consideration holds for any other code that resizes a frame to
a specific size. There is nothing special here about "special". :)


 > - resizing existing frames is risky: you want to make sure you don't undo
 >   what the user did manually.  So I'd refrain from doing it except for
 >   frames where the user specifically asked for it.

Yes, we must not undo what the user did. No, resizing existing frames is not
"risky" - we just need to do it only when appropriate, and not step on the
user.

Even using my simple implementation, I never encountered a problem as a
user: automatic resizing only takes place when the buffer is displayed (e.g.
display-buffer), so it's not done after you resize a frame manually.

Again, there were a couple corner cases where I had to ensure there was no
resizing upon display: compile and occur are the only ones I encountered,
but there may be others. (I did this just by locally binding an inhibit
variable around the call to display-buffer.)

A sophisticated implementation that corresponds exactly to the requirements
I listed previously might be ideal. But even my simple solution is
preferable (IMO) to restricting users to on-demand resizing. I've used
automatic resizing for years, and never had it conflict with manual
resizing.

And of course, users can turn automatic resizing off. And it doesn't affect
frames with more than one window (resize-frame, as a command, can be used in
multi-window frames: the selected-window is determinant).


 >   Maybe you could allow resizing existing frames when they get
deiconified,
 >   but even that sounds risky.

No, just the opposite. We do *not* want to resize a frame when it is
deiconified. A user should be able to manually size a frame, iconify it, do
some stuff, and deiconify it to exactly the same position and size. We want
to automatically resize a frame only when it is displayed.


 > - resizing frames showing the content of a file is probably not a great
idea.

Reason?

Automatic resizing is just as handy for file buffers. You never see
wrapped-around or truncated text, and you save a lot of manual fiddling,
resizing frames (you can still fiddle, if you want). If I'm editing a short,
narrow buffer and I switch to a longer, wider buffer, I want the frame to be
the right size for the latter. It doesn't matter whether or not a buffer is
associated with a file.

Try it. Ce n'est pas le fil a couper le beurre, mais c'est utile.

BTW, since there is some discussion about word-wrapping lately - We could
choose to make the resizing-inhibit variable buffer-local and inhibit
resizing in long-line, word-wrapping modes.


 >   More generally, if the elisp code doesn't call
 >   shrink-window-if-larger-than-buffer, it's likely that the frame's size
 >   shouldn't be changed either.

Not sure I follow you. This has nothing to do with resizing windows.
Automatic frame resizing is done only when the selected window is alone in
the frame (one-window-p). Whether code resizes windows or not is not
pertinent to what should happen when each window is in its own frame. It's a
different UI model.


 > - don't enlarge the frame to be larger than the user's screen (which
might
 >   be significantly smaller than what x-display-pixel-height claims).

The doc string of command shrink-frame-to-fit (resize-frame) explains the
algorithm.

There is a (user-definable) maximum frame height and width. By default,
these limits are calculated relative to the display size and the frame's
character size (based on user-definable max percentages). They can also be
specified absolutely.

There is also a (user-definable) minimum frame height and width for new
non-empty frames.

There is also a (user-definable) minimum frame height and width for new
empty frames. In fact, there are two: one for normal empty frames and one
for special empty frames (default, if no special-frame-function).

The only problem I've had with using x-display-pixel-height/width is when I
run Emacs on a different machine than my display - for instance, if I run
Emacs on a workstation (with a large display), and access it from a laptop
(with a small display). In that case, I just impose an absolute max size,
based on my target display size. I know of no way for Emacs to figure out
what the remote display I'm using is like. If there is a way, we should use
it.

Are there other circumstances where screen size can be "significantly
smaller" than the display? I'm not aware of a better measure of display size
in pixels than x-display-pixel-height/width. If there is one, that should be
used instead.


BTW - I mentioned too, in an earlier mail, that I have not tried this code
with images or a mixture of font sizes. Perhaps some adjustment will be
necessary to accomodate these. The current resizing code uses
set-frame-size. It counts lines and measures maximum line-width (in
characters) to determine the needed frame height (lines) and width (cols).

 - Drew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: wanted: someone to integrate frame-resizing code
  2004-05-29  1:21   ` Drew Adams
@ 2004-05-30 21:11     ` Stefan Monnier
  2004-06-01  0:34       ` automatic frame-resizing Drew Adams
  0 siblings, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2004-05-30 21:11 UTC (permalink / raw)
  Cc: emacs-devel

> Even using my simple implementation, I never encountered a problem as a
> user: automatic resizing only takes place when the buffer is displayed (e.g.
> display-buffer), so it's not done after you resize a frame manually.

I regularly (tho not often) do C-x 5  f <somefile> where <somefile> is
already in an open frame.  This basically has the effect of raising that
frame and it should not resize it (even tho it does get "displayed" in the
sense that pop-to-buffer is called on it).
[ I don't distinguish between pop-to-buffer and display-buffer here. ]

>> Maybe you could allow resizing existing frames when they get deiconified,
>> but even that sounds risky.

> No, just the opposite. We do *not* want to resize a frame when it is
> deiconified. A user should be able to manually size a frame, iconify it, do
> some stuff, and deiconify it to exactly the same position and size.  We want
> to automatically resize a frame only when it is displayed.

I meant "deiconified by pop-to-buffer", not manually of course.
[ I don't like to use "displayed" since it doesn't mean anything precise. ]

>> - resizing frames showing the content of a file is probably not a great idea.
> Reason?

None other than my gut feeling.

> Automatic resizing is just as handy for file buffers.

Of course it's true that it's not uncommon to open a file just to look at
it, but if not, a short frame might just turn out inconvenient as soon as
I start adding text to the file.

> You never see wrapped-around or truncated text, and you save a lot of
> manual fiddling, resizing frames (you can still fiddle, if you want).

I never fiddle with the horizontal size of file buffers: if text gets
wrapped around, I want to fix the text, not the frame.

> If I'm editing a short, narrow buffer and I switch to a longer, wider
> buffer, I want the frame to be the right size for the latter.

All my file frames are vertically maximized (and 80 columns).
[ And I virtually never switch buffers in a frame. ]

> It doesn't matter whether or not a buffer is associated with a file.

Could be.  I just know that I currently manage the two very differently,
mostly because I use the two kinds of buffers very differently: in file
buffers, I edit, I move around, etc, whereas in non-file buffers
I generally don't do much more than click on a few things.

>> More generally, if the elisp code doesn't call
>> shrink-window-if-larger-than-buffer, it's likely that the frame's size
>> shouldn't be changed either.

> Not sure I follow you.  This has nothing to do with resizing windows.

Why not?  shrink-window-if-larger-than-buffer is basically the same as you
code, if you consider that it's typically used for single-frame Emacs
instances where Emacs manages all the windows whereas your code works for
multi-frame Emacs instances where the window manager manages the windows
(indirectly by managing the frames).

> Automatic frame resizing is done only when the selected window is alone in
> the frame (one-window-p).  Whether code resizes windows or not is not
> pertinent to what should happen when each window is in its own frame.
> It's a different UI model.

I don't find it very different: Emacs's windows don't overlap, but
otherwise it's pretty similar.

> Are there other circumstances where screen size can be "significantly
> smaller" than the display?

When I connect my 1280x1024 external monitor to my 1024x768 laptop, I get
a virtual screen of 1304x1024 or 1280x1792 pixels (where some are
non-displayed, some are displayed on the laptop's screen and the rest is on
the external monitor).

> I'm not aware of a better measure of display size in pixels than
> x-display-pixel-height/width.

Neither am I.

The above email is not a comment about your code.  It's just some comments
based on my own use pattern.  I don't claim it has any kind of
representative quality.


        Stefan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* automatic frame-resizing
  2004-05-30 21:11     ` Stefan Monnier
@ 2004-06-01  0:34       ` Drew Adams
  0 siblings, 0 replies; 5+ messages in thread
From: Drew Adams @ 2004-06-01  0:34 UTC (permalink / raw)
  Cc: emacs-devel


 > I regularly (tho not often) do C-x 5  f <somefile> where <somefile> is
 > already in an open frame.  This basically has the effect of raising that
 > frame and it should not resize it

Stefan, your point on not resizing existing frames when raising them by
function is a valid one - I agree 100%.

If automatic frame resizing is added to Emacs, then simply raising an
existing frame (whether iconified, invisible, or already raised) should not
by itself trigger resizing. Resizing should only happen when the buffer in
the frame changes (different buffer or different contents for the same
buffer).

It is not necessary to adopt the sort of implementation of automatic frame
resizing I used, but *if* an implementation is done along those lines (that
is, if the resizing is done in display-buffer and switch-to-buffer), then it
is necessary to modify the C code for display-buffer and switch-to-buffer:
If an existing frame is simply being raised, then do not resize it.

(Pop-to-buffer, switch-to-buffer-other-frame, and
switch-to-buffer-other-window are taken care of by display-buffer;
switch-to-buffer does not use display-buffer, so it needs to be modified
separately.)

I did not try to change any C code: my implementation is a simple Lisp
hack/workaround. I just called the built-in functions from Lisp, doing a
resize-frame afterward (if one-window-p).  I don't know of any way in Lisp
to determine whether an existing frame was in fact reused by display-buffer
or switch-to-buffer. I do at least inhibit resizing in switch-to-buffer
(same frame) in the case where the original buffer and the new buffer are
the same.

So, my code does in fact step on the user by resizing upon programmatic
frame-raise and other pop-to-buffer calls like find-file. Given that I could
not change the C code, I preferred this to giving up automatic resizing for
things like find-file.

For the rest of your remarks - I don't want to belabor this. I already
mentioned that my implementation is a simple one, not ideal. I listed what I
think are the requirements for a more exact solution. I argued for adding
the functionality of automatic frame resizing, not my implementation of
that. (I also argued that my command to resize a frame could be added more
or less as is, independently of any automatic resizing.)

It sounds like your file editing is a special case, though perhaps not
uncommon: you apparently edit mainly files with the same (max) line width,
so you just use an appropriate constant frame width. In general, though,
there are lots of kinds of file, with different (max) line widths or
fill-columns. I believe that it makes as much sense to shrink-wrap a file
frame as a dired, help, info, or any other frame. (And you can always impose
a constant frame width for your file editing, if you like.)

Regarding your concern that a short file frame might be inconvenient for
appending to: a user can establish a minimum frame height in several ways.
You can use the same value you now use for your file frames, if you like.

Thanks,

   Drew

P.S. I simplified some of my code (and renamed shrink-* to resize-*); here
it is:

 - http://www.emacswiki.org/elisp/auto-resize-frames.el
 - http://www.emacswiki.org/elisp/resize-frame.el

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-06-01  0:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-28 21:10 wanted: someone to integrate frame-resizing code Drew Adams
2004-05-28 22:08 ` Stefan Monnier
2004-05-29  1:21   ` Drew Adams
2004-05-30 21:11     ` Stefan Monnier
2004-06-01  0:34       ` automatic frame-resizing Drew Adams

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).