unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* moving window handling into lisp
@ 2009-07-27  8:32 Miles Bader
  2009-07-27 13:37 ` martin rudalics
       [not found] ` <4A87F8B8.6050102@gmx.at>
  0 siblings, 2 replies; 130+ messages in thread
From: Miles Bader @ 2009-07-27  8:32 UTC (permalink / raw)
  To: emacs-devel

I'm kind of confused by what exactly is going to happen with windows
(multiple competing vaguely-not-satisfying-and-confusing-at-least-
to-my-simple-brain proposals...), but my impression is that it's
desirable to have as much in lisp as possible.

[I apologize if some of what I say below duplicates what's been said
before; I often start zoning out when reading these long threads, and
miss stuff!]

The general approach I've always kind of assumed would be followed by
any extension of window handling in emacs has a very simple basis (at
least it _sounds_ simple :):

** Expose the (existing) window tree to lisp

Basically keep the same window objects we have today, but allow lisp
to get a handle on non-leaf window objects (today, AFAICT, lisp can
only ever see leaf windows).

Together with some low-level accessor/modifier functions, e.g. maybe:

   frame-root-window FRAME      => ROOT-WIN
   window-children WINDOW       => (LEFT-CHILD-WIN . RIGHT-CHILD-WIN)
   window-parent WINDOW         => PARENT-WIN
   set-window-children WINDOW LEFT-CHILD-WIN RIGHT-CHILD-WIN
   (etc)

A brief look suggests that much of the traditional window handling
code (`window-list', `other-window', `split-window', `delete-window',
`delete-other-windows', etc) could then be moved into lisp; none of
that code looks very complicated or dangerous.

With traditional user-level window handling functions in lisp,
exploring various higher level window frameworks/abstractions seems to
be easier.

Of course the basic assumption is that what we really want is to make
existing lisp windows a bit more malleable, rather than an entirely
new infrastructure.


** Extending window handling

As a separate layer on top of the above, my vague thinking is that the
various fancy behaviors desired for things like ECB could be
implemented as essentially hooks and window-properties etc that affect
the typical user-level window functions (which are now lisp).

For instance (these are simply rough ideas!):

 * A window-property which says "treat this window as the window root for
   purposes of C-x 1, C-x o, etc".  Note that the new low-level primitive
   functions (which I listed above) _wouldn't_ be affected, and any lisp
   code that wants to see the raw tree, can do so.

 * A window property that says (somehow, not sure of the exact form)
   "When looking for a window leaf (C-x 0, C-x o, etc), use <parent
   window X> instead".

 * A buffer-local hook which gets run after setting a window's buffer to
   that buffer.  (I guess window-configuration-change-hook covers this to
   some degree, but it can be annoying to use)

[The first two properties probably would need some means of specifying
different behaviors for different operations -- what you want to
consider a "leaf" might be different depending on whether the user is
moving amongst windows or deleting them.]

Anyway, those are my vague ideas.  I hope I'm not simply adding to the
confusion...


-miles

-- 
Advice, n. The smallest current coin.




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

* Re: moving window handling into lisp
  2009-07-27  8:32 moving window handling into lisp Miles Bader
@ 2009-07-27 13:37 ` martin rudalics
  2009-07-27 13:41   ` Lennart Borgman
  2009-07-27 14:00   ` Miles Bader
       [not found] ` <4A87F8B8.6050102@gmx.at>
  1 sibling, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-07-27 13:37 UTC (permalink / raw)
  To: Miles Bader; +Cc: emacs-devel

 > Basically keep the same window objects we have today, but allow lisp
 > to get a handle on non-leaf window objects (today, AFAICT, lisp can
 > only ever see leaf windows).

Elisp can "see" all internal windows.  Making internal windows more
accessible was the idea underlying my proposal.

 >    window-children WINDOW       => (LEFT-CHILD-WIN . RIGHT-CHILD-WIN)

An internal window can have more than two children (for no good reason,
BTW).

 >    window-parent WINDOW         => PARENT-WIN
 >    set-window-children WINDOW LEFT-CHILD-WIN RIGHT-CHILD-WIN

`window-parent' and `window-children' would be trivial.  Providing
`set-window-children' is hardly feasible IMHO.  Who'd be responsible for
calculating the respective sizes?

 >    (etc)
 >
 > A brief look suggests that much of the traditional window handling
 > code (`window-list', `other-window', `split-window', `delete-window',
 > `delete-other-windows', etc) could then be moved into lisp; none of
 > that code looks very complicated or dangerous.

The problem with `split-window' and `delete-window' is that you can
easily mess up things when you create windows that don't have the right
size.  From my experience this usually makes Emacs crash pretty soon and
we shouldn't allow Elisp code crash Emacs.  OTOH doing all the necessary
checks wrt window sizes in `set-window-children' would mean hard work.
It would be fine to see such code though since we could use it to safely
store window configurations on disk in a non-procedural manner.

martin, whose `switch-to-buffer' is in window.el




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

* Re: moving window handling into lisp
  2009-07-27 13:37 ` martin rudalics
@ 2009-07-27 13:41   ` Lennart Borgman
  2009-07-27 13:45     ` martin rudalics
  2009-07-27 14:00   ` Miles Bader
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-27 13:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Miles Bader

On Mon, Jul 27, 2009 at 3:37 PM, martin rudalics<rudalics@gmx.at> wrote:

> It would be fine to see such code though since we could use it to safely
> store window configurations on disk in a non-procedural manner.


What do you mean? Is not the code in winsav.el non-procedural enough?




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

* Re: moving window handling into lisp
  2009-07-27 13:41   ` Lennart Borgman
@ 2009-07-27 13:45     ` martin rudalics
  2009-07-27 13:58       ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-27 13:45 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel, Miles Bader

> What do you mean? Is not the code in winsav.el non-procedural enough?

IIRC you're using `split-window' recursively to restore configurations.

martin




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

* Re: moving window handling into lisp
  2009-07-27 13:45     ` martin rudalics
@ 2009-07-27 13:58       ` Lennart Borgman
  2009-07-27 14:35         ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-27 13:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Miles Bader

On Mon, Jul 27, 2009 at 3:45 PM, martin rudalics<rudalics@gmx.at> wrote:
>> What do you mean? Is not the code in winsav.el non-procedural enough?
>
> IIRC you're using `split-window' recursively to restore configurations.


I see. Yes, it would be nice to avoid that. But is that really that
difficult? I mean you calculate the sizes of all direct children and
then you create them. What is the problem with that? (Sorry, I just
don't understand.)

In winsav.el the problem is that you can't be sure what size the
windows get so you have to iterate and do some strange things to get
back the original (relative) sizes). But is not that more easy to do
if you can create the sizes and adjust them before creating the child
windows?




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

* Re: moving window handling into lisp
  2009-07-27 13:37 ` martin rudalics
  2009-07-27 13:41   ` Lennart Borgman
@ 2009-07-27 14:00   ` Miles Bader
  2009-07-27 14:36     ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Miles Bader @ 2009-07-27 14:00 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:
>>    window-parent WINDOW         => PARENT-WIN
>>    set-window-children WINDOW LEFT-CHILD-WIN RIGHT-CHILD-WIN
>
> `window-parent' and `window-children' would be trivial.  Providing
> `set-window-children' is hardly feasible IMHO.  Who'd be responsible for
> calculating the respective sizes?

Currently split-window does, and that doesn't seem particularly
complicated.

Certainly set-window-children has to do a fair bit of sanity checking,
but it's not going to be any greater than that currently done by
split-window, and that function isn't all that complicated.

>> A brief look suggests that much of the traditional window handling
>> code (`window-list', `other-window', `split-window', `delete-window',
>> `delete-other-windows', etc) could then be moved into lisp; none of
>> that code looks very complicated or dangerous.
>
> The problem with `split-window' and `delete-window' is that you can
> easily mess up things when you create windows that don't have the right
> size.  From my experience this usually makes Emacs crash pretty soon and
> we shouldn't allow Elisp code crash Emacs.  OTOH doing all the necessary
> checks wrt window sizes in `set-window-children' would mean hard work.

Hmm, I dunno why it's hard -- just copy the appropriate bits from split-window.

Maybe set-window-children would end up being mostly sanity-checking
code, but that's OK -- it'll probably be smaller than split-window, and
will serve as a nice low-level interface.

> martin, whose `switch-to-buffer' is in window.el

Wait... switch-to-buffer is in C...

-Miles

-- 
Generous, adj. Originally this word meant noble by birth and was rightly
applied to a great multitude of persons. It now means noble by nature and is
taking a bit of a rest.




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

* Re: moving window handling into lisp
  2009-07-27 13:58       ` Lennart Borgman
@ 2009-07-27 14:35         ` martin rudalics
  2009-07-27 14:41           ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-27 14:35 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Miles Bader, emacs-devel

 > I see. Yes, it would be nice to avoid that. But is that really that
 > difficult? I mean you calculate the sizes of all direct children and
 > then you create them. What is the problem with that? (Sorry, I just
 > don't understand.)

It's not transparent, that is, it depends on the order how things are
done.  You can set window attributes like `window-size-fixed' only after
splitting.  You have to bind `window-min-height' and `window-min-width'
around the splitting code.  `set-window-configuration' is much simpler
in this regard.

 > In winsav.el the problem is that you can't be sure what size the
 > windows get so you have to iterate and do some strange things to get
 > back the original (relative) sizes). But is not that more easy to do
 > if you can create the sizes and adjust them before creating the child
 > windows?

I suppose we agree that it's much simpler when we can set the window
sizes directly (and apply any frame resizing afterwards).

martin




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

* Re: moving window handling into lisp
  2009-07-27 14:00   ` Miles Bader
@ 2009-07-27 14:36     ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-07-27 14:36 UTC (permalink / raw)
  To: Miles Bader; +Cc: emacs-devel

 >> `window-parent' and `window-children' would be trivial.  Providing
 >> `set-window-children' is hardly feasible IMHO.  Who'd be responsible for
 >> calculating the respective sizes?
 >
 > Currently split-window does, and that doesn't seem particularly
 > complicated.

Because it doesn't split internal windows.  Anyway `enlarge-window' and
`delete-window' which eventually wind up calling size_window are more
complicated.

 > Certainly set-window-children has to do a fair bit of sanity checking,
 > but it's not going to be any greater than that currently done by
 > split-window, and that function isn't all that complicated.

`set-window-children' with arguments nil?

 > Hmm, I dunno why it's hard -- just copy the appropriate bits from split-window.

Anything that doesn't resize other windows is easy.  Everything that
does is complicated.  Believe me, there's a couple of bugs in the C code
implementing resizing.

 > Maybe set-window-children would end up being mostly sanity-checking
 > code, but that's OK -- it'll probably be smaller than split-window, and
 > will serve as a nice low-level interface.

Obviously, if you leave the size-handling code in C.

 >> martin, whose `switch-to-buffer' is in window.el
 >
 > Wait... switch-to-buffer is in C...

Not mine ;-)

martin




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

* Re: moving window handling into lisp
  2009-07-27 14:35         ` martin rudalics
@ 2009-07-27 14:41           ` Lennart Borgman
  2009-07-27 15:02             ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-27 14:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: Miles Bader, emacs-devel

On Mon, Jul 27, 2009 at 4:35 PM, martin rudalics<rudalics@gmx.at> wrote:
>> I see. Yes, it would be nice to avoid that. But is that really that
>> difficult? I mean you calculate the sizes of all direct children and
>> then you create them. What is the problem with that? (Sorry, I just
>> don't understand.)
>
> It's not transparent, that is, it depends on the order how things are
> done.  You can set window attributes like `window-size-fixed' only after
> splitting.

That sounds like a real problem. Can't that be moved?


> You have to bind `window-min-height' and `window-min-width'
> around the splitting code.

Is that a problem?


> `set-window-configuration' is much simpler
> in this regard.
>
>> In winsav.el the problem is that you can't be sure what size the
>> windows get so you have to iterate and do some strange things to get
>> back the original (relative) sizes). But is not that more easy to do
>> if you can create the sizes and adjust them before creating the child
>> windows?
>
> I suppose we agree that it's much simpler when we can set the window
> sizes directly (and apply any frame resizing afterwards).

Hm, maybe ... ;-)

I do not understand how you mean. But yes, if the sizes can be kept
(or interpreted) as relative sizes when doing frame resizing.


> martin
>




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

* Re: moving window handling into lisp
  2009-07-27 14:41           ` Lennart Borgman
@ 2009-07-27 15:02             ` martin rudalics
  2009-07-27 15:28               ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-27 15:02 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Miles Bader, emacs-devel

 >> It's not transparent, that is, it depends on the order how things are
 >> done.  You can set window attributes like `window-size-fixed' only after
 >> splitting.
 >
 > That sounds like a real problem. Can't that be moved?

It's not a real problem, in particular if this attribute doesn't apply
to internal windows.  You can also, for example, have `split-window'
ignore the fixed-sizeness of windows.  But it's one of the things you
have to take care of.

 >> You have to bind `window-min-height' and `window-min-width'
 >> around the splitting code.
 >
 > Is that a problem?

No.  Just another thing you have to take care of.  The sizes of windows
you see in a saved window configuration are not necessarily the sizes
resulting exclusively from applications of `split-window'.

 >> I suppose we agree that it's much simpler when we can set the window
 >> sizes directly (and apply any frame resizing afterwards).
 >
 > Hm, maybe ... ;-)
 >
 > I do not understand how you mean. But yes, if the sizes can be kept
 > (or interpreted) as relative sizes when doing frame resizing.

I mean that you first have to build the new window tree with the stored
sizes.  If the size of the target frame (or window) differs from that of
the source frame (window) you have to resize the windows in the target
(a process which is certainly not guaranteed to keep relative sizes and,
in the worst case, may even delete windows).

martin




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

* Re: moving window handling into lisp
  2009-07-27 15:02             ` martin rudalics
@ 2009-07-27 15:28               ` Lennart Borgman
  2009-07-27 16:52                 ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-27 15:28 UTC (permalink / raw)
  To: martin rudalics; +Cc: Miles Bader, emacs-devel

On Mon, Jul 27, 2009 at 5:02 PM, martin rudalics<rudalics@gmx.at> wrote:

>>> I suppose we agree that it's much simpler when we can set the window
>>> sizes directly (and apply any frame resizing afterwards).
>>
>> Hm, maybe ... ;-)
>>
>> I do not understand how you mean. But yes, if the sizes can be kept
>> (or interpreted) as relative sizes when doing frame resizing.
>
> I mean that you first have to build the new window tree with the stored
> sizes.  If the size of the target frame (or window) differs from that of
> the source frame (window) you have to resize the windows in the target
> (a process which is certainly not guaranteed to keep relative sizes and,
> in the worst case, may even delete windows).


What I mean is that maybe you have more freedom there when you do this
internally. Can't you for example calculate the sizes going down the
tree before actually applying them to the windows? Can't you this way
calculate all the sizes before applying them? You may then of course
have to store them node by node by node, but there will be no
surprises when you apply them, or?




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

* Re: moving window handling into lisp
  2009-07-27 15:28               ` Lennart Borgman
@ 2009-07-27 16:52                 ` martin rudalics
  2009-07-27 16:58                   ` Lennart Borgman
  2009-07-27 18:18                   ` Stefan Monnier
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-07-27 16:52 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Miles Bader, emacs-devel

 > What I mean is that maybe you have more freedom there when you do this
 > internally. Can't you for example calculate the sizes going down the
 > tree before actually applying them to the windows? Can't you this way
 > calculate all the sizes before applying them? You may then of course
 > have to store them node by node by node, but there will be no
 > surprises when you apply them, or?

I don't know, I would have to code that first.  But I wonder why this
didn't occur to you and Stefan when you wrote your window balancing
routines.  You both ended up using `adjust-window-trailing-edge' ;-)

martin




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

* Re: moving window handling into lisp
  2009-07-27 16:52                 ` martin rudalics
@ 2009-07-27 16:58                   ` Lennart Borgman
  2009-07-27 18:18                   ` Stefan Monnier
  1 sibling, 0 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-07-27 16:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: Miles Bader, emacs-devel

On Mon, Jul 27, 2009 at 6:52 PM, martin rudalics<rudalics@gmx.at> wrote:
>> What I mean is that maybe you have more freedom there when you do this
>> internally. Can't you for example calculate the sizes going down the
>> tree before actually applying them to the windows? Can't you this way
>> calculate all the sizes before applying them? You may then of course
>> have to store them node by node by node, but there will be no
>> surprises when you apply them, or?
>
> I don't know, I would have to code that first.  But I wonder why this
> didn't occur to you and Stefan when you wrote your window balancing
> routines.  You both ended up using `adjust-window-trailing-edge' ;-)


It did, but there was not time and room to change the C code then ... ;-)




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

* Re: moving window handling into lisp
  2009-07-27 16:52                 ` martin rudalics
  2009-07-27 16:58                   ` Lennart Borgman
@ 2009-07-27 18:18                   ` Stefan Monnier
  2009-07-28  7:38                     ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-07-27 18:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Lennart Borgman, Miles Bader

>> What I mean is that maybe you have more freedom there when you do this
>> internally. Can't you for example calculate the sizes going down the
>> tree before actually applying them to the windows? Can't you this way
>> calculate all the sizes before applying them? You may then of course
>> have to store them node by node by node, but there will be no
>> surprises when you apply them, or?

> I don't know, I would have to code that first.  But I wonder why this
> didn't occur to you and Stefan when you wrote your window balancing
> routines.  You both ended up using `adjust-window-trailing-edge' ;-)

I know why it didn't occur to me:
- I specifically didn't want to use an algorithm like the one that was
  used in the past (when I wrote the code, which started a long time
  ago, before adjust-window-trailing-edge') nor like the one that's
  currently used.  I wanted an algorithm that's more declarative: you
  specify the goal, and the algorithm looks for it without you having to
  tell it how to do it.
- Even if you have the code to compute the desired shape of the tree, it's
  far from trivial to figure out how to go from the current tree shape to
  the goal tree shape without bumping into things like window-min-height
  and window-min-width on intermediate states.
  Actually most of the code in balance-windows-area was written
  specifically for that purpose while trying to fix the original
  balance-windows (which tended to delete windows in some cases for no
  apparent reason).  At some point along the way I figured that I could
  just as well "compute the goal along the way".


        Stefan





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

* Re: moving window handling into lisp
  2009-07-27 18:18                   ` Stefan Monnier
@ 2009-07-28  7:38                     ` martin rudalics
  2009-07-28  9:39                       ` Lennart Borgman
  2009-07-28 13:47                       ` Stefan Monnier
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-07-28  7:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Lennart Borgman, Miles Bader

 > - I specifically didn't want to use an algorithm like the one that was
 >   used in the past (when I wrote the code, which started a long time
 >   ago, before adjust-window-trailing-edge') nor like the one that's
 >   currently used.  I wanted an algorithm that's more declarative: you
 >   specify the goal, and the algorithm looks for it without you having to
 >   tell it how to do it.

As it stands, your algorithm depends on `adjust-window-trailing-edge'
DTRT though.

 > - Even if you have the code to compute the desired shape of the tree, it's
 >   far from trivial to figure out how to go from the current tree shape to
 >   the goal tree shape without bumping into things like window-min-height
 >   and window-min-width on intermediate states.

And fixed-size windows.  It's a pain.  Some combinations of desired
window configuration / frame sizes do not even have a solution at all
(just like putting footnotes on pages): You can't put a cretain window
into a frame because it won't fit due to some restrictions; so you
decide to delete it.  But if you delete it, the remaining windows won't
fit, so you put it back.

 >   Actually most of the code in balance-windows-area was written
 >   specifically for that purpose while trying to fix the original
 >   balance-windows (which tended to delete windows in some cases for no
 >   apparent reason).  At some point along the way I figured that I could
 >   just as well "compute the goal along the way".

martin




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

* Re: moving window handling into lisp
  2009-07-28  7:38                     ` martin rudalics
@ 2009-07-28  9:39                       ` Lennart Borgman
  2009-07-28 12:25                         ` martin rudalics
  2009-07-28 13:47                       ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-28  9:39 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Stefan Monnier, Miles Bader

On Tue, Jul 28, 2009 at 9:38 AM, martin rudalics<rudalics@gmx.at> wrote:
>
>> - Even if you have the code to compute the desired shape of the tree, it's
>>   far from trivial to figure out how to go from the current tree shape to
>>   the goal tree shape without bumping into things like window-min-height
>>   and window-min-width on intermediate states.
>
> And fixed-size windows.  It's a pain.  Some combinations of desired
> window configuration / frame sizes do not even have a solution at all
> (just like putting footnotes on pages): You can't put a cretain window
> into a frame because it won't fit due to some restrictions; so you
> decide to delete it.  But if you delete it, the remaining windows won't
> fit, so you put it back.


In the situation when you try to put back a window tree config into a
window/frame and there is no solution I guess the best would be to not
put anything back.




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

* Re: moving window handling into lisp
  2009-07-28  9:39                       ` Lennart Borgman
@ 2009-07-28 12:25                         ` martin rudalics
       [not found]                           ` <e01d8a50907280532kcff2d1w15567a430668a502@mail.gmail.com>
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-28 12:25 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel, Stefan Monnier, Miles Bader

 > In the situation when you try to put back a window tree config into a
 > window/frame and there is no solution I guess the best would be to not
 > put anything back.

There must be a solution, always.  When I rewrote `display-buffer' in
Elisp I allowed it to return nil in case it couldn't produce a suitable
window.  But we really never expect `display-buffer' to return nil.

martin




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

* Re: moving window handling into lisp
       [not found]                           ` <e01d8a50907280532kcff2d1w15567a430668a502@mail.gmail.com>
@ 2009-07-28 13:23                             ` martin rudalics
  2009-07-28 13:44                               ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-28 13:23 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel, Stefan Monnier, Miles Bader

 > I expect display-buffer to always to something useful. But I do not
 > expect that a saved window tree can always be put back (with all
 > windows there) in any window (ie if the size of the window is too
 > small).

What do you expect it to do when restoring a saved session?  IMHO it
should fail gracefully by trying to restore as much as possible.

martin




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

* Re: moving window handling into lisp
  2009-07-28 13:23                             ` martin rudalics
@ 2009-07-28 13:44                               ` Lennart Borgman
  2009-07-29  9:04                                 ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-07-28 13:44 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Stefan Monnier, Miles Bader

On Tue, Jul 28, 2009 at 3:23 PM, martin rudalics<rudalics@gmx.at> wrote:
>> I expect display-buffer to always to something useful. But I do not
>> expect that a saved window tree can always be put back (with all
>> windows there) in any window (ie if the size of the window is too
>> small).
>
> What do you expect it to do when restoring a saved session?  IMHO it
> should fail gracefully by trying to restore as much as possible.


Yes, it is difficult. But I found I wonder if restoring as much as
possible is the best strategy.

First, it is hard to define what it should mean. Second, if it instead
fail without restoring anything you can take actions like enlarging
the target window/frame and try again.




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

* Re: moving window handling into lisp
  2009-07-28  7:38                     ` martin rudalics
  2009-07-28  9:39                       ` Lennart Borgman
@ 2009-07-28 13:47                       ` Stefan Monnier
  2009-07-28 14:11                         ` Lennart Borgman
  2009-07-29  9:05                         ` martin rudalics
  1 sibling, 2 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-07-28 13:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Lennart Borgman, Miles Bader

>> - I specifically didn't want to use an algorithm like the one that was
>> used in the past (when I wrote the code, which started a long time
>> ago, before adjust-window-trailing-edge') nor like the one that's
>> currently used.  I wanted an algorithm that's more declarative: you
>> specify the goal, and the algorithm looks for it without you having to
>> tell it how to do it.
> As it stands, your algorithm depends on `adjust-window-trailing-edge'
> DTRT though.

Actually, it works better if adjust-window-trailing-edge DTRT, but it
should still work OK if adjust-window-trailing-edge doesn't quite do the
right thing (e.g. if it resizes by less then requested).

>> - Even if you have the code to compute the desired shape of the tree, it's
>> far from trivial to figure out how to go from the current tree shape to
>> the goal tree shape without bumping into things like window-min-height
>> and window-min-width on intermediate states.
> And fixed-size windows.  It's a pain.  Some combinations of desired
> window configuration / frame sizes do not even have a solution at all

I'm talking about something else: after having a found a solution
(i.e. you know exactly the size you want for of each window and it is
correct for the size of the frame), find a set of calls to
enlarge/shrink-window (or equivalent) that will bring you from the
current window configuration to the desired window configuration.

But yes, "finding a solution" is itself a difficult problem.


        Stefan




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

* Re: moving window handling into lisp
  2009-07-28 13:47                       ` Stefan Monnier
@ 2009-07-28 14:11                         ` Lennart Borgman
  2009-07-29  9:05                         ` martin rudalics
  1 sibling, 0 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-07-28 14:11 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel, Miles Bader

On Tue, Jul 28, 2009 at 3:47 PM, Stefan Monnier<monnier@iro.umontreal.ca> wrote:
>
> I'm talking about something else: after having a found a solution
> (i.e. you know exactly the size you want for of each window and it is
> correct for the size of the frame), find a set of calls to
> enlarge/shrink-window (or equivalent) that will bring you from the
> current window configuration to the desired window configuration.


Maybe the easiest way to do this is to write a new function that can
split the current window tree node in the desired number of child
windows and apply the sizes?

All the checks needed can be done before applying this function. (With
a bit code restructiring, of course...)


> But yes, "finding a solution" is itself a difficult problem.
>
>
>        Stefan
>




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

* Re: moving window handling into lisp
  2009-07-28 13:44                               ` Lennart Borgman
@ 2009-07-29  9:04                                 ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-07-29  9:04 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Miles Bader, Stefan Monnier, emacs-devel

 > Second, if it instead
 > fail without restoring anything you can take actions like enlarging
 > the target window/frame and try again.

But probably not when starting a session.  Maybe it should use the old
frame size instead.

martin




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

* Re: moving window handling into lisp
  2009-07-28 13:47                       ` Stefan Monnier
  2009-07-28 14:11                         ` Lennart Borgman
@ 2009-07-29  9:05                         ` martin rudalics
  2009-07-29 14:05                           ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-07-29  9:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, Lennart Borgman, Miles Bader

 > I'm talking about something else: after having a found a solution
 > (i.e. you know exactly the size you want for of each window and it is
 > correct for the size of the frame), find a set of calls to
 > enlarge/shrink-window (or equivalent) that will bring you from the
 > current window configuration to the desired window configuration.

Indeed.  Specifying a good interface for that seems tedious.  Something
like a function which accepts a list of all windows and their new sizes,
checks whether the sizes add up correctly, and applies them.

 > But yes, "finding a solution" is itself a difficult problem.

NP-complete, I suppose.  I always wondered whether there are
configurations where your code could produce a suboptimal solution by
stopping to early.

martin




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

* Re: moving window handling into lisp
  2009-07-29  9:05                         ` martin rudalics
@ 2009-07-29 14:05                           ` Stefan Monnier
  2009-08-01  2:20                             ` Miles Bader
  2009-08-11  9:18                             ` martin rudalics
  0 siblings, 2 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-07-29 14:05 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Lennart Borgman, Miles Bader

>> I'm talking about something else: after having a found a solution
>> (i.e. you know exactly the size you want for of each window and it is
>> correct for the size of the frame), find a set of calls to
>> enlarge/shrink-window (or equivalent) that will bring you from the
>> current window configuration to the desired window configuration.

> Indeed.  Specifying a good interface for that seems tedious.  Something
> like a function which accepts a list of all windows and their new sizes,
> checks whether the sizes add up correctly, and applies them.

Yes, that would be basically a set-window-configuration.
Another approach is to have a transactional interface, like
start-window-configuration and end-window-configuration:
- during the transaction, windows can be resized to too-large/too-small
  sizes (but maybe window-fixed-size should stil be obeyed?).
- if redisplay happens inbetween, it's an error, and the resulting display
  will be blank.

>> But yes, "finding a solution" is itself a difficult problem.
> NP-complete, I suppose.  I always wondered whether there are
> configurations where your code could produce a suboptimal solution by
> stopping to early.

If you let my code run longer, you'll see that it often cycles between
a few different configurations, but as far as I've been able to tell,
those are very similar: it's just a matter of off-by-one
issues, usually.  Still, there are corner cases where it oscillates
a lot more.  This is why I put an upper bound rather than "loop until it
settles".


        Stefan




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

* Re: moving window handling into lisp
  2009-07-29 14:05                           ` Stefan Monnier
@ 2009-08-01  2:20                             ` Miles Bader
  2009-08-03 21:29                               ` Stefan Monnier
  2009-08-11  9:18                             ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Miles Bader @ 2009-08-01  2:20 UTC (permalink / raw)
  To: Stefan Monnier, Chong Yidong; +Cc: emacs-devel

So can you say whether, as maintainers, you support this goal, or should
I just go away?

This:
  (1) exposing non-leaf windows to lisp
  (2) making the C window functions more "primitive", and moving all the
      "user level" functions to lisp

I think it could be done very incrementally, and would enable easier
exploration of higher-level frameworks in lisp.

[Otherwise, what _are_ the maintainer's positions w/r/t window handling?
What I've seen discussed on this list just seems a huge hairy mess, but
there's very little obvious direction coming from above.]

-Miles

-- 
`Life is a boundless sea of bitterness'




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

* Re: moving window handling into lisp
  2009-08-01  2:20                             ` Miles Bader
@ 2009-08-03 21:29                               ` Stefan Monnier
  0 siblings, 0 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-03 21:29 UTC (permalink / raw)
  To: Miles Bader; +Cc: Chong Yidong, emacs-devel

> So can you say whether, as maintainers, you support this goal, or should
> I just go away?

I support this goal, as I'm generally in favor of moving code away
from C.


        Stefan




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

* Re: moving window handling into lisp
  2009-07-29 14:05                           ` Stefan Monnier
  2009-08-01  2:20                             ` Miles Bader
@ 2009-08-11  9:18                             ` martin rudalics
  2009-08-11 19:16                               ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-11  9:18 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

 > Another approach is to have a transactional interface, like
 > start-window-configuration and end-window-configuration:
 > - during the transaction, windows can be resized to too-large/too-small
 >   sizes (but maybe window-fixed-size should stil be obeyed?).

This would still rely on some predictable behavior of `enlarge-window',
`adjust-window-trailing-edge' and `size_window'.  I suppose we should
merge these functions into one Elisp function that moves the trailing
edge of a window and have one C function checking whether the resulting
window tree is well-formed and, if that is the case, apply the change.

martin





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

* Re: moving window handling into lisp
  2009-08-11  9:18                             ` martin rudalics
@ 2009-08-11 19:16                               ` Stefan Monnier
  2009-08-11 19:29                                 ` Lennart Borgman
  2009-08-12  8:56                                 ` martin rudalics
  0 siblings, 2 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-11 19:16 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

>> Another approach is to have a transactional interface, like
>> start-window-configuration and end-window-configuration:
>> - during the transaction, windows can be resized to too-large/too-small
>> sizes (but maybe window-fixed-size should stil be obeyed?).

> This would still rely on some predictable behavior of `enlarge-window',
> `adjust-window-trailing-edge' and `size_window'.

There'd be new low-level functions to resize windows which would work in
simple and predictable ways, but with the end-state being potentially
invalid.

> I suppose we should merge these functions into one Elisp function that
> moves the trailing edge of a window and have one C function checking
> whether the resulting window tree is well-formed and, if that is the
> case, apply the change.

As a "high-level" function, I'd imagine a function that looks like
(window-resize W N) and returns the amount that it was able to resize
(between 0 and N).
It would work by calling itself recursively on siblings and/or children.
It can't fail and cannot result in an invalid window-tree.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-11 19:16                               ` Stefan Monnier
@ 2009-08-11 19:29                                 ` Lennart Borgman
  2009-08-12  8:57                                   ` martin rudalics
  2009-08-12  8:56                                 ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-11 19:29 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel

On Tue, Aug 11, 2009 at 9:16 PM, Stefan Monnier<monnier@iro.umontreal.ca> wrote:
>>> Another approach is to have a transactional interface, like
>>> start-window-configuration and end-window-configuration:
>>> - during the transaction, windows can be resized to too-large/too-small
>>> sizes (but maybe window-fixed-size should stil be obeyed?).
>
>> This would still rely on some predictable behavior of `enlarge-window',
>> `adjust-window-trailing-edge' and `size_window'.
>
> There'd be new low-level functions to resize windows which would work in
> simple and predictable ways, but with the end-state being potentially
> invalid.
>
>> I suppose we should merge these functions into one Elisp function that
>> moves the trailing edge of a window and have one C function checking
>> whether the resulting window tree is well-formed and, if that is the
>> case, apply the change.
>
> As a "high-level" function, I'd imagine a function that looks like
> (window-resize W N) and returns the amount that it was able to resize
> (between 0 and N).
> It would work by calling itself recursively on siblings and/or children.
> It can't fail and cannot result in an invalid window-tree.


I promised Martin a recipe that I belive could avoid making the
problem np-complete. It is very simple, and maybe along the lines
Stefan is thinking. It is just like this:

Note: This recipe is for doing it logically, so "split" means a
logical thing in a logical tree. The actual window splitting is done
later after computation.

1) Make a logical representation of the window tree where you split as
necessary.
2) Walk this logical tree bottom up collecting minimum required window sizes.
3) Walk top bottom-wise applying the sizes as they could be.
4) Apply the splitting and the computed sizes to the window tree.

Step 3 could of course fail if the minimum sizes does not fit.
Step 4 should be know problem in itself (fi the needed primitives are
available of course).

I "forgot" taking some things into account above, perhaps.


Is the description of the algorithm structure clear? Am I
misunderstanding this, or?




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

* Re: moving window handling into lisp
  2009-08-11 19:16                               ` Stefan Monnier
  2009-08-11 19:29                                 ` Lennart Borgman
@ 2009-08-12  8:56                                 ` martin rudalics
  2009-08-13  2:32                                   ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-12  8:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

 > There'd be new low-level functions to resize windows which would work in
 > simple and predictable ways, but with the end-state being potentially
 > invalid.

And how'd we revert to a valid state?  Using `set-window-configuration'?
Wasn't that something you wanted to avoid?

 >> I suppose we should merge these functions into one Elisp function that
 >> moves the trailing edge of a window and have one C function checking
 >> whether the resulting window tree is well-formed and, if that is the
 >> case, apply the change.
 >
 > As a "high-level" function, I'd imagine a function that looks like
 > (window-resize W N) and returns the amount that it was able to resize
 > (between 0 and N).
 > It would work by calling itself recursively ...

For modeline dragging we need a function which resizes a window by
moving _one edge_ only (which can be either the leading or the trailing
one).  If, in addition, we want to call that function recursively we
must be able to specify _which edge_ it should move, that is, it must be
able to move trailing _and_ leading edges.  Moreover, we probably want
to specify whether the function is allowed to delete windows, resize
windows below `window-min-height' or `window-min-width', or ignore the
value of `window-size-fixed'.

Also I think that a call with N > 1 failing to resize the window should
be able to result in an abort.  An application that can't get a window
of the appropriate size might prefer to use a new frame and leave the
original configuration unchanged.  Should it do that by saving the
window configuration and restoring it provided the amount returned by
`window-resize' doesn't fit its needs?

 > ... on siblings and/or children.

Including siblings of the window's parent, grandparent, ... I suppose.

 > It can't fail and cannot result in an invalid window-tree.

IMO `window-resize' should be written in Elisp while the check whether a
window tree is invalid would reside in C to guarantee that Elisp code
never crashes Emacs.  I'm not sure about the interface though.  I
imagine primitives like say `book-window-parent', `book-window-top',
`book-window-lines', ... and have a function checking-in the booked
values by (1) checking whether the booked values form a valid window
tree and, if that is the case, (2) replacing the actual values by the
booked values.

martin




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

* Re: moving window handling into lisp
  2009-08-11 19:29                                 ` Lennart Borgman
@ 2009-08-12  8:57                                   ` martin rudalics
  2009-08-12  9:02                                     ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-12  8:57 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > 1) Make a logical representation of the window tree where you split as
 > necessary.
 > 2) Walk this logical tree bottom up collecting minimum required window sizes.
 > 3) Walk top bottom-wise applying the sizes as they could be.
 > 4) Apply the splitting and the computed sizes to the window tree.
 >
 > Step 3 could of course fail if the minimum sizes does not fit.

The case where the minimum (and probably fixed) sizes don't fit is what
makes this problem hard and is _all_ I care about.  You end up by
deleting a window because it drops below some minimum height and when
that windows is missing you can't keep the fixed-sizeness of another
window ...

 > Step 4 should be know problem in itself (fi the needed primitives are
 > available of course).

The current primitives do a lot of deleting by themselves.  So your tree
carefully laid out in 3) might become a mess in 4).

martin




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

* Re: moving window handling into lisp
  2009-08-12  8:57                                   ` martin rudalics
@ 2009-08-12  9:02                                     ` Lennart Borgman
  2009-08-12 13:33                                       ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-12  9:02 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

On Wed, Aug 12, 2009 at 10:57 AM, martin rudalics<rudalics@gmx.at> wrote:
>> 1) Make a logical representation of the window tree where you split as
>> necessary.
>> 2) Walk this logical tree bottom up collecting minimum required window
>> sizes.
>> 3) Walk top bottom-wise applying the sizes as they could be.
>> 4) Apply the splitting and the computed sizes to the window tree.
>>
>> Step 3 could of course fail if the minimum sizes does not fit.
>
> The case where the minimum (and probably fixed) sizes don't fit is what
> makes this problem hard and is _all_ I care about.  You end up by
> deleting a window because it drops below some minimum height and when
> that windows is missing you can't keep the fixed-sizeness of another
> window ...


Mmm, but that problem does not make it np-complete...

... or perhaps it is then since there can be no solution in this case ... ;-)

I do not understand what you mean. You have found that it can't be
solved in this case, or? What am I missing?


>> Step 4 should be know problem in itself (fi the needed primitives are
>> available of course).
>
> The current primitives do a lot of deleting by themselves.  So your tree
> carefully laid out in 3) might become a mess in 4).


Yes. The primitives must be changed so there is a chance of putting
back the tree in 4 at all. (But I think I have said that several
times.)


> martin
>




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

* Re: moving window handling into lisp
  2009-08-12  9:02                                     ` Lennart Borgman
@ 2009-08-12 13:33                                       ` martin rudalics
  2009-08-12 15:57                                         ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-12 13:33 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > Mmm, but that problem does not make it np-complete...

... It can make it loop infinitely.  ISTR an early problem with (La)TeX
really hanging when inserting a footnote would make a page overfull,
leaving it away underfull.

 > ... or perhaps it is then since there can be no solution in this case ... ;-)
 >
 > I do not understand what you mean. You have found that it can't be
 > solved in this case, or? What am I missing?

I don't know.  I'm still waiting to see how your algorithm handles
windows getting too small and fixed size windows.

 > Yes. The primitives must be changed so there is a chance of putting
 > back the tree in 4 at all. (But I think I have said that several
 > times.)

Which primitives?  What does "putting back the tree" mean?

martin




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

* Re: moving window handling into lisp
  2009-08-12 13:33                                       ` martin rudalics
@ 2009-08-12 15:57                                         ` Lennart Borgman
  2009-08-12 17:05                                           ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-12 15:57 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

On Wed, Aug 12, 2009 at 3:33 PM, martin rudalics<rudalics@gmx.at> wrote:

> ... It can make it loop infinitely.  ISTR an early problem with (La)TeX
> really hanging when inserting a footnote would make a page overfull,
> leaving it away underfull.

I think the problems in the currently used logic may show up like
that, yes. But I am sure you know much more about that.


>> I do not understand what you mean. You have found that it can't be
>> solved in this case, or? What am I missing?
>
> I don't know.  I'm still waiting to see how your algorithm handles
> windows getting too small and fixed size windows.


I do not think that fixed size windows is any problem in the algorithm
I gave. You just use that size both when walking up and collecting
(minimal) sizes and when walking down to compute sizes to apply.

There is so to say no way to get too small windows when computing
sizes to apply, but you can of course find that there is not enough
space if the "sum" of the minimum sizes is too large. But you will
easily see that since on each level when you are going down you know
how much space each sublevel as a mininum needs.

I forgot to say that you of course have to use the algorithm
separately for widht and height.


Maybe I think totally wrong (I admitedly do that sometimes ... ;-) so
please help me and tell me what problems you see in the above.


If the space is not enough then there is a problem, yes, but that is a
real world problem so to say. It must be handled with a decision. We
must make some rules for it. I suggest simply FAIL, raise an error.
(Maybe catch+throw would be better since this really is expected
behaviour, but we have no structure, no predefined "catch names" that
could make this understandable by the programmer/user. And no messages
tied to it.)



>> Yes. The primitives must be changed so there is a chance of putting
>> back the tree in 4 at all. (But I think I have said that several
>> times.)
>
> Which primitives?  What does "putting back the tree" mean?


A very good question.


First the code that computes the sizes must be breaken out so the
above algorithm can be used when walking up and just collecting the
sizes. (Nothing is changed when walking up and collecting sizes.)


Then maybe some code must be changed so that you can walk down and
apply the sizes - without anything jumping in and preventing it.

I guess I might be missing something there, but I thought collecting
the sizes first should prevent anything bad happening when applying
them. However I think you understand this better. Is there something I
am missing in this step?


> martin
>




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

* Re: moving window handling into lisp
  2009-08-12 15:57                                         ` Lennart Borgman
@ 2009-08-12 17:05                                           ` martin rudalics
  2009-08-12 19:39                                             ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-12 17:05 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > I think the problems in the currently used logic may show up like
 > that, yes. But I am sure you know much more about that.

I suppose it can't loop currently.  Stefan's window balancing code can
loop so he put an upper bound on how often that loop can get executed.

 > I do not think that fixed size windows is any problem in the algorithm
 > I gave. You just use that size both when walking up and collecting
 > (minimal) sizes and when walking down to compute sizes to apply.

Maybe.  I still don't know whether you have an algorithm in the first
place.  The recipe you gave lacks two details: (1) How to "collect" the
sizes, and (2) how to "apply" them as they could be.

 > There is so to say no way to get too small windows when computing
 > sizes to apply, but you can of course find that there is not enough
 > space if the "sum" of the minimum sizes is too large. But you will
 > easily see that since on each level when you are going down you know
 > how much space each sublevel as a mininum needs.

With fixed-size windows you have a minimum and a maximum.  Surprisingly,
fixed-size windows are used in practice as a recent bug report confirms.

martin




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

* Re: moving window handling into lisp
  2009-08-12 17:05                                           ` martin rudalics
@ 2009-08-12 19:39                                             ` Lennart Borgman
  2009-08-12 21:10                                               ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-12 19:39 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]

Here is some elisp code that shows the "collecting" part. Am I missing
something essential there?

There are not so many comments at the moment, but I think you can guess... ;-)



On Wed, Aug 12, 2009 at 7:05 PM, martin rudalics<rudalics@gmx.at> wrote:
>> I think the problems in the currently used logic may show up like
>> that, yes. But I am sure you know much more about that.
>
> I suppose it can't loop currently.  Stefan's window balancing code can
> loop so he put an upper bound on how often that loop can get executed.
>
>> I do not think that fixed size windows is any problem in the algorithm
>> I gave. You just use that size both when walking up and collecting
>> (minimal) sizes and when walking down to compute sizes to apply.
>
> Maybe.  I still don't know whether you have an algorithm in the first
> place.  The recipe you gave lacks two details: (1) How to "collect" the
> sizes, and (2) how to "apply" them as they could be.
>
>> There is so to say no way to get too small windows when computing
>> sizes to apply, but you can of course find that there is not enough
>> space if the "sum" of the minimum sizes is too large. But you will
>> easily see that since on each level when you are going down you know
>> how much space each sublevel as a mininum needs.
>
> With fixed-size windows you have a minimum and a maximum.  Surprisingly,
> fixed-size windows are used in practice as a recent bug report confirms.
>
> martin
>

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 3340 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.1
;; Last-Updated: 2009-08-12 Wed
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wmin wmax height hmin hmax)
(defun wa-make-window (width wmin wmax)
  (list (list 'child nil) ;; Child
        (list 'size width wmin wmax) ;; Actual values
        (list 'compsize nil nil) ;; Slot for computation, wmin wmax
        ))

(defun wa-child (window) (nth 1 (nth 0 window)))
(defun wa-width (window) (nth 1 (nth 1 window)))
(defun wa-wmin  (window) (nth 2 (nth 1 window)))
(defun wa-wmax  (window) (nth 3 (nth 1 window)))

(defun wa-set-child (window child) (setcar (nthcdr 1 (nth 0 window)) child))
(defun wa-set-width (window)       (setcar (nthcdr 1 (nth 1 window))))
(defun wa-set-wmin  (window)       (setcar (nthcdr 2 (nth 1 window))))
(defun wa-set-wmax  (window)       (setcar (nthcdr 3 (nth 1 window))))

(defvar wa-root-window nil)
(setq wa-root-window (wa-make-window 80 nil nil))

(defun wa-set-child-windows (parent vertical &rest sizes)
  (dolist (s sizes) (assert (= 3 (length s)) t))
  (let* ((tot-given (apply '+ (mapcar (lambda (s) (car s)) (cdr sizes))))
         (par-size       (if vertical (wa-width parent) (wa-height parent)))
         ;;(par-other-size (if vertical (wa-height parent) (wa-width parent)))
         (real-sizes (copy-sequence sizes))
         children)
    (setcar (nth 1 real-sizes) (- par-size tot-given))
    (setq children (mapcar (lambda (size)
                             (if vertical
                                 (wa-make-window (nth 0 size)
                                                 (nth 1 size)
                                                 (nth 2 size))
                               ;;(wa-make-window size par-other-size)
                               ))
                           real-sizes))
    (wa-set-child parent children)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-compute-required (win)
  (let ((cmin (or (wa-wmin win) most-negative-fixnum))
        (cmax (or (wa-wmax win) most-positive-fixnum)))
    (dolist (c (wa-child win))
      (let ((res (wa-compute-required c)))
        (setq cmin (max (nth 0 res)
                        cmin))
        (setq cmax (max (nth 1 res)
                        cmax))))
    (assert (eq 'compsize (car (nth 2 win))))
    (setcar (nthcdr 1 (nth 2 win)) cmin)
    (setcar (nthcdr 2 (nth 2 win)) cmax)
    (list cmin cmax)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

;; (wa-test)
;; (wa-child wa-root-window)
;; (wa-width wa-root-window)
;; (wa-wmin wa-root-window)
;; (wa-wmax wa-root-window)
;; (wa-compute-required wa-root-window)

(defun wa-test ()
  (wa-set-child-windows wa-root-window t
                         '(nil nil nil)
                         '(5 4 nil)
                         '(8 nil nil)
                         '(4 3 nil)
                         ))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-12 19:39                                             ` Lennart Borgman
@ 2009-08-12 21:10                                               ` Lennart Borgman
  2009-08-13  9:55                                                 ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-12 21:10 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1692 bytes --]

Ehum, as always..., here is a better, somewhat more working version... ;-)



On Wed, Aug 12, 2009 at 9:39 PM, Lennart
Borgman<lennart.borgman@gmail.com> wrote:
> Here is some elisp code that shows the "collecting" part. Am I missing
> something essential there?
>
> There are not so many comments at the moment, but I think you can guess... ;-)
>
>
>
> On Wed, Aug 12, 2009 at 7:05 PM, martin rudalics<rudalics@gmx.at> wrote:
>>> I think the problems in the currently used logic may show up like
>>> that, yes. But I am sure you know much more about that.
>>
>> I suppose it can't loop currently.  Stefan's window balancing code can
>> loop so he put an upper bound on how often that loop can get executed.
>>
>>> I do not think that fixed size windows is any problem in the algorithm
>>> I gave. You just use that size both when walking up and collecting
>>> (minimal) sizes and when walking down to compute sizes to apply.
>>
>> Maybe.  I still don't know whether you have an algorithm in the first
>> place.  The recipe you gave lacks two details: (1) How to "collect" the
>> sizes, and (2) how to "apply" them as they could be.
>>
>>> There is so to say no way to get too small windows when computing
>>> sizes to apply, but you can of course find that there is not enough
>>> space if the "sum" of the minimum sizes is too large. But you will
>>> easily see that since on each level when you are going down you know
>>> how much space each sublevel as a mininum needs.
>>
>> With fixed-size windows you have a minimum and a maximum.  Surprisingly,
>> fixed-size windows are used in practice as a recent bug report confirms.
>>
>> martin
>>
>

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 5422 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.1
;; Last-Updated: 2009-08-12 Wed
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wmin wmax height hmin hmax)
(defun wa-make-window (name width wmin wmax)
  (list (list 'name name) ;; Easier communication ...
        (list 'child nil) ;; Child
        (list 'size width wmin wmax) ;; Actual values
        (list 'compsize nil nil) ;; Slot for computation, wmin wmax
        ))

;; Fix-me: Make defmacro to make those getters setters... - including
;; checks...
(defun wa-name  (window) (nth 1 (nth 0 window)))
(defun wa-child (window) (nth 1 (nth 1 window)))
(defun wa-width (window) (nth 1 (nth 2 window)))
(defun wa-wmin  (window) (nth 2 (nth 2 window)))
(defun wa-wmax  (window) (nth 3 (nth 2 window)))
(defun wa-wcmin (window) (nth 1 (nth 3 window)))
(defun wa-wcmax (window) (nth 2 (nth 3 window)))

(defun wa-set-name   (window name)  (setcar (nthcdr 1 (nth 0 window)) name))
(defun wa-set-child  (window child) (setcar (nthcdr 1 (nth 1 window)) child))
(defun wa-set-width  (window width) (setcar (nthcdr 1 (nth 2 window)) width))
(defun wa-set-wmin   (window wmin)  (setcar (nthcdr 2 (nth 2 window)) wmin))
(defun wa-set-wmax   (window wmax)  (setcar (nthcdr 3 (nth 2 window)) wmax))
(defun wa-set-wcmin  (window wmin)  (setcar (nthcdr 1 (nth 3 window)) wmin))
(defun wa-set-wcmax  (window wmax)  (setcar (nthcdr 2 (nth 3 window)) wmax))

(defun wa-check-fit (win)
  (let ((wmin (wa-wmin win))
        (wmax (wa-wmax win))
        (wcmin (wa-wcmin win))
        (wcmax (wa-wcmax win)))
    (when (and wmax wcmin)
      (unless (<= wcmin wmax)
        (error "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wcmin wmax)))
    (when (and wcmax wmin)
      (unless (<= wcmax wmin)
        (error "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wcmax wmin)))))

(defvar wa-root-window nil)

(defun wa-set-child-windows (parent vertical &rest sizes)
  (dolist (s sizes) (assert (= 3 (length s)) t))
  (let* ((tot-given (apply '+ (mapcar (lambda (s) (car s)) (cdr sizes))))
         (par-size       (if vertical (wa-width parent) (wa-height parent)))
         ;;(par-other-size (if vertical (wa-height parent) (wa-width parent)))
         (real-sizes (copy-sequence sizes))
         children
         (num 0))
    (setcar (nth 1 real-sizes) (- par-size tot-given))
    (setq children (mapcar (lambda (size)
                             (setq num (1+ num))
                             (if vertical
                                 (wa-make-window (format "%s-%d" (wa-name parent) num)
                                                 (nth 0 size)
                                                 (nth 1 size)
                                                 (nth 2 size))
                               ;;(wa-make-window size par-other-size)
                               ))
                           real-sizes))
    (wa-set-child parent children)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-clear-computed (win)
  (wa-set-wcmin win nil)
  (wa-set-wcmax win nil)
  (dolist (c (wa-child win))
    (wa-clear-computed c)))

(defun wa-compute-required (win)
  (let ((wmin (wa-wmin win))
        (wmax (wa-wmax win))
        (cmin 0)
        (cmax -1)
        )
    (dolist (c (wa-child win))
      (let* ((res (wa-compute-required c))
             (res-min (nth 0 res))
             (res-max (nth 1 res)))
        ;; Just sum the MIN
        (when res-min
          (setq cmin (+ cmin res-min)))
        (if res-max
            ;; ... ok, let us sum MAX to see how big we can be ...
            (if (numberp cmax)
                (setq cmax (+ cmax res-max))
              (setq cmax res-max))
          ;; Hurray, at least one child can grow!
          (setq cmax nil))
        ))
    (when (and cmax (< cmax 0)) (setq cmax nil)) ;; There was no max, ie no childs
    (when wmin (setq cmin (max wmin cmin)))
    (wa-set-wcmin win cmin)
    (wa-set-wcmax win cmax)
    (wa-check-fit win)
    (list (wa-wcmin win)
          (wa-wcmax win))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

(defun wa-add-test-childs ()
  (wa-set-child-windows wa-root-window t
                         '(nil nil nil)
                         '(5 4 nil)
                         '(8 nil nil)
                         '(4 3 nil)
                         ))

(setq wa-root-window (wa-make-window "Root" 80 nil nil))
(setq wa-root-window (wa-make-window "Root" 80 nil 8))
(setq wa-root-window (wa-make-window "Root" 80 nil 6))
(setq wa-root-window (wa-make-window "Root" 80 5 nil))
(setq wa-root-window (wa-make-window "Root" 80 15 nil))

;; (wa-child wa-root-window)
;; (wa-width wa-root-window)
;; (wa-wmin wa-root-window)
;; (wa-wmax wa-root-window)
;; (wa-clear-computed wa-root-window)

(wa-add-test-childs)
(wa-compute-required wa-root-window)
(describe-variable 'wa-root-window)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-12  8:56                                 ` martin rudalics
@ 2009-08-13  2:32                                   ` Stefan Monnier
  2009-08-13  9:54                                     ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-08-13  2:32 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

>> There'd be new low-level functions to resize windows which would work in
>> simple and predictable ways, but with the end-state being potentially
>> invalid.

> And how'd we revert to a valid state?  Using `set-window-configuration'?

The concept of transaction says that wehn you reach the end, you check
that things went right and if they don't you revert to the start state.
So yes, obviously it'd internally use something similar to
set-window-configuration.

> Wasn't that something you wanted to avoid?

No.  I did mention that its use to resurrect a deleted window should be
avoided because it may not work any more at some point in the future.
But we're here only talking about resizing windows, no deletion.

> For modeline dragging we need a function which resizes a window by
> moving _one edge_ only (which can be either the leading or the trailing
> one).  If, in addition, we want to call that function recursively we
> must be able to specify _which edge_ it should move, that is, it must be
> able to move trailing _and_ leading edges.

Yes, that'd probably be a different function from the one I suggested,
tho it could/would probably use the one I suggested for part of its work.

> Moreover, we probably want
> to specify whether the function is allowed to delete windows, resize
> windows below `window-min-height' or `window-min-width', or ignore the
> value of `window-size-fixed'.

At the user-level, it's pretty clear: no function resizing should ever
delete a window, resize a window below window-min-height or
window-min-width or ignore window-size-fixed.

> Also I think that a call with N > 1 failing to resize the window should
> be able to result in an abort.

It's easy to provide that behavior from outside when needed.

> An application that can't get a window of the appropriate size might
> prefer to use a new frame and leave the original configuration
> unchanged.  Should it do that by saving the window configuration and
> restoring it provided the amount returned by `window-resize' doesn't
> fit its needs?

Yes, it could.

>> ... on siblings and/or children.
> Including siblings of the window's parent, grandparent, ... I suppose.

That is the tricky part of th algorithm, indeed.

>> It can't fail and cannot result in an invalid window-tree.
> IMO `window-resize' should be written in Elisp while the check whether a
> window tree is invalid would reside in C to guarantee that Elisp code
> never crashes Emacs.

Yes, it's part of my working assumption.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-13  2:32                                   ` Stefan Monnier
@ 2009-08-13  9:54                                     ` martin rudalics
  2009-08-13 17:00                                       ` Stefan Monnier
  2009-08-14  6:42                                       ` Richard Stallman
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-13  9:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

 >> Wasn't that something you wanted to avoid?
 >
 > No.  I did mention that its use to resurrect a deleted window should be
 > avoided because it may not work any more at some point in the future.
 > But we're here only talking about resizing windows, no deletion.

Deleting windows currently is an inherent part of resizing, otherwise
`window-min-height' and `window-min-width' wouldn't make sense.  Where
and how would you handle these variables?

 >> For modeline dragging we need a function which resizes a window by
 >> moving _one edge_ only (which can be either the leading or the trailing
 >> one).  If, in addition, we want to call that function recursively we
 >> must be able to specify _which edge_ it should move, that is, it must be
 >> able to move trailing _and_ leading edges.
 >
 > Yes, that'd probably be a different function from the one I suggested,
 > tho it could/would probably use the one I suggested for part of its work.

That functionality was important enough to blow up the argument list of
size_window.  And that's the function we want to replace, I suppose?

 >> Moreover, we probably want
 >> to specify whether the function is allowed to delete windows, resize
 >> windows below `window-min-height' or `window-min-width', or ignore the
 >> value of `window-size-fixed'.
 >
 > At the user-level, it's pretty clear: no function resizing should ever
 > delete a window, resize a window below window-min-height or
 > window-min-width or ignore window-size-fixed.

I recall a discussion where everyone but me insisted that resizing
_should_ delete windows that get to small.  So I'm getting confused
about what "user-level" stands for.

Anyway, we may have to call some such function when resizing a frame and
that may ultimately require to delete windows.  Do you want to delegate
that to a higher level and re-call our function?

 >> Also I think that a call with N > 1 failing to resize the window should
 >> be able to result in an abort.
 >
 > It's easy to provide that behavior from outside when needed.

If window-configuration handling stuff is done within the function you
have in mind, then there will be two identic configurations we have to
save at the same time.  Why waste that space?

 >> An application that can't get a window of the appropriate size might
 >> prefer to use a new frame and leave the original configuration
 >> unchanged.  Should it do that by saving the window configuration and
 >> restoring it provided the amount returned by `window-resize' doesn't
 >> fit its needs?
 >
 > Yes, it could.

Expensive as explained above.

 >>> ... on siblings and/or children.
 >> Including siblings of the window's parent, grandparent, ... I suppose.
 >
 > That is the tricky part of th algorithm, indeed.
 >
 >>> It can't fail and cannot result in an invalid window-tree.
 >> IMO `window-resize' should be written in Elisp while the check whether a
 >> window tree is invalid would reside in C to guarantee that Elisp code
 >> never crashes Emacs.
 >
 > Yes, it's part of my working assumption.

So we agree on two points, at l(e)ast ;-)

martin




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

* Re: moving window handling into lisp
  2009-08-12 21:10                                               ` Lennart Borgman
@ 2009-08-13  9:55                                                 ` martin rudalics
  2009-08-13  9:57                                                   ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-13  9:55 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > Ehum, as always..., here is a better, somewhat more working version... ;-)

IIUC you're going down in some window tree and try to distribute the
available space among the children of each internal window.  But the
interesting part is when you have to backtrack because some window
didn't fit into its parent and you have to shrink (or enlarge) some
(grand-)parent's sibling.  I couldn't find that part :-(

martin




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

* Re: moving window handling into lisp
  2009-08-13  9:55                                                 ` martin rudalics
@ 2009-08-13  9:57                                                   ` Lennart Borgman
  2009-08-13 10:25                                                     ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-13  9:57 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

On Thu, Aug 13, 2009 at 11:55 AM, martin rudalics<rudalics@gmx.at> wrote:
>> Ehum, as always..., here is a better, somewhat more working version... ;-)
>
> IIUC you're going down in some window tree and try to distribute the
> available space among the children of each internal window.  But the
> interesting part is when you have to backtrack because some window
> didn't fit into its parent and you have to shrink (or enlarge) some
> (grand-)parent's sibling.  I couldn't find that part :-(


And that is the whole point of going up the tree and collecting sizes first...




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

* Re: moving window handling into lisp
  2009-08-13  9:57                                                   ` Lennart Borgman
@ 2009-08-13 10:25                                                     ` Lennart Borgman
  2009-08-13 11:32                                                       ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-13 10:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 769 bytes --]

On Thu, Aug 13, 2009 at 11:57 AM, Lennart
Borgman<lennart.borgman@gmail.com> wrote:
> On Thu, Aug 13, 2009 at 11:55 AM, martin rudalics<rudalics@gmx.at> wrote:
>>> Ehum, as always..., here is a better, somewhat more working version... ;-)
>>
>> IIUC you're going down in some window tree and try to distribute the
>> available space among the children of each internal window.  But the
>> interesting part is when you have to backtrack because some window
>> didn't fit into its parent and you have to shrink (or enlarge) some
>> (grand-)parent's sibling.  I couldn't find that part :-(
>
>
> And that is the whole point of going up the tree and collecting sizes first...


Here is the walking down part too. You have to tell me what you are missing.

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 7559 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.1
;; Last-Updated: 2009-08-12 Wed
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wmin wmax height hmin hmax)
(defun wa-make-window (name width wmin wmax)
  (list (list 'name name)            ;; Easier communication ...
        (list 'child nil)            ;; Child windows
        (list 'size width wmin wmax) ;; Old size and restrictions
        (list 'compsize nil nil)     ;; Slot for computation, wmin wmax
        (list 'set-size nil)         ;; Slot for setting, wmin wmax
        ))

;; Fix-me: Make defmacro to make those getters setters... - including
;; checks...
(defun wa-name  (window) (nth 1 (nth 0 window)))
(defun wa-child (window) (nth 1 (nth 1 window)))
(defun wa-width (window) (nth 1 (nth 2 window)))
(defun wa-wmin  (window) (nth 2 (nth 2 window)))
(defun wa-wmax  (window) (nth 3 (nth 2 window)))
(defun wa-wcmin (window) (nth 1 (nth 3 window)))
(defun wa-wcmax (window) (nth 2 (nth 3 window)))
(defun wa-wset  (window) (nth 1 (nth 4 window)))

(defun wa-set-name   (window name)  (setcar (nthcdr 1 (nth 0 window)) name))
(defun wa-set-child  (window child) (setcar (nthcdr 1 (nth 1 window)) child))
(defun wa-set-width  (window width) (setcar (nthcdr 1 (nth 2 window)) width))
(defun wa-set-wmin   (window wmin)  (setcar (nthcdr 2 (nth 2 window)) wmin))
(defun wa-set-wmax   (window wmax)  (setcar (nthcdr 3 (nth 2 window)) wmax))
(defun wa-set-wcmin  (window wmin)  (setcar (nthcdr 1 (nth 3 window)) wmin))
(defun wa-set-wcmax  (window wmax)  (setcar (nthcdr 2 (nth 3 window)) wmax))
(defun wa-set-wset   (window size)  (setcar (nthcdr 1 (nth 4 window)) size))

(defun wa-set-child-windows (parent vertical &rest sizes)
  (dolist (s sizes) (assert (= 3 (length s)) t))
  (let* ((tot-given (apply '+ (mapcar (lambda (s) (car s)) (cdr sizes))))
         (par-size       (if vertical (wa-width parent) (wa-height parent)))
         ;;(par-other-size (if vertical (wa-height parent) (wa-width parent)))
         (real-sizes (copy-sequence sizes))
         children
         (num 0))
    (setcar (nth 1 real-sizes) (- par-size tot-given))
    (setq children (mapcar (lambda (size)
                             (setq num (1+ num))
                             (if vertical
                                 (wa-make-window (format "%s-%d" (wa-name parent) num)
                                                 (nth 0 size)
                                                 (nth 1 size)
                                                 (nth 2 size))
                               ;;(wa-make-window size par-other-size)
                               ))
                           real-sizes))
    (wa-set-child parent children)))

(defun wa-check-fit (win)
  (let ((wmin (wa-wmin win))
        (wmax (wa-wmax win))
        (wcmin (wa-wcmin win))
        (wcmax (wa-wcmax win)))
    (when (and wmax wcmin)
      (unless (<= wcmin wmax)
        (error "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wcmin wmax)))
    (when (and wcmax wmin)
      (unless (<= wcmax wmin)
        (error "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wcmax wmin)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-clear-computed (win)
  (wa-set-wcmin win nil)
  (wa-set-wcmax win nil)
  (dolist (c (wa-child win))
    (wa-clear-computed c)))

(defun wa-compute-required (win)
  "Walk up collecting needed sizes."
  (let ((childs (wa-child win))
        (wmin (wa-wmin win))
        (wmax (wa-wmax win))
        (cmin 0)
        (cmax nil))
    (when childs
      (dolist (c childs)
        (let* ((res (wa-compute-required c))
               (res-min (nth 0 res))
               (res-max (nth 1 res)))
          ;; Just sum the MIN
          (setq cmin (+ cmin res-min))
          (if res-max
              ;; ... ok, let us sum MAX to see how big we can be ...
              (if (numberp cmax)
                  (setq cmax (+ cmax res-max))
                (setq cmax res-max))
            ;; Hurray, at least one child can grow!
            (setq cmax nil)))))
    (when wmin (setq cmin (max wmin (or cmin wmin))))
    (when wmax (setq cmax (min wmax (or cmax wmax))))
    (wa-set-wcmin win cmin)
    (wa-set-wcmax win cmax)
    (wa-check-fit win)
    (list (wa-wcmin win)
          (wa-wcmax win))))

(defun wa-compute-wanted (win strategy)
  "Walk down compute sizes."
  ;; Set root window size
  (unless (wa-wset win) (wa-set-wset win (wa-width win)))
  (let ((cmin   (wa-wcmin  win))
        (cmax   (wa-wcmax  win))
        (width  (wa-width win))
        (childs (wa-child win))
        )
  (case strategy
    ('eq-sizes
     (let (
           (rest-width width)
           (goal (/ width (length childs)))
           (rest-childs (copy-sequence childs)))
       ;; Clear childs
       (dolist (c childs) (wa-set-wset c nil))
       ;; Check child min requirements
       (dolist (c (copy-sequence rest-childs))
         (let ((wcmin (wa-wcmin c)))
           (when (and wcmin (<= goal wcmin))
             (wa-set-wset c (wa-wcmin c))
             (setq rest-childs (delete c rest-childs))
             (setq rest-width (- rest-width (wa-wcmin c))))))
       (setq goal (/ rest-width (length childs)))
       ;; Check child max requirements
       (dolist (c (copy-sequence rest-childs))
         (let ((wcmax (wa-wcmax c)))
           (when (and wcmax (>= goal wcmax))
             (wa-set-wset c (wa-wcmax c))
             (setq rest-childs (delete c rest-childs))
             (setq rest-width (- rest-width (wa-wcmax c))))))
       (setq goal (/ rest-width (length childs)))
       ;; Distribute the rest, taking care of roundings
       (wa-set-wset (car rest-childs)
                   (- rest-width (* goal (1- (length rest-childs)))))
       (dolist (c (cdr rest-childs))
         (wa-set-wset c goal))))
    (t (error "Unknown rule: %s" rule)))
  ;; Check
  (let ((w 0))
    (dolist (c childs)
      (setq w (+ w (wa-wset c))))
    (unless (= w (wa-wset win))
      (error "Bad set sizes child sum w=%d, win width=%d" w (wa-wset win))))
  ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

(defvar wa-root-window nil)

(defun wa-add-test-childs ()
  (wa-set-child-windows wa-root-window t
                         '(nil nil nil)
                         '(5 4 nil)
                         '(8 nil nil)
                         '(4 3 nil)
                         ))

(setq wa-root-window (wa-make-window "Root" 80 nil nil))
(setq wa-root-window (wa-make-window "Root" 80 nil 8))
(setq wa-root-window (wa-make-window "Root" 80 nil 6))
(setq wa-root-window (wa-make-window "Root" 80 5 nil))
(setq wa-root-window (wa-make-window "Root" 80 15 nil))

;; (wa-child wa-root-window)
;; (wa-width wa-root-window)
;; (wa-wmin wa-root-window)
;; (wa-wmax wa-root-window)
;; (wa-clear-computed wa-root-window)

(wa-add-test-childs)
(wa-compute-required wa-root-window)
(wa-compute-wanted   wa-root-window 'eq-sizes)
(describe-variable 'wa-root-window)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-13 10:25                                                     ` Lennart Borgman
@ 2009-08-13 11:32                                                       ` Lennart Borgman
  2009-08-13 12:49                                                         ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-13 11:32 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 931 bytes --]

New, version. This one does walk down too... ;-)


On Thu, Aug 13, 2009 at 12:25 PM, Lennart
Borgman<lennart.borgman@gmail.com> wrote:
> On Thu, Aug 13, 2009 at 11:57 AM, Lennart
> Borgman<lennart.borgman@gmail.com> wrote:
>> On Thu, Aug 13, 2009 at 11:55 AM, martin rudalics<rudalics@gmx.at> wrote:
>>>> Ehum, as always..., here is a better, somewhat more working version... ;-)
>>>
>>> IIUC you're going down in some window tree and try to distribute the
>>> available space among the children of each internal window.  But the
>>> interesting part is when you have to backtrack because some window
>>> didn't fit into its parent and you have to shrink (or enlarge) some
>>> (grand-)parent's sibling.  I couldn't find that part :-(
>>
>>
>> And that is the whole point of going up the tree and collecting sizes first...
>
>
> Here is the walking down part too. You have to tell me what you are missing.
>

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 8075 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.2
;; Last-Updated: 2009-08-13 Thu
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wumin wumax height hmin hmax)
(defun wa-make-window (name width wumin wumax)
  (list (list 'name name)            ;; Easier communication ...
        (list 'child nil)            ;; Child windows
        (list 'usr-size wumin wumax) ;; Restrictions
        (list 'req-size nil nil)     ;; Slot for computated requirements, wumin wumax
        (list 'set-size width)       ;; Slot for setting new size
        ))

;; Fix-me: Make defmacro to make those getters setters... - including
;; checks...

(defun wa-name  (window) (nth 1 (nth 0 window))) ;; 'name
(defun wa-child (window) (nth 1 (nth 1 window))) ;; 'child
(defun wa-wumin (window) (nth 1 (nth 2 window))) ;; 'usr-size
(defun wa-wumax (window) (nth 2 (nth 2 window))) ;; 'usr-size
(defun wa-wrmin (window) (nth 1 (nth 3 window))) ;; 'req-size
(defun wa-wrmax (window) (nth 2 (nth 3 window))) ;; 'req-size
(defun wa-wset  (window) (nth 1 (nth 4 window))) ;; 'set-size

(defun wa-set-name   (window name)  (setcar (nthcdr 1 (nth 0 window)) name))  ;; 'name
(defun wa-set-child  (window child) (setcar (nthcdr 1 (nth 1 window)) child)) ;; 'name
(defun wa-set-wumin  (window wumin) (setcar (nthcdr 1 (nth 2 window)) wumin)) ;; 'usr-size
(defun wa-set-wumax  (window wumax) (setcar (nthcdr 2 (nth 2 window)) wumax)) ;; 'usr-size
(defun wa-set-wrmin  (window wumin) (setcar (nthcdr 1 (nth 3 window)) wumin)) ;; 'req-size
(defun wa-set-wrmax  (window wumax) (setcar (nthcdr 2 (nth 3 window)) wumax)) ;; 'req-size
(defun wa-set-wset   (window size)  (setcar (nthcdr 1 (nth 4 window)) size))  ;; 'set-size

(defun wa-set-child-windows (parent vertical &rest sizes)
  (let (children
        (num 0))
    (setq children (mapcar (lambda (size)
                             (setq num (1+ num))
                             (if vertical
                                 (wa-make-window (format "%s-%d" (wa-name parent) num)
                                                 nil
                                                 (nth 0 size)
                                                 (nth 1 size))
                               ))
                           sizes))
    (wa-set-child parent children)))

(defun wa-check-fit (win)
  (let ((wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (wrmin (wa-wrmin win))
        (wrmax (wa-wrmax win))
        (wset  (wa-wset win)))
    ;; Top window
    (when (and wset wrmin)
      (unless (<= wrmin wset)
        (error "Window %s set size too small=%d, min=%d" (wa-name win) wset wrmin)))
    (when (and wset wrmax)
      (unless (>= wrmax wset)
        (error "Window %s set size too large=%d, max=%s" (wa-name win) wset wrmax)))
    ;; All
    (when (and wumax wrmin)
      (unless (<= wrmin wumax)
        (error "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wrmin wumax)))
    (when (and wrmax wumin)
      (unless (<= wrmax wumin)
        (error "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wrmax wumin)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-clear-computed (win)
  (wa-set-wrmin win nil)
  (wa-set-wrmax win nil)
  (wa-set-wset  win nil)
  (dolist (c (wa-child win))
    (wa-clear-computed c)))

(defun wa-compute-required (win)
  "Walk up collecting needed sizes."
  (let ((childs (wa-child win))
        (wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (cmin 0)
        (cmax nil))
    (when childs
      ;; Clear childs set sizes, we do not know them here
      (dolist (c childs) (wa-set-wset c nil))
      (dolist (c childs)
        (let* ((res (wa-compute-required c))
               (res-min (nth 0 res))
               (res-max (nth 1 res)))
          ;; Just sum the MIN
          (setq cmin (+ cmin res-min))
          (if res-max
              ;; ... ok, let us sum MAX to see how big we can be ...
              (if (numberp cmax)
                  (setq cmax (+ cmax res-max))
                (setq cmax res-max))
            ;; Hurray, at least one child can grow!
            (setq cmax nil)))))
    (when wumin (setq cmin (max wumin (or cmin wumin))))
    (when wumax (setq cmax (min wumax (or cmax wumax))))
    ;; Sanity
    (when (= cmin 0) (setq cmin 1))
    (assert (or (not cmin) (<= 1 cmin)) t)
    (assert (or (not cmax) (<= 1 cmax)) t)
    (wa-set-wrmin win cmin)
    (wa-set-wrmax win cmax)
    (wa-check-fit win)
    (list (wa-wrmin win)
          (wa-wrmax win))))

(defun wa-compute-wanted (win strategy)
  "Walk down compute sizes."
  (when (wa-child win)
    (let ((cmin   (wa-wrmin  win))
          (cmax   (wa-wrmax  win))
          (width  (wa-wset win))
          (childs (wa-child win))
          )
      (case strategy
        ('eq-sizes
         (let (
               (rest-width width)
               (goal (/ width (length childs)))
               (rest-childs (copy-sequence childs)))
           ;; Clear childs
           (dolist (c childs) (wa-set-wset c nil))
           ;; Check child min requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmin (wa-wrmin c)))
               (when (and wrmin (<= goal wrmin))
                 (wa-set-wset c (wa-wrmin c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmin c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Check child max requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmax (wa-wrmax c)))
               (when (and wrmax (>= goal wrmax))
                 (wa-set-wset c (wa-wrmax c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmax c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Distribute the rest, taking care of roundings
           (wa-set-wset (car rest-childs)
                        (- rest-width (* goal (1- (length rest-childs)))))
           (dolist (c (cdr rest-childs))
             (wa-set-wset c goal))))
        (t (error "Unknown rule: %s" rule)))
      ;; Check
      (let ((w 0))
        (dolist (c childs)
          (let ((wset (wa-wset c)))
            (assert (<= 0 wset) t)
            (setq w (+ w wset))))
        (unless (= w (wa-wset win))
          (error "Bad set sizes child sum w=%d, win width=%d" w (wa-wset win))))
      ;; Walk down
      (dolist (c childs)
        (wa-compute-wanted c strategy)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

(defvar wa-root-window nil)

(defun wa-add-test-childs ()
  (wa-set-child-windows wa-root-window t
                         '(nil nil)
                         '(14 nil)
                         '(nil nil)
                         '(3 nil)
                         ))

(setq wa-root-window (wa-make-window "Root" 80 nil nil))
(setq wa-root-window (wa-make-window "Root" 80 nil 8))
(setq wa-root-window (wa-make-window "Root" 80 nil 6))
(setq wa-root-window (wa-make-window "Root" 80 5 nil))
(setq wa-root-window (wa-make-window "Root" 15 15 nil))
(setq wa-root-window (wa-make-window "Root" 18 15 nil))

;; (wa-child wa-root-window)
;; (wa-wset wa-root-window)
;; (wa-wumin wa-root-window)
;; (wa-wumax wa-root-window)
;; (wa-clear-computed wa-root-window)

(wa-add-test-childs)
(wa-compute-required wa-root-window)
(wa-compute-wanted   wa-root-window 'eq-sizes)
(describe-variable 'wa-root-window)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-13 11:32                                                       ` Lennart Borgman
@ 2009-08-13 12:49                                                         ` Lennart Borgman
  2009-08-13 13:56                                                           ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-13 12:49 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1082 bytes --]

This one is easier to play with.


On Thu, Aug 13, 2009 at 1:32 PM, Lennart
Borgman<lennart.borgman@gmail.com> wrote:
> New, version. This one does walk down too... ;-)
>
>
> On Thu, Aug 13, 2009 at 12:25 PM, Lennart
> Borgman<lennart.borgman@gmail.com> wrote:
>> On Thu, Aug 13, 2009 at 11:57 AM, Lennart
>> Borgman<lennart.borgman@gmail.com> wrote:
>>> On Thu, Aug 13, 2009 at 11:55 AM, martin rudalics<rudalics@gmx.at> wrote:
>>>>> Ehum, as always..., here is a better, somewhat more working version... ;-)
>>>>
>>>> IIUC you're going down in some window tree and try to distribute the
>>>> available space among the children of each internal window.  But the
>>>> interesting part is when you have to backtrack because some window
>>>> didn't fit into its parent and you have to shrink (or enlarge) some
>>>> (grand-)parent's sibling.  I couldn't find that part :-(
>>>
>>>
>>> And that is the whole point of going up the tree and collecting sizes first...
>>
>>
>> Here is the walking down part too. You have to tell me what you are missing.
>>
>

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 9153 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.2
;; Last-Updated: 2009-08-13 Thu
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wumin wumax height hmin hmax)
(defun wa-make-window (name width wumin wumax)
  (list (list 'name name)            ;; Easier communication ...
        (list 'child nil)            ;; Child windows
        (list 'usr-size wumin wumax) ;; Restrictions
        (list 'req-size nil nil)     ;; Slot for computated requirements, wumin wumax
        (list 'set-size nil width)       ;; Slot for setting new size
        ))

;; Fix-me: Make defmacro to make those getters setters... - including
;; checks...

(defun wa-name  (window) (nth 1 (nth 0 window))) ;; 'name
(defun wa-child (window) (nth 1 (nth 1 window))) ;; 'child
(defun wa-wumin (window) (nth 1 (nth 2 window))) ;; 'usr-size
(defun wa-wumax (window) (nth 2 (nth 2 window))) ;; 'usr-size
(defun wa-wrmin (window) (nth 1 (nth 3 window))) ;; 'req-size
(defun wa-wrmax (window) (nth 2 (nth 3 window))) ;; 'req-size
(defun wa-wset  (window) (nth 2 (nth 4 window))) ;; 'set-size

(defun wa-set-name   (window name)  (setcar (nthcdr 1 (nth 0 window)) name))  ;; 'name
(defun wa-set-child  (window child) (setcar (nthcdr 1 (nth 1 window)) child)) ;; 'child
(defun wa-set-wumin  (window wumin) (setcar (nthcdr 1 (nth 2 window)) wumin)) ;; 'usr-size
(defun wa-set-wumax  (window wumax) (setcar (nthcdr 2 (nth 2 window)) wumax)) ;; 'usr-size
(defun wa-set-wrmin  (window wumin) (setcar (nthcdr 1 (nth 3 window)) wumin)) ;; 'req-size
(defun wa-set-wrmax  (window wumax) (setcar (nthcdr 2 (nth 3 window)) wumax)) ;; 'req-size
(defun wa-set-wset   (window size)  (setcar (nthcdr 2 (nth 4 window)) size))  ;; 'set-size

(defun wa-set-flag   (window flag)  (setcar (nthcdr 1 (nth 4 window)) flag))  ;; 'set-size

(defvar wa-failed nil)

(defun wa-error (format-string &rest args)
  (setq wa-failed t)
  (apply 'message (propertize format-string 'face 'secondary-selection)
         args)
  (throw 'wa-error nil))

(defun wa-set-child-windows (parent vertical &rest sizes)
  (unless wa-failed (assert (< 1 (length sizes)) t))
  (let (children
        (num 0))
    (setq children (mapcar (lambda (size)
                             (setq num (1+ num))
                             (if vertical
                                 (wa-make-window (format "%s-%d" (wa-name parent) num)
                                                 nil
                                                 (nth 0 size)
                                                 (nth 1 size))))
                           sizes))
    (wa-set-child parent children)
    parent))

(defun wa-check-fit (win)
  (let ((wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (wrmin (wa-wrmin win))
        (wrmax (wa-wrmax win))
        (wset  (wa-wset win)))
    (wa-set-flag win 'FAILED)
    ;; Top window
    (when (and wset wrmin)
      (unless (<= wrmin wset)
        (wa-error "Window %s set size too small=%d, min=%d" (wa-name win) wset wrmin)))
    (when (and wset wrmax)
      (unless (>= wrmax wset)
        (wa-error "Window %s set size too large=%d, max=%s" (wa-name win) wset wrmax)))
    ;; All
    (when (and wumax wrmin)
      (unless (<= wrmin wumax)
        (wa-error "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wrmin wumax)))
    (when (and wrmax wumin)
      (unless (>= wrmax wumin)
        (wa-error "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wrmax wumin)))
    (wa-set-flag win 'OK)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-clear-computed (win)
  (wa-set-wrmin win nil)
  (wa-set-wrmax win nil)
  (wa-set-wset  win nil)
  (dolist (c (wa-child win))
    (wa-clear-computed c)))

(defun wa-init-fail-flag (win)
  (wa-set-flag win 'INIT)
  (dolist (c (wa-child win))
    (wa-init-fail-flag c)))

(defun wa-compute-required (win)
  "Walk up collecting needed sizes."
  (let ((childs (wa-child win))
        (wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (cmin 0)
        (cmax nil))
    (when childs
      ;; Clear childs set sizes, we do not know them here
      (dolist (c childs) (wa-set-wset c nil))
      (dolist (c childs)
        (let* ((res (wa-compute-required c))
               (res-min (nth 0 res))
               (res-max (nth 1 res)))
          ;; Just sum the MIN
          (setq cmin (+ cmin res-min))
          (if res-max
              ;; ... ok, let us sum MAX to see how big we can be ...
              (if (numberp cmax)
                  (setq cmax (+ cmax res-max))
                (setq cmax res-max))
            ;; Hurray, at least one child can grow!
            (setq cmax nil)))))
    (when wumin (setq cmin (max wumin (or cmin wumin))))
    (when wumax (setq cmax (min wumax (or cmax wumax))))
    ;; Sanity
    (when (= cmin 0) (setq cmin 1))
    (unless wa-failed (assert (or (not cmin) (<= 1 cmin)) t))
    (unless wa-failed (assert (or (not cmax) (<= 1 cmax)) t))
    (wa-set-wrmin win cmin)
    (wa-set-wrmax win cmax)
    (wa-check-fit win)
    (list (wa-wrmin win)
          (wa-wrmax win))))

(defun wa-compute-wanted (win strategy)
  "Walk down compute sizes."
  (when (wa-child win)
    (let ((cmin   (wa-wrmin  win))
          (cmax   (wa-wrmax  win))
          (width  (wa-wset win))
          (childs (wa-child win)))
      (case strategy
        ('eq-sizes
         (let ((rest-width width)
               (goal (/ width (length childs)))
               (rest-childs (copy-sequence childs)))
           ;; Clear childs
           (dolist (c childs) (wa-set-wset c nil))
           ;; Check child min requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmin (wa-wrmin c)))
               (when (and wrmin (<= goal wrmin))
                 (wa-set-wset c (wa-wrmin c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmin c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Check child max requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmax (wa-wrmax c)))
               (when (and wrmax (>= goal wrmax))
                 (wa-set-wset c (wa-wrmax c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmax c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Distribute the rest, taking care of roundings
           (wa-set-wset (car rest-childs)
                        (- rest-width (* goal (1- (length rest-childs)))))
           (dolist (c (cdr rest-childs))
             (wa-set-wset c goal))))
        (t (wa-error "Unknown strategy: %s" strategy)))
      ;; Check
      (let ((w 0))
        (dolist (c childs)
          (let ((wset (wa-wset c)))
            (unless wa-failed (assert (<= 0 wset) t))
            (setq w (+ w wset))))
        (unless (= w (wa-wset win))
          (wa-error "Bad set sizes child sum w=%d, win width=%d" w (wa-wset win))))
      ;; Walk down
      (dolist (c childs)
        (wa-compute-wanted c strategy)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

(defvar wa-root-window nil)

(defun wa-add-test-childs ()
  (wa-set-child-windows wa-root-window t
                         '(nil 7)
                         '(14 nil)
                         '(nil nil)
                         '(3 nil)
                         )
  (wa-set-child-windows (car (wa-child wa-root-window)) t
                        '(nil nil)
                        '(8 15))
  )

(setq wa-root-window (wa-make-window "Root" 80 nil nil))
(setq wa-root-window (wa-make-window "Root" 80 nil 8))
(setq wa-root-window (wa-make-window "Root" 80 nil 6))
(setq wa-root-window (wa-make-window "Root" 80 5 nil))
(setq wa-root-window (wa-make-window "Root" 15 15 nil))
(setq wa-root-window (wa-make-window "Root" 43 15 nil))
(setq wa-root-window (wa-make-window "Root" 18 15 nil))

;; (wa-child wa-root-window)
;; (wa-wset wa-root-window)
;; (wa-wumin wa-root-window)
;; (wa-wumax wa-root-window)
;; (wa-clear-computed wa-root-window)

;; Setup
(wa-add-test-childs)
(wa-init-fail-flag   wa-root-window)
(setq wa-failed nil)

;; Show state now in case we want to stop on errors
(describe-variable  'wa-root-window)

;; Compute required, may fail. In this case the initial state will
;; remain in the help buffer.
(catch 'wa-error
  (wa-compute-required wa-root-window))

;; Now it should not fail
(wa-compute-wanted   wa-root-window 'eq-sizes)
(describe-variable  'wa-root-window)



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-13 12:49                                                         ` Lennart Borgman
@ 2009-08-13 13:56                                                           ` martin rudalics
  2009-08-13 16:43                                                             ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-13 13:56 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > This one is easier to play with.
[...]
 >>> Here is the walking down part too. You have to tell me what you are missing.

When I try to evaluate that I get

Window Root-1 is too small, min=9, but can be max=7


Anyway, I do hope to understand what you mean.  When "going up" you
calculate minimum and maximum sizes and when "going down" you distribute
the frame size recursively among its children according to some
"strategy".  When the minimum and maximum sizes can't be applied you
give up before going down.

The problem I see is with the "strategy" that sets the desired sizes.
With 'eq-sizes you calculate them on the fly when you "walk down".
Unfortunately, this won't help when you just want to enlarge one
individual leaf window.  In that case we usually resize one adjacent
window and leave the other windows alone.  You'd probably first set the
min/max values of the window you want to enlarge to the desired value,
relax the min/max values of an adjacent sibling and leave all other
min/max values at the current sizes.  If this works out you're done.

Otherwise, you'd have to relax min/max values for additional windows and
see whether you succeed.  You'd probably start doing that process
"inside out" by selecting siblings of the window you want to enlarge,
siblings of their parent and so on.  That's what I meant with
backtracking.  The complexity of that process is, in the worst case,
proportional to the number of possible Emacs tilings of a frame into the
windows you have.  Obviously, we don't expect the worst case to happen.
But we'd probably need some reasonable divide-and-conquer strategy to
make sure to always get a good result.  Finding such a strategy is the
hard part.

I suppose your approach would handle the case where you simply want to
resize the containing frame.  Just calculate the min/max values and look
whether the desired window sizes fit into that.  After that, adjust the
windows arbitrarily with one line/column more or less.  But with
frame-resizing the hard case is just that we need some heuristics when
windows don't fit due to their hard min-weight/-height, fixed-size
requirements.

martin




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

* Re: moving window handling into lisp
  2009-08-13 13:56                                                           ` martin rudalics
@ 2009-08-13 16:43                                                             ` Lennart Borgman
  2009-08-13 18:07                                                               ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-13 16:43 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

On Thu, Aug 13, 2009 at 3:56 PM, martin rudalics<rudalics@gmx.at> wrote:
>> This one is easier to play with.
> [...]
>>>> Here is the walking down part too. You have to tell me what you are
>>>> missing.
>
> When I try to evaluate that I get
>
> Window Root-1 is too small, min=9, but can be max=7

Yes, that how it should be. You evaluate this file to test. Look at
the bottom of the file.


> Anyway, I do hope to understand what you mean.  When "going up" you
> calculate minimum and maximum sizes and when "going down" you distribute
> the frame size recursively among its children according to some
> "strategy".  When the minimum and maximum sizes can't be applied you
> give up before going down.

Yes, you catch the errors going up before you try to apply.


> The problem I see is with the "strategy" that sets the desired sizes.
> With 'eq-sizes you calculate them on the fly when you "walk down".
> Unfortunately, this won't help when you just want to enlarge one
> individual leaf window.  In that case we usually resize one adjacent
> window and leave the other windows alone.  You'd probably first set the
> min/max values of the window you want to enlarge to the desired value,
> relax the min/max values of an adjacent sibling and leave all other
> min/max values at the current sizes.  If this works out you're done.
>
> Otherwise, you'd have to relax min/max values for additional windows and
> see whether you succeed.  You'd probably start doing that process
> "inside out" by selecting siblings of the window you want to enlarge,
> siblings of their parent and so on.  That's what I meant with
> backtracking.  The complexity of that process is, in the worst case,
> proportional to the number of possible Emacs tilings of a frame into the
> windows you have.  Obviously, we don't expect the worst case to happen.
> But we'd probably need some reasonable divide-and-conquer strategy to
> make sure to always get a good result.  Finding such a strategy is the
> hard part.

I am not sure why you want to do something like the above. However you
introduce a new element here: relaxing of the requirements.

Do you really want to do that? Or did I misunderstand you?

Of course, chaning the boundaries/requirement can lead to infinite
recursion.... ;-)

More seriously: if you are changing the rules, then please tell what
rules you want to use see we can see if the problem is solveable with
your new rules.

On the other hand, if you do not change the rules, then I can't see
why the algorithm I provided can't be used when you enlarge a single
window. But maybe you can, so please tell me.


> I suppose your approach would handle the case where you simply want to
> resize the containing frame.  Just calculate the min/max values and look
> whether the desired window sizes fit into that.  After that, adjust the
> windows arbitrarily with one line/column more or less.  But with
> frame-resizing the hard case is just that we need some heuristics when
> windows don't fit due to their hard min-weight/-height, fixed-size
> requirements.

If they do not fit, they do not fit. So you mean we should have new rules then?

Maybe. I am not sure. But if you please tell what rules you are
thinking of then I will try to put it into the algorithm (in case you
do not do it yourself, of course).


I could think of some rules to use, so it is not totally unfamiliar to
me. How about a rule like this:

- If the windows are too large then allow shrinking them to a system
wide default minimum size.

Such a rule could easily be added to the algorithm like this:

- run a first pass bottom-up.
- if it did not fit run a second bottom-up pass with the new rules.


> martin
>




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

* Re: moving window handling into lisp
  2009-08-13  9:54                                     ` martin rudalics
@ 2009-08-13 17:00                                       ` Stefan Monnier
  2009-08-13 18:09                                         ` martin rudalics
  2009-08-14  6:42                                       ` Richard Stallman
  1 sibling, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-08-13 17:00 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

>>> Wasn't that something you wanted to avoid?
>> No.  I did mention that its use to resurrect a deleted window should be
>> avoided because it may not work any more at some point in the future.
>> But we're here only talking about resizing windows, no deletion.
> Deleting windows currently is an inherent part of resizing,

"currently" is the operative word.  I consider it to be a serious flaw
in the current design.

> otherwise `window-min-height' and `window-min-width' wouldn't make
> sense.  Where and how would you handle these variables?

They would cause the window resizing to fail.  I would only consider
deleting too-small windows when faced with a frame-resize, where failure
would be worse.

> That functionality was important enough to blow up the argument list of
> size_window.  And that's the function we want to replace, I suppose?

Could be.  I haven't spent enough time looking at the code yet.

> I recall a discussion where everyone but me insisted that resizing
> _should_ delete windows that get to small.

If I did insist on that back then, I was wrong.  Luckily, I forgot about
having such a bad idea.

> Anyway, we may have to call some such function when resizing a frame and
> that may ultimately require to delete windows.  Do you want to delegate
> that to a higher level and re-call our function?

Yes.

>>> Also I think that a call with N > 1 failing to resize the window should
>>> be able to result in an abort.
>> It's easy to provide that behavior from outside when needed.
> If window-configuration handling stuff is done within the function you
> have in mind, then there will be two identic configurations we have to
> save at the same time.  Why waste that space?

Maybe we'll decide to provide the feature directly from within, if
performance forces us to.  We're sufficiently far from an implementation
that I have no idea why you'd bring up such issues at this point.

>>> An application that can't get a window of the appropriate size might
>>> prefer to use a new frame and leave the original configuration
>>> unchanged.  Should it do that by saving the window configuration and
>>> restoring it provided the amount returned by `window-resize' doesn't
>>> fit its needs?
>> Yes, it could.
> Expensive as explained above.

Could be.  I wouldn't bet on it, tho.  If needed, we could even make the
window tree objects a bit more functional, in which case save/restore
a window tree becomes very cheap.  Or we could use another algorithm
which first figures out what the end tree should look like and then
applies the changes, ...


        Stefan




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

* Re: moving window handling into lisp
  2009-08-13 16:43                                                             ` Lennart Borgman
@ 2009-08-13 18:07                                                               ` martin rudalics
  2009-08-14  1:13                                                                 ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-13 18:07 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 >> The problem I see is with the "strategy" that sets the desired sizes.
 >> With 'eq-sizes you calculate them on the fly when you "walk down".
 >> Unfortunately, this won't help when you just want to enlarge one
 >> individual leaf window.  In that case we usually resize one adjacent
 >> window and leave the other windows alone.  You'd probably first set the
 >> min/max values of the window you want to enlarge to the desired value,
 >> relax the min/max values of an adjacent sibling and leave all other
 >> min/max values at the current sizes.  If this works out you're done.
 >>
 >> Otherwise, you'd have to relax min/max values for additional windows and
 >> see whether you succeed.  You'd probably start doing that process
 >> "inside out" by selecting siblings of the window you want to enlarge,
 >> siblings of their parent and so on.  That's what I meant with
 >> backtracking.  The complexity of that process is, in the worst case,
 >> proportional to the number of possible Emacs tilings of a frame into the
 >> windows you have.  Obviously, we don't expect the worst case to happen.
 >> But we'd probably need some reasonable divide-and-conquer strategy to
 >> make sure to always get a good result.  Finding such a strategy is the
 >> hard part.
 >
 > I am not sure why you want to do something like the above. However you
 > introduce a new element here: relaxing of the requirements.

Not only - in the first step I would make them stronger.

 > Do you really want to do that? Or did I misunderstand you?

When I change the size of a particular window on one end of my frame I
don't want Emacs to change the sizes of windows at the other end.
Changes should be "as local as possible".  For example, when I drag a
modeline I usually do not expect the sizes of windows not adjacent to
that modeline change unless Emacs has no other choice.

 > More seriously: if you are changing the rules, then please tell what
 > rules you want to use see we can see if the problem is solveable with
 > your new rules.

What rules?  Please tell me _how_ your algorithm would handle a single
`enlarge-window' command.  Which other windows would change in which
order?  How would new window sizes relate to the old ones?

martin




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

* Re: moving window handling into lisp
  2009-08-13 17:00                                       ` Stefan Monnier
@ 2009-08-13 18:09                                         ` martin rudalics
  2009-08-14  1:47                                           ` Stephen J. Turnbull
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-13 18:09 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

 >> Deleting windows currently is an inherent part of resizing,
 >
 > "currently" is the operative word.  I consider it to be a serious flaw
 > in the current design.

We violently agree.  In particular the idea of temporarily binding
`window-min-height' to some small value and having the next resize
operation kill that window strikes me as quite flawed.

 >> otherwise `window-min-height' and `window-min-width' wouldn't make
 >> sense.  Where and how would you handle these variables?
 >
 > They would cause the window resizing to fail.  I would only consider
 > deleting too-small windows when faced with a frame-resize, where failure
 > would be worse.

Agreed.  Honestly, do we need these variables?

 >> That functionality was important enough to blow up the argument list of
 >> size_window.  And that's the function we want to replace, I suppose?
 >
 > Could be.  I haven't spent enough time looking at the code yet.

It's easy to explain: When dragging a modeline, you probably want to
shrink/enlarge the bottom-most windows above the modeline and
enlarge/shrink the topmost windows below the modeline first.

 >> I recall a discussion where everyone but me insisted that resizing
 >> _should_ delete windows that get to small.
 >
 > If I did insist on that back then, I was wrong.  Luckily, I forgot about
 > having such a bad idea.

Fine (but I don't recall if you participated in that discussion).

 >> Anyway, we may have to call some such function when resizing a frame and
 >> that may ultimately require to delete windows.  Do you want to delegate
 >> that to a higher level and re-call our function?
 >
 > Yes.

There's one small point here: The resizing function might know better
which window to delete.  WOW the function to pick the candidates for
deletion would probably walk the same windows anway.

 >>>> Also I think that a call with N > 1 failing to resize the window should
 >>>> be able to result in an abort.
 >>> It's easy to provide that behavior from outside when needed.
 >> If window-configuration handling stuff is done within the function you
 >> have in mind, then there will be two identic configurations we have to
 >> save at the same time.  Why waste that space?
 >
 > Maybe we'll decide to provide the feature directly from within, if
 > performance forces us to.  We're sufficiently far from an implementation
 > that I have no idea why you'd bring up such issues at this point.

But it wouldn't harm to consider this from the outset.

 >> Expensive as explained above.
 >
 > Could be.  I wouldn't bet on it, tho.  If needed, we could even make the
 > window tree objects a bit more functional, in which case save/restore
 > a window tree becomes very cheap.

Not necessarily cheap.  But much, much simpler to code.

 > Or we could use another algorithm
 > which first figures out what the end tree should look like and then
 > applies the changes, ...

That's what I had in mind.

martin




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

* Re: moving window handling into lisp
  2009-08-13 18:07                                                               ` martin rudalics
@ 2009-08-14  1:13                                                                 ` Lennart Borgman
  2009-08-14  7:18                                                                   ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-14  1:13 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3274 bytes --]

On Thu, Aug 13, 2009 at 8:07 PM, martin rudalics<rudalics@gmx.at> wrote:

>> I am not sure why you want to do something like the above. However you
>> introduce a new element here: relaxing of the requirements.
>
> Not only - in the first step I would make them stronger.
>
>> Do you really want to do that? Or did I misunderstand you?
>
> When I change the size of a particular window on one end of my frame I
> don't want Emacs to change the sizes of windows at the other end.
> Changes should be "as local as possible".  For example, when I drag a
> modeline I usually do not expect the sizes of windows not adjacent to
> that modeline change unless Emacs has no other choice.

I see. But would not that be easy to implement with the algorithm I suggested?

You just have to find the window subtree that is adjecent to the
modeline and apply the algorithm there. (With new temporary
restrictions there. These things must of course be added to the
algorithm, but I can't see any fundamental problem with it.)

What problems do you see with that?


>> More seriously: if you are changing the rules, then please tell what
>> rules you want to use see we can see if the problem is solveable with
>> your new rules.
>
> What rules?  Please tell me _how_ your algorithm would handle a single
> `enlarge-window' command.  Which other windows would change in which
> order?  How would new window sizes relate to the old ones?


A very important idea in the algorithm is that it works with all the
child windows on level at once. You compute all the sizes on that
level and then you apply them. (So a new function in C for applying
the changes per sublevel is needed.)

To apply enlarge-window (or any similar command)  -- or, VERY
important, rather what it does --- simply set fix size restrictions on
that windows size (to the desired size) and other windows (to their
current sizes) on that level that is not adjecent to the window that
we try to enlarge.

If this fails then then take away the restrictions on windows
next-adjecent and try again. Repeat until success or final failure.
(The order of repetioins is just the lenght of the list, there is no
recursions, so it is no performance problem.)

Of course I did not implement an easy way to apply the restrictions
right now but that is easily added (except for my clumsiness... ;-).


Note: The existing enlarge-window should in this scenario go away and
a new one should be implemented (probably in elis then) that does the
above things. The same apply to the other window handling routines
that does similar things.



I attach yet a new version of my little play thing for this. I have
not tried to implement something that handles restrictions as per
above there. You could at the moment simulate it by setting the
restrictions for max and min sizes for a window. It is not difficult
to add the restrictions, it just one of those small things where I
tend to make a lot of small mistakes a la or/and etc so I do not want
to do it right now. I need some more minutes to get it done. (What I
have done in this version is making it a bit easier to play with and
added comments about how I think it should tie into the C level.)


> martin
>

[-- Attachment #2: win-alg.el --]
[-- Type: text/plain, Size: 10032 bytes --]

;;; win-alg.el --- Window size computation
;;
;; Author: Lennart Borgman (lennart O borgman A gmail O com)
;; Created: 2009-08-12 Wed
;; Version: 0.2
;; Last-Updated: 2009-08-13 Thu
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Window creation etc

;;(defun wa-make-window (width wumin wumax height hmin hmax)
(defun wa-make-window (name width wumin wumax)
  (list (list 'name name)            ;; Easier communication ...
        (list 'child nil)            ;; Child windows
        (list 'usr-size wumin wumax) ;; Restrictions
        (list 'req-size nil nil)     ;; Slot for computated requirements, wumin wumax
        (list 'set-size nil width)       ;; Slot for setting new size
        ))

;; Fix-me: Make defmacro to make those getters setters... - including
;; checks...

(defun wa-name  (window) (nth 1 (nth 0 window))) ;; 'name
(defun wa-child (window) (nth 1 (nth 1 window))) ;; 'child
(defun wa-wumin (window) (nth 1 (nth 2 window))) ;; 'usr-size
(defun wa-wumax (window) (nth 2 (nth 2 window))) ;; 'usr-size
(defun wa-wrmin (window) (nth 1 (nth 3 window))) ;; 'req-size
(defun wa-wrmax (window) (nth 2 (nth 3 window))) ;; 'req-size
(defun wa-wset  (window) (nth 2 (nth 4 window))) ;; 'set-size

(defun wa-set-name   (window name)  (setcar (nthcdr 1 (nth 0 window)) name))  ;; 'name
(defun wa-set-child  (window child) (setcar (nthcdr 1 (nth 1 window)) child)) ;; 'child
(defun wa-set-wumin  (window wumin) (setcar (nthcdr 1 (nth 2 window)) wumin)) ;; 'usr-size
(defun wa-set-wumax  (window wumax) (setcar (nthcdr 2 (nth 2 window)) wumax)) ;; 'usr-size
(defun wa-set-wrmin  (window wumin) (setcar (nthcdr 1 (nth 3 window)) wumin)) ;; 'req-size
(defun wa-set-wrmax  (window wumax) (setcar (nthcdr 2 (nth 3 window)) wumax)) ;; 'req-size
(defun wa-set-wset   (window size)  (setcar (nthcdr 2 (nth 4 window)) size))  ;; 'set-size

(defun wa-set-flag   (window flag)  (setcar (nthcdr 1 (nth 4 window)) flag))  ;; 'set-size

(defvar wa-failed nil)

(defun wa-error (format-string &rest args)
  (setq wa-failed t)
  (apply 'message (propertize format-string 'face 'secondary-selection)
         args)
  (throw 'wa-error nil))

(defun wa-win-error (win format-string &rest args)
  (wa-set-flag win (concat "FAILED: " (apply 'format format-string args)))
  (apply 'wa-error format-string args))

(defun wa-set-child-windows (parent vertical &rest sizes)
  (unless wa-failed (assert (< 1 (length sizes)) t))
  (let (children
        (num 0))
    (setq children (mapcar (lambda (size)
                             (setq num (1+ num))
                             (if vertical
                                 (wa-make-window (format "%s-%d" (wa-name parent) num)
                                                 nil
                                                 (nth 0 size)
                                                 (nth 1 size))))
                           sizes))
    (wa-set-child parent children)
    parent))

(defun wa-check-fit (win)
  (let ((wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (wrmin (wa-wrmin win))
        (wrmax (wa-wrmax win))
        (wset  (wa-wset win)))
    (wa-set-flag win 'FAILED)
    ;; Top window
    (when (and wset wrmin)
      (unless (<= wrmin wset)
        (wa-win-error win "Window %s set size too small=%d, min=%d" (wa-name win) wset wrmin)))
    (when (and wset wrmax)
      (unless (>= wrmax wset)
        (wa-win-error win "Window %s set size too large=%d, max=%s" (wa-name win) wset wrmax)))
    ;; All
    (when (and wumax wrmin)
      (unless (<= wrmin wumax)
        (wa-win-error win "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wrmin wumax)))
    (when (and wrmax wumin)
      (unless (>= wrmax wumin)
        (wa-win-error win "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wrmax wumin)))
    (wa-set-flag win 'OK)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Computation of sizes

(defun wa-clear-computed (win)
  (wa-set-wrmin win nil)
  (wa-set-wrmax win nil)
  (wa-set-wset  win nil)
  (dolist (c (wa-child win))
    (wa-clear-computed c)))

(defun wa-init-fail-flag (win)
  (wa-set-flag win 'INIT)
  (dolist (c (wa-child win))
    (wa-init-fail-flag c)))

(defun wa-compute-required (win)
  "Walk up collecting needed sizes."
  (let ((childs (wa-child win))
        (wumin (wa-wumin win))
        (wumax (wa-wumax win))
        (cmin 0)
        (cmax nil))
    (when childs
      ;; Clear childs set sizes, we do not know them here
      (dolist (c childs) (wa-set-wset c nil))
      (dolist (c childs)
        (let* ((res (wa-compute-required c))
               (res-min (nth 0 res))
               (res-max (nth 1 res)))
          ;; Just sum the MIN
          (setq cmin (+ cmin res-min))
          (if res-max
              ;; ... ok, let us sum MAX to see how big we can be ...
              (if (numberp cmax)
                  (setq cmax (+ cmax res-max))
                (setq cmax res-max))
            ;; Hurray, at least one child can grow!
            (setq cmax nil)))))
    (when wumin (setq cmin (max wumin (or cmin wumin))))
    (when wumax (setq cmax (min wumax (or cmax wumax))))
    ;; Sanity
    (when (= cmin 0) (setq cmin 1))
    (unless wa-failed (assert (or (not cmin) (<= 1 cmin)) t))
    (unless wa-failed (assert (or (not cmax) (<= 1 cmax)) t))
    (wa-set-wrmin win cmin)
    (wa-set-wrmax win cmax)
    (wa-check-fit win)
    (list (wa-wrmin win)
          (wa-wrmax win))))

(defun wa-compute-resulting (win strategy)
  "Walk down compute resulting sizes and apply them."
  ;; NOTE: This is the part that can tie into the C functions. This
  ;; computes the sizes to apply level by level when going down.
  ;;
  ;; To apply it to the C level I suggest implementing a function in C
  ;; that accept a list of sizes, one size per window on that
  ;; level. Walk the C structures in parallell with this when applying
  ;; the sizes. (I do not think it is necessary to have this code in
  ;; C.)
  (when (wa-child win)
    (let ((cmin   (wa-wrmin  win))
          (cmax   (wa-wrmax  win))
          (width  (wa-wset win))
          (childs (wa-child win)))
      (case strategy
        ('eq-sizes
         (let ((rest-width width)
               (goal (/ width (length childs)))
               (rest-childs (copy-sequence childs)))
           ;; Clear childs
           (dolist (c childs) (wa-set-wset c nil))
           ;; Check child min requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmin (wa-wrmin c)))
               (when (and wrmin (<= goal wrmin))
                 (wa-set-wset c (wa-wrmin c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmin c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Check child max requirements
           (dolist (c (copy-sequence rest-childs))
             (let ((wrmax (wa-wrmax c)))
               (when (and wrmax (>= goal wrmax))
                 (wa-set-wset c (wa-wrmax c))
                 (setq rest-childs (delete c rest-childs))
                 (setq rest-width (- rest-width (wa-wrmax c))))))
           (setq goal (/ rest-width (length childs)))
           ;; Distribute the rest, taking care of roundings
           (wa-set-wset (car rest-childs)
                        (- rest-width (* goal (1- (length rest-childs)))))
           (dolist (c (cdr rest-childs))
             (wa-set-wset c goal))))
        (t (wa-error "Unknown strategy: %s" strategy)))
      ;; Check
      (let ((w 0))
        (dolist (c childs)
          (let ((wset (wa-wset c)))
            (unless wa-failed (assert (<= 0 wset) t))
            (setq w (+ w wset))))
        (unless (= w (wa-wset win))
          (wa-error "Bad set sizes child sum w=%d, win width=%d" w (wa-wset win))))
      ;; Call the suggested C level function here for example.
      ;; .......
      ;; Walk down
      (dolist (c childs)
        (wa-compute-resulting c strategy)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Testing part

(defvar wa-root-window nil)

(defun wa-add-test-childs ()
  (wa-set-child-windows wa-root-window t
                         '(nil 12)
                         '(14 nil)
                         '(nil nil)
                         '(3 nil)
                         )
  (wa-set-child-windows (car (wa-child wa-root-window)) t
                        '(nil nil)
                        '(8 15))
  )

;; (wa-child wa-root-window)
;; (wa-wset wa-root-window)
;; (wa-wumin wa-root-window)
;; (wa-wumax wa-root-window)
;; (wa-clear-computed wa-root-window)

;; Setup
(setq wa-root-window (wa-make-window "Root" 80 nil nil))
(setq wa-root-window (wa-make-window "Root" 80 nil 8))
(setq wa-root-window (wa-make-window "Root" 80 nil 6))
(setq wa-root-window (wa-make-window "Root" 80 5 nil))
(setq wa-root-window (wa-make-window "Root" 43 15 nil))
(setq wa-root-window (wa-make-window "Root" 18 15 nil))
(setq wa-root-window (wa-make-window "Root" 15 15 nil))

(wa-add-test-childs)
(wa-init-fail-flag     wa-root-window)
(setq wa-failed nil)

;; Show state now in case we want to stop on errors
(describe-variable    'wa-root-window)

;; Compute required, may fail.
(catch 'wa-error
  (wa-compute-required wa-root-window)

  ;; Now it should not fail
  (wa-compute-resulting  wa-root-window 'eq-sizes))

;; Show final state
(describe-variable    'wa-root-window)
(with-current-buffer (help-buffer)
  (hi-lock-face-buffer "\"FAILED.*\"" 'hi-red-b)
  (hi-lock-face-buffer "OK" 'hi-green)
  (hi-lock-face-buffer "INIT" 'hi-blue))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; win-alg.el ends here

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

* Re: moving window handling into lisp
  2009-08-13 18:09                                         ` martin rudalics
@ 2009-08-14  1:47                                           ` Stephen J. Turnbull
  2009-08-14  7:17                                             ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-14  1:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

martin rudalics writes:

 > It's easy to explain: When dragging a modeline, you probably want to
 > shrink/enlarge the bottom-most windows above the modeline and
 > enlarge/shrink the topmost windows below the modeline first.

Abstractly, I agree, but note that some UIs don't do that.  For
example, in spreadsheets typically dragging on a column divider
resizes only the column immediately to its left, and pushes or pulls
the columns to the right rigidly.  I think that behavior is pretty
plausible for multiwindow configurations in an editor, too, but
perhaps not as common as the "adjust adjoining windows" behavior you
proposed.





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

* Re: moving window handling into lisp
  2009-08-13  9:54                                     ` martin rudalics
  2009-08-13 17:00                                       ` Stefan Monnier
@ 2009-08-14  6:42                                       ` Richard Stallman
  2009-08-14  7:18                                         ` martin rudalics
  2009-08-14 15:39                                         ` Stefan Monnier
  1 sibling, 2 replies; 130+ messages in thread
From: Richard Stallman @ 2009-08-14  6:42 UTC (permalink / raw)
  To: martin rudalics; +Cc: monnier, emacs-devel

    Deleting windows currently is an inherent part of resizing, otherwise
    `window-min-height' and `window-min-width' wouldn't make sense.  Where
    and how would you handle these variables?

If window resizing is done in Lisp, the Lisp code could delete windows
whenever it wants to.  It could work using a low-level resize
primitive that would never delete windows.

This might require a primitive to undelete a window,
for the sake of dragging a boundary all the way across and back.
I'd guess that is not very hard to add.





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

* Re: moving window handling into lisp
  2009-08-14  1:47                                           ` Stephen J. Turnbull
@ 2009-08-14  7:17                                             ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-14  7:17 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Stefan Monnier, emacs-devel

 >  > It's easy to explain: When dragging a modeline, you probably want to
 >  > shrink/enlarge the bottom-most windows above the modeline and
 >  > enlarge/shrink the topmost windows below the modeline first.
 >
 > Abstractly, I agree, but note that some UIs don't do that.  For
 > example, in spreadsheets typically dragging on a column divider
 > resizes only the column immediately to its left, and pushes or pulls
 > the columns to the right rigidly.  I think that behavior is pretty
 > plausible for multiwindow configurations in an editor, too, but
 > perhaps not as common as the "adjust adjoining windows" behavior you
 > proposed.

I don't quite understand what you mean.  "resizes only" could stand for
resizing _just one_ window which would violate our invariant that all
windows must form a frame and the (implicit) assumption that the size of
the frame must not change when dragging a vertical divider.

Note that I was talking about the present behavior.  Richard spent some
time on debugging it, IIRC.  Basically, it wouldn't be difficult to drag
the remaining windows "rigidly".  Implicitly, this would be realized by
resizing some last sibling in that case.  The point is that the behavior
must be implemented consistently.

martin




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

* Re: moving window handling into lisp
  2009-08-14  1:13                                                                 ` Lennart Borgman
@ 2009-08-14  7:18                                                                   ` martin rudalics
  2009-08-14 11:21                                                                     ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-14  7:18 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > You just have to find the window subtree that is adjecent to the
 > modeline and apply the algorithm there. (With new temporary
 > restrictions there. These things must of course be added to the
 > algorithm, but I can't see any fundamental problem with it.)
 >
 > What problems do you see with that?

None, if the adjacent subtree can handle the request.  All sorts of
otherwise.  That's where the "temporary restrictions" you mention must
be relaxed.

 > A very important idea in the algorithm is that it works with all the
 > child windows on level at once. You compute all the sizes on that
 > level and then you apply them. (So a new function in C for applying
 > the changes per sublevel is needed.)
 >
 > To apply enlarge-window (or any similar command)  -- or, VERY
 > important, rather what it does --- simply set fix size restrictions on
 > that windows size (to the desired size) and other windows (to their
 > current sizes) on that level that is not adjecent to the window that
 > we try to enlarge.
 >
 > If this fails then then take away the restrictions on windows
 > next-adjecent and try again. Repeat until success or final failure.
 > (The order of repetioins is just the lenght of the list, there is no
 > recursions, so it is no performance problem.)

The recursion (or backtracking) is right with the "take away the
restrictions on windows next-adjecent and try again".  It doesn't help
if you remove that crucial detail from your algorithm and leave it to
the caller to handle it.

 > Of course I did not implement an easy way to apply the restrictions
 > right now but that is easily added (except for my clumsiness... ;-).

Applying the restrictions is trivial.  The point is in finding the right
set of restrictions.  Compare how modeline dragging is done in Emacs 21
and Emacs 22.  The differences show up come because Emacs 22 does not
relax the respective restrictions.  OTOH relaxing them got us into all
sorts of troubles in Emacs 21.

 > Note: The existing enlarge-window should in this scenario go away and
 > a new one should be implemented (probably in elis then) that does the
 > above things. The same apply to the other window handling routines
 > that does similar things.

As long as we can't at least emulate the present (poor) behavior ...

martin




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

* Re: moving window handling into lisp
  2009-08-14  6:42                                       ` Richard Stallman
@ 2009-08-14  7:18                                         ` martin rudalics
  2009-08-14 20:56                                           ` Richard Stallman
  2009-08-14 15:39                                         ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-14  7:18 UTC (permalink / raw)
  To: rms; +Cc: monnier, emacs-devel

 > If window resizing is done in Lisp, the Lisp code could delete windows
 > whenever it wants to.  It could work using a low-level resize
 > primitive that would never delete windows.

That's exactly what Stefan has in mind, yes.

 > This might require a primitive to undelete a window,
 > for the sake of dragging a boundary all the way across and back.
 > I'd guess that is not very hard to add.

Just that Stefan wants "undelete a window" behave like "create a window
with a new identity and the appearance of the old one".

martin




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

* Re: moving window handling into lisp
  2009-08-14  7:18                                                                   ` martin rudalics
@ 2009-08-14 11:21                                                                     ` Lennart Borgman
  2009-08-14 13:21                                                                       ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-14 11:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

On Fri, Aug 14, 2009 at 9:18 AM, martin rudalics<rudalics@gmx.at> wrote:

> None, if the adjacent subtree can handle the request.  All sorts of
> otherwise.  That's where the "temporary restrictions" you mention must
> be relaxed.


Ok. Could you please then summarize what rules you have thought of
here? What is it that should be relaxed? What do you want to happen
then? What problems do you see for different solutions there? (Not the
algorithms, just the rules, please.)


>> A very important idea in the algorithm is that it works with all the
>> child windows on level at once. You compute all the sizes on that
>> level and then you apply them. (So a new function in C for applying
>> the changes per sublevel is needed.)
>>
>> To apply enlarge-window (or any similar command)  -- or, VERY
>> important, rather what it does --- simply set fix size restrictions on
>> that windows size (to the desired size) and other windows (to their
>> current sizes) on that level that is not adjecent to the window that
>> we try to enlarge.
>>
>> If this fails then then take away the restrictions on windows
>> next-adjecent and try again. Repeat until success or final failure.
>> (The order of repetioins is just the lenght of the list, there is no
>> recursions, so it is no performance problem.)
>
> The recursion (or backtracking) is right with the "take away the
> restrictions on windows next-adjecent and try again".  It doesn't help
> if you remove that crucial detail from your algorithm and leave it to
> the caller to handle it.


Sorry, I must have expressed myself unclear in some way.

There is no recursion in my example above, just a simple iteration
when taking away the restrictions. One iteration for every sibling
window where you take away the restriction.

There is no "crucial details" left out. I just did not have time to
write an example of enlarge-window and left it to your imagination
here.

I will try to find some minutes in do write enlarge-window this way,
but it would help very much if you tried to summarize your views of
the restrictions. (As I already said above.)


> Applying the restrictions is trivial.  The point is in finding the right
> set of restrictions.


Yes. But finding a useful set of restrictions can't be done without
considering the structure of the code. And that is what I am trying to
do.

Without that you might get the impression that the problem is
np-complete while it is the structure of the current code that perhaps
(as I see it) is the problem instead.


>> Note: The existing enlarge-window should in this scenario go away and
>> a new one should be implemented (probably in elis then) that does the
>> above things. The same apply to the other window handling routines
>> that does similar things.
>
> As long as we can't at least emulate the present (poor) behavior ...

;-)

Doing it the way I suggest you can slightly change the rules so we can
avoid some of the troubles. But to show that we must get into some
more concrete exampel I guess. So please (again) tell me some example
of rules that you find troublesome.

You may have some very good point that I am totally missing. That will
show probably show up if we consider some more concrete example and
rules.


> martin
>




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

* Re: moving window handling into lisp
  2009-08-14 11:21                                                                     ` Lennart Borgman
@ 2009-08-14 13:21                                                                       ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-14 13:21 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

 > Ok. Could you please then summarize what rules you have thought of
 > here? What is it that should be relaxed? What do you want to happen
 > then? What problems do you see for different solutions there? (Not the
 > algorithms, just the rules, please.)

How can I give you rules if I don't know what kind of rules you expect.
I can only guess, so let's take an example.  Suppose I have two windows
w1 and w2 one above the other:

  ------
| w1   |
|------|
| w2   |
  ------

When I want to enlarge w1 by one line I suppose I can do something
like

(wa-set-wrmin w1 (1+ (window-height w1)))
(wa-set-wrmax w1 (1+ (window-height w1)))
(wa-set-wrmin w2 (1- (window-height w2)))
(wa-set-wrmax w2 (1- (window-height w2)))

that is start with the tightest possible restriction.  Now suppose I
have a third window w3

  ------
| w1   |
|------|
| w2   |
|------|
|      |
| w3   |
|      |
  ------

want to enlarge w1, but w2 has minimum height or is fixed-size (the
latter is an example of a pending bug).  In this case I probably first
try the same as before, fail, and then do

(wa-set-wrmin w1 (1+ (window-height w1)))
(wa-set-wrmax w1 (1+ (window-height w1)))
(wa-set-wrmin w3 (1- (window-height w3)))
(wa-set-wrmax w3 (1- (window-height w3)))

  ------
| w1   |
|------|
| w2   |
|------|
|      |
| w3   |
|      |
  ------

If w3 has two subwindows side-by-side as in

  -------
| w1    |
|-------|
| w2    |
|-------|
|   |   |
| w4|w5 |
|   |   |
  -------

I probably have to do

(wa-set-wrmin w1 (1+ (window-height w1)))
(wa-set-wrmax w1 (1+ (window-height w1)))
(wa-set-wrmin w4 (1- (window-height w4)))
(wa-set-wrmax w4 (1- (window-height w4)))
(wa-set-wrmin w5 (1- (window-height w5)))
(wa-set-wrmax w5 (1- (window-height w5)))

Now is that the way your algorithm is supposed to be used?

[...]
 > You may have some very good point that I am totally missing. That will
 > show probably show up if we consider some more concrete example and
 > rules.

Just tell me whether I got it right in my examples above or whether the
"size applying stuff" is something you want to resolve with the help of
another strategy within

       (case strategy
         ('eq-sizes
	   ....

martin




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

* Re: moving window handling into lisp
  2009-08-14  6:42                                       ` Richard Stallman
  2009-08-14  7:18                                         ` martin rudalics
@ 2009-08-14 15:39                                         ` Stefan Monnier
  2009-08-14 15:42                                           ` Lennart Borgman
  2009-08-15 10:12                                           ` martin rudalics
  1 sibling, 2 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-14 15:39 UTC (permalink / raw)
  To: rms; +Cc: martin rudalics, emacs-devel

> This might require a primitive to undelete a window,
> for the sake of dragging a boundary all the way across and back.
> I'd guess that is not very hard to add.

Actually, regardless of whether it can introduce problems (which it
could), I think this is not a good idea: dragging modelines and
scrollbars should not be construed as a way to delete windows.
So no amount of dragging modelines should be able to delete windows.

OTOH, there is a situations where we have to live with it: when resizing
a frame "all the way across and back", we may want/need to delete
a window and then resurrect it.  Not sure what's the best way to deal
with this:
- either somehow make it possible to undelete windows (I'd *much* rather
  not, but maybe if we make it sufficiently restrictive it'd be OK).
- or maybe avoid deleting the window in this case, instead leave it
  a size-0, and delete it at some later time (when would that be?).
- prevent frame resizing that would require deleting a window.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-14 15:39                                         ` Stefan Monnier
@ 2009-08-14 15:42                                           ` Lennart Borgman
  2009-08-14 18:26                                             ` Stefan Monnier
  2009-08-15 10:12                                           ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-14 15:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, rms, emacs-devel

On Fri, Aug 14, 2009 at 5:39 PM, Stefan Monnier<monnier@iro.umontreal.ca> wrote:

> - prevent frame resizing that would require deleting a window.

I vote for this one. It is less confusing.




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

* Re: moving window handling into lisp
  2009-08-14 15:42                                           ` Lennart Borgman
@ 2009-08-14 18:26                                             ` Stefan Monnier
  0 siblings, 0 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-14 18:26 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: martin rudalics, rms, emacs-devel

>> - prevent frame resizing that would require deleting a window.
> I vote for this one. It is less confusing.

I'd tend to agree, but I'm not sure if it can always be done, and how.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-14  7:18                                         ` martin rudalics
@ 2009-08-14 20:56                                           ` Richard Stallman
  2009-08-15 10:12                                             ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Richard Stallman @ 2009-08-14 20:56 UTC (permalink / raw)
  To: martin rudalics; +Cc: monnier, emacs-devel

    Just that Stefan wants "undelete a window" behave like "create a window
    with a new identity and the appearance of the old one".

It might be good enough in practice.  I am not sure.




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

* Re: moving window handling into lisp
  2009-08-14 20:56                                           ` Richard Stallman
@ 2009-08-15 10:12                                             ` martin rudalics
  2009-08-15 19:47                                               ` Stefan Monnier
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-15 10:12 UTC (permalink / raw)
  To: rms; +Cc: monnier, emacs-devel

 >     Just that Stefan wants "undelete a window" behave like "create a window
 >     with a new identity and the appearance of the old one".
 >
 > It might be good enough in practice.  I am not sure.

It's not good enough when `adjust-window-trailing-edge' inadvertently
deletes a window.

martin




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

* Re: moving window handling into lisp
  2009-08-14 15:39                                         ` Stefan Monnier
  2009-08-14 15:42                                           ` Lennart Borgman
@ 2009-08-15 10:12                                           ` martin rudalics
  2009-08-15 11:02                                             ` Lennart Borgman
  2009-08-15 19:51                                             ` Stefan Monnier
  1 sibling, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-15 10:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

 > OTOH, there is a situations where we have to live with it: when resizing
 > a frame "all the way across and back", we may want/need to delete
 > a window and then resurrect it.  Not sure what's the best way to deal
 > with this:
 > - either somehow make it possible to undelete windows (I'd *much* rather
 >   not, but maybe if we make it sufficiently restrictive it'd be OK).

We'd eventually have to GC such windows to avoid leaks.

 > - or maybe avoid deleting the window in this case, instead leave it
 >   a size-0, and delete it at some later time (when would that be?).

Same as above.  We'd end up accumulating zero-sized windows.

 > - prevent frame resizing that would require deleting a window.

Emacs not honoring a window manager's request?

I think we can live with deleting windows in that case and _not_
resurrecting them when the frame is resized.

martin




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

* Re: moving window handling into lisp
  2009-08-15 10:12                                           ` martin rudalics
@ 2009-08-15 11:02                                             ` Lennart Borgman
  2009-08-15 12:44                                               ` martin rudalics
  2009-08-15 19:51                                             ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-15 11:02 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Stefan Monnier, rms

On Sat, Aug 15, 2009 at 12:12 PM, martin rudalics<rudalics@gmx.at> wrote:

>> - prevent frame resizing that would require deleting a window.
>
> Emacs not honoring a window manager's request?
>
> I think we can live with deleting windows in that case and _not_
> resurrecting them when the frame is resized.


We can both honor the window manager request and avoiding deleting windows.

Just show a single window saying the windows does not fit when the
frame gets too small. Put back the windows then the frame gets bigger.




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

* Re: moving window handling into lisp
  2009-08-15 11:02                                             ` Lennart Borgman
@ 2009-08-15 12:44                                               ` martin rudalics
  2009-08-15 13:35                                                 ` David Kastrup
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-15 12:44 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel, Stefan Monnier, rms

 > We can both honor the window manager request and avoiding deleting windows.
 >
 > Just show a single window saying the windows does not fit when the
 > frame gets too small. Put back the windows then the frame gets bigger.

Where are these windows in the period starting when you show the single
window and ending when you put them back?

martin




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

* Re: moving window handling into lisp
  2009-08-15 12:44                                               ` martin rudalics
@ 2009-08-15 13:35                                                 ` David Kastrup
  2009-08-15 13:39                                                   ` Lennart Borgman
                                                                     ` (2 more replies)
  0 siblings, 3 replies; 130+ messages in thread
From: David Kastrup @ 2009-08-15 13:35 UTC (permalink / raw)
  To: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> We can both honor the window manager request and avoiding deleting windows.
>>
>> Just show a single window saying the windows does not fit when the
>> frame gets too small. Put back the windows then the frame gets bigger.
>
> Where are these windows in the period starting when you show the single
> window and ending when you put them back?

I find it saner to refuse the resize request (perfectly valid behavior)
until the frame-internal window configuration allows it.

-- 
David Kastrup





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

* Re: moving window handling into lisp
  2009-08-15 13:35                                                 ` David Kastrup
@ 2009-08-15 13:39                                                   ` Lennart Borgman
  2009-08-15 16:11                                                     ` martin rudalics
  2009-08-15 15:07                                                   ` Jan Djärv
  2009-08-15 16:07                                                   ` martin rudalics
  2 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-15 13:39 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

On Sat, Aug 15, 2009 at 3:35 PM, David Kastrup<dak@gnu.org> wrote:
> martin rudalics <rudalics@gmx.at> writes:
>
>>> We can both honor the window manager request and avoiding deleting windows.
>>>
>>> Just show a single window saying the windows does not fit when the
>>> frame gets too small. Put back the windows then the frame gets bigger.
>>
>> Where are these windows in the period starting when you show the single
>> window and ending when you put them back?


This could be a special case. Just change the pointer to the (root)
window and save the old pointer.


> I find it saner to refuse the resize request (perfectly valid behavior)
> until the frame-internal window configuration allows it.


I have no idea if it is valid. It is on w32, but what about other
window managers?

There are also similar (but without windows identity problems) when
restoring a saved window configuration.




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

* Re: moving window handling into lisp
  2009-08-15 13:35                                                 ` David Kastrup
  2009-08-15 13:39                                                   ` Lennart Borgman
@ 2009-08-15 15:07                                                   ` Jan Djärv
  2009-08-15 15:38                                                     ` David Kastrup
  2009-08-15 16:07                                                   ` martin rudalics
  2 siblings, 1 reply; 130+ messages in thread
From: Jan Djärv @ 2009-08-15 15:07 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel



David Kastrup skrev:
> martin rudalics <rudalics@gmx.at> writes:
> 
>>> We can both honor the window manager request and avoiding deleting windows.
>>>
>>> Just show a single window saying the windows does not fit when the
>>> frame gets too small. Put back the windows then the frame gets bigger.
>> Where are these windows in the period starting when you show the single
>> window and ending when you put them back?
> 
> I find it saner to refuse the resize request (perfectly valid behavior)
> until the frame-internal window configuration allows it.
> 

You can't in X11 (well maybe by fiddling with WM size hints, but it isn't 
guaranteed to work).  There is no resize request, just an event telling you 
"you have been resized, adapt".

Override redirect would work, but that is so bad.

	Jan D.




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

* Re: moving window handling into lisp
  2009-08-15 15:07                                                   ` Jan Djärv
@ 2009-08-15 15:38                                                     ` David Kastrup
  0 siblings, 0 replies; 130+ messages in thread
From: David Kastrup @ 2009-08-15 15:38 UTC (permalink / raw)
  To: emacs-devel

Jan Djärv <jan.h.d@swipnet.se> writes:

> David Kastrup skrev:
>> martin rudalics <rudalics@gmx.at> writes:
>>
>>>> We can both honor the window manager request and avoiding deleting windows.
>>>>
>>>> Just show a single window saying the windows does not fit when the
>>>> frame gets too small. Put back the windows then the frame gets bigger.
>>> Where are these windows in the period starting when you show the single
>>> window and ending when you put them back?
>>
>> I find it saner to refuse the resize request (perfectly valid behavior)
>> until the frame-internal window configuration allows it.
>>
>
> You can't in X11 (well maybe by fiddling with WM size hints, but it
> isn't guaranteed to work).  There is no resize request, just an event
> telling you "you have been resized, adapt".
>
> Override redirect would work, but that is so bad.

Strange.  I am pretty sure that in ancient Xt times this was the way
things were done.  Maybe the WM size hints are supposed to have replaced
these mechanism.  If so, a step backwards.

-- 
David Kastrup





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

* Re: moving window handling into lisp
  2009-08-15 13:35                                                 ` David Kastrup
  2009-08-15 13:39                                                   ` Lennart Borgman
  2009-08-15 15:07                                                   ` Jan Djärv
@ 2009-08-15 16:07                                                   ` martin rudalics
  2009-08-15 18:21                                                     ` Stephen J. Turnbull
  2 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-15 16:07 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

 > I find it saner to refuse the resize request (perfectly valid behavior)
 > until the frame-internal window configuration allows it.

Depends on your mileage.  A tiling WM would not be really amused if
Emacs refused to resize its frame.

martin




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

* Re: moving window handling into lisp
  2009-08-15 13:39                                                   ` Lennart Borgman
@ 2009-08-15 16:11                                                     ` martin rudalics
  2009-08-15 16:19                                                       ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-15 16:11 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: David Kastrup, emacs-devel

 > This could be a special case. Just change the pointer to the (root)
 > window and save the old pointer.

Well, and what would we do then?  Could you sketch a dialogue?

 >> I find it saner to refuse the resize request (perfectly valid behavior)
 >> until the frame-internal window configuration allows it.
 >
 > I have no idea if it is valid. It is on w32, but what about other
 > window managers?

We already do have a lot of complaints from people using some less
standard WMs.  Most of them run like "Emacs is the only application that
does (or does not) behave that way."

 > There are also similar (but without windows identity problems) when
 > restoring a saved window configuration.

Indeed.  And asking questions while a saved desktop gets restored could
be annoying as well.  BTW, what kind of questions would you ask here?

martin




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

* Re: moving window handling into lisp
  2009-08-15 16:11                                                     ` martin rudalics
@ 2009-08-15 16:19                                                       ` Lennart Borgman
  2009-08-15 17:37                                                         ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-15 16:19 UTC (permalink / raw)
  To: martin rudalics; +Cc: David Kastrup, emacs-devel

On Sat, Aug 15, 2009 at 6:11 PM, martin rudalics<rudalics@gmx.at> wrote:
>> This could be a special case. Just change the pointer to the (root)
>> window and save the old pointer.
>
> Well, and what would we do then?  Could you sketch a dialogue?


My idea is just to display a window with information about what
happened and how to get the windows back. Is not that enough?


> Indeed.  And asking questions while a saved desktop gets restored could
> be annoying as well.  BTW, what kind of questions would you ask here?


Same as above (not the message, the idea).




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

* Re: moving window handling into lisp
  2009-08-15 16:19                                                       ` Lennart Borgman
@ 2009-08-15 17:37                                                         ` martin rudalics
  2009-08-15 18:18                                                           ` Lennart Borgman
  2009-08-15 19:05                                                           ` Stephen J. Turnbull
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-15 17:37 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel

 >> Well, and what would we do then?  Could you sketch a dialogue?
 >
 > My idea is just to display a window with information about what
 > happened and how to get the windows back. Is not that enough?

Suppose the Emacs frame is a window in a tiling WM that just asked Emacs
to shrink that frame because the user needs it for another application.
Do you think that user would care about what Emacs tells how to get back
some old window configuration?  And what would Emacs tell?  Something
like "try to delete some windows you currently can't see but could see
if you resized your frame to what it was before you wanted to shrink
it and after that carry on with your stupid application"?

Believe me.  Deleting windows in some way is the one bullet we do have
to bite here.

martin




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

* Re: moving window handling into lisp
  2009-08-15 17:37                                                         ` martin rudalics
@ 2009-08-15 18:18                                                           ` Lennart Borgman
  2009-08-16 10:25                                                             ` martin rudalics
  2009-08-15 19:05                                                           ` Stephen J. Turnbull
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-15 18:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

On Sat, Aug 15, 2009 at 7:37 PM, martin rudalics<rudalics@gmx.at> wrote:
>>> Well, and what would we do then?  Could you sketch a dialogue?
>>
>> My idea is just to display a window with information about what
>> happened and how to get the windows back. Is not that enough?
>
> Suppose the Emacs frame is a window in a tiling WM that just asked Emacs
> to shrink that frame because the user needs it for another application.
> Do you think that user would care about what Emacs tells how to get back
> some old window configuration?  And what would Emacs tell?  Something
> like "try to delete some windows you currently can't see but could see
> if you resized your frame to what it was before you wanted to shrink
> it and after that carry on with your stupid application"?


Maybe that is a case where we want to delete windows. I am not quite
convinced yet.

However in that case I would still suggest showing one window
temporary and explain and give alternatives there. I can't see that it
is worse than just deleting the windows. Just deleting the windows
might look like a bug - or maybe just not be noticed, be confusing.


> Believe me.  Deleting windows in some way is the one bullet we do have
> to bite here.
>
> martin
>




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

* Re: moving window handling into lisp
  2009-08-15 16:07                                                   ` martin rudalics
@ 2009-08-15 18:21                                                     ` Stephen J. Turnbull
  2009-08-16 10:25                                                       ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-15 18:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: David Kastrup, emacs-devel

martin rudalics writes:

 > Depends on your mileage.  A tiling WM would not be really amused if
 > Emacs refused to resize its frame.

Actually, it's Emacs that would be less than amused (more precisely,
the Emacs user).  The WM *will* resize the shell.  Emacs can fit its
content to that window or not, the WM does not care.  X will simply
clip Emacs to fit.

Just-call-me-Procrustes-ly y'rs,






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

* Re: moving window handling into lisp
  2009-08-15 17:37                                                         ` martin rudalics
  2009-08-15 18:18                                                           ` Lennart Borgman
@ 2009-08-15 19:05                                                           ` Stephen J. Turnbull
  2009-08-16 10:26                                                             ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-15 19:05 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lennart Borgman, emacs-devel

martin rudalics writes:

 > Suppose the Emacs frame is a window in a tiling WM that just asked
 > Emacs to shrink that frame because the user needs it for another
 > application.

[...]
 > Believe me.  Deleting windows in some way is the one bullet we do have
 > to bite here.

But you're wrong!  A (radical) alternative is to shrink the Emacs
windows as much as possible, then ignore further shrinkage.[1]
The WM will shrink the shell widget's window, and the GUI server will
then clip the Emacs frame to fit.

The rationale is that the WM has shrunk Emacs past the size where the
user can get any work done anyway, and in that case the user will have
to tell the WM to resize Emacs to a usable size to get work done.  Why
not just leave Emacs's internal configuration as it is?

That should work nicely on X11.  Whether this works on Windows or Aqua
I dunno.

Another possibility would be to withdraw (iconify) the Emacs frame if
it's ask to shrink to the point where its windows' minimum size
constraints are violated.  The bug reports will be great: "I was
shrinking Emacs and suddenly it collapsed into a nano-black hole,
started spraying X-rays, and cured my cancer!"

Footnotes: 
[1]  It might be a good idea to keep Emacs's "viewport" centered on
point in the selected Emacs window.  Then again, it might not.





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

* Re: moving window handling into lisp
  2009-08-15 10:12                                             ` martin rudalics
@ 2009-08-15 19:47                                               ` Stefan Monnier
  0 siblings, 0 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-15 19:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: rms, emacs-devel

>> Just that Stefan wants "undelete a window" behave like "create a window
>> with a new identity and the appearance of the old one".
>> It might be good enough in practice.  I am not sure.

> It's not good enough when `adjust-window-trailing-edge' inadvertently
> deletes a window.

Clearly, adjust-window-trailing-edge will be changed to never delete
windows (not even internally temporarily).


        Stefan




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

* Re: moving window handling into lisp
  2009-08-15 10:12                                           ` martin rudalics
  2009-08-15 11:02                                             ` Lennart Borgman
@ 2009-08-15 19:51                                             ` Stefan Monnier
  2009-08-16 10:26                                               ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-08-15 19:51 UTC (permalink / raw)
  To: martin rudalics; +Cc: rms, emacs-devel

>> - prevent frame resizing that would require deleting a window.
> Emacs not honoring a window manager's request?

Not necessarily: it could be done by instructing the window-manager
beforehand about the applicable resizing limits.  I've often found
windows that cannot be resized below some threshold (often dialog
windows).  Try it with `evolution', for example: I can't make it
narrower than 879 pixels.

> I think we can live with deleting windows in that case and _not_
> resurrecting them when the frame is resized.

With window-managers that do "opaque resizing" (pretty much standard
nowadays), that can be very problematic.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-15 18:18                                                           ` Lennart Borgman
@ 2009-08-16 10:25                                                             ` martin rudalics
  2009-08-16 11:14                                                               ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 10:25 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel

 > However in that case I would still suggest showing one window
 > temporary and explain and give alternatives there. I can't see that it
 > is worse than just deleting the windows. Just deleting the windows
 > might look like a bug - or maybe just not be noticed, be confusing.

It hardly was a problem recently.  What's more important IMHO is that
when we shrink a frame and re-enlarge it afterwards we should get the
previous sizes.  That's, however, more difficult to do.

martin




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

* Re: moving window handling into lisp
  2009-08-15 18:21                                                     ` Stephen J. Turnbull
@ 2009-08-16 10:25                                                       ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 10:25 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: David Kastrup, emacs-devel

 > Actually, it's Emacs that would be less than amused (more precisely,
 > the Emacs user).  The WM *will* resize the shell.  Emacs can fit its
 > content to that window or not, the WM does not care.  X will simply
 > clip Emacs to fit.

Indeed.  Thanks for filling in the gory details.

 > Just-call-me-Procrustes-ly y'rs,

I'll try to remember that ;-)

martin




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

* Re: moving window handling into lisp
  2009-08-15 19:05                                                           ` Stephen J. Turnbull
@ 2009-08-16 10:26                                                             ` martin rudalics
  2009-08-16 11:16                                                               ` Lennart Borgman
  2009-08-16 14:49                                                               ` Stephen J. Turnbull
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 10:26 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Lennart Borgman, emacs-devel

 >  > Suppose the Emacs frame is a window in a tiling WM that just asked
 >  > Emacs to shrink that frame because the user needs it for another
 >  > application.
 >
 > [...]
 >  > Believe me.  Deleting windows in some way is the one bullet we do have
 >  > to bite here.
 >
 > But you're wrong!  A (radical) alternative is to shrink the Emacs
 > windows as much as possible, then ignore further shrinkage.[1]

Ignoring `window-min-height' and `window-min-width' when shrinking
frames seems to do most of that job already.

 > The WM will shrink the shell widget's window, and the GUI server will
 > then clip the Emacs frame to fit.

This would usually clip off the echo area, I presume.

 > user can get any work done anyway, and in that case the user will have
 > to tell the WM to resize Emacs to a usable size to get work done.  Why
 > not just leave Emacs's internal configuration as it is?

When I resize an Emacs frame because I temporarily want to work with
another application I usually don't care about the state of Emacs'
windows.  Leaving the frame configuration in some not very orderly state
doesn't strike me as very clean.  So such behavior seems acceptable iff
I resize one Emacs frame because I want to continue working with another
Emacs frame.

 > That should work nicely on X11.  Whether this works on Windows or Aqua
 > I dunno.

I don't have the slightest idea.  Interaction with the WM is Jan's
department.

 > Another possibility would be to withdraw (iconify) the Emacs frame if
 > it's ask to shrink to the point where its windows' minimum size
 > constraints are violated.  The bug reports will be great: "I was
 > shrinking Emacs and suddenly it collapsed into a nano-black hole,
 > started spraying X-rays, and cured my cancer!"
 >
 > Footnotes:
 > [1]  It might be a good idea to keep Emacs's "viewport" centered on
 > point in the selected Emacs window.  Then again, it might not.

We could just show the selected window of that frame and save the old
configuration somewhere.  The problem of undeleting windows raises its
ugly head again :-(

martin




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

* Re: moving window handling into lisp
  2009-08-15 19:51                                             ` Stefan Monnier
@ 2009-08-16 10:26                                               ` martin rudalics
  2009-08-16 11:18                                                 ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 10:26 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, emacs-devel

 > Not necessarily: it could be done by instructing the window-manager
 > beforehand about the applicable resizing limits.

We'd have to consult Jan whether this can be done on a general base.

 > I've often found
 > windows that cannot be resized below some threshold (often dialog
 > windows).  Try it with `evolution', for example: I can't make it
 > narrower than 879 pixels.

But dialogue windows are handled specially by most WMs.  Personally, I
hate dialogue windows because they all too often cut off some text and I
can't get them show it.

 >> I think we can live with deleting windows in that case and _not_
 >> resurrecting them when the frame is resized.
 >
 > With window-managers that do "opaque resizing" (pretty much standard
 > nowadays), that can be very problematic.

Because a window gets deleted when I shrink the frame and does not
reappear when I re-enlarge the frame?

martin




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

* Re: moving window handling into lisp
  2009-08-16 10:25                                                             ` martin rudalics
@ 2009-08-16 11:14                                                               ` Lennart Borgman
  2009-08-16 12:12                                                                 ` David Kastrup
  2009-08-16 12:17                                                                 ` martin rudalics
  0 siblings, 2 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 11:14 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

On Sun, Aug 16, 2009 at 12:25 PM, martin rudalics<rudalics@gmx.at> wrote:
>> However in that case I would still suggest showing one window
>> temporary and explain and give alternatives there. I can't see that it
>> is worse than just deleting the windows. Just deleting the windows
>> might look like a bug - or maybe just not be noticed, be confusing.
>
> It hardly was a problem recently.  What's more important IMHO is that
> when we shrink a frame and re-enlarge it afterwards we should get the
> previous sizes.  That's, however, more difficult to do.


What is problematic with that if we save pointers to the old structure
as I suggested? (I am not saying there aren't any problem, I just
don't know what kind of problem you see.)




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

* Re: moving window handling into lisp
  2009-08-16 10:26                                                             ` martin rudalics
@ 2009-08-16 11:16                                                               ` Lennart Borgman
  2009-08-16 12:17                                                                 ` martin rudalics
  2009-08-16 14:49                                                               ` Stephen J. Turnbull
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 11:16 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stephen J. Turnbull, emacs-devel

On Sun, Aug 16, 2009 at 12:26 PM, martin rudalics<rudalics@gmx.at> wrote:

> We could just show the selected window of that frame and save the old
> configuration somewhere.  The problem of undeleting windows raises its
> ugly head again :-(

Exactly which problem?




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

* Re: moving window handling into lisp
  2009-08-16 10:26                                               ` martin rudalics
@ 2009-08-16 11:18                                                 ` Lennart Borgman
  2009-08-16 12:17                                                   ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 11:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Stefan Monnier, rms

On Sun, Aug 16, 2009 at 12:26 PM, martin rudalics<rudalics@gmx.at> wrote:

>> I've often found
>> windows that cannot be resized below some threshold (often dialog
>> windows).  Try it with `evolution', for example: I can't make it
>> narrower than 879 pixels.
>
> But dialogue windows are handled specially by most WMs.


On w32 this is not special to dialogue windows.




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

* Re: moving window handling into lisp
  2009-08-16 11:14                                                               ` Lennart Borgman
@ 2009-08-16 12:12                                                                 ` David Kastrup
  2009-08-16 12:19                                                                   ` Lennart Borgman
  2009-08-16 15:17                                                                   ` martin rudalics
  2009-08-16 12:17                                                                 ` martin rudalics
  1 sibling, 2 replies; 130+ messages in thread
From: David Kastrup @ 2009-08-16 12:12 UTC (permalink / raw)
  To: emacs-devel

Lennart Borgman <lennart.borgman@gmail.com> writes:

> On Sun, Aug 16, 2009 at 12:25 PM, martin rudalics<rudalics@gmx.at> wrote:
>>> However in that case I would still suggest showing one window
>>> temporary and explain and give alternatives there. I can't see that it
>>> is worse than just deleting the windows. Just deleting the windows
>>> might look like a bug - or maybe just not be noticed, be confusing.
>>
>> It hardly was a problem recently.  What's more important IMHO is that
>> when we shrink a frame and re-enlarge it afterwards we should get the
>> previous sizes.  That's, however, more difficult to do.
>
>
> What is problematic with that if we save pointers to the old structure
> as I suggested? (I am not saying there aren't any problem, I just
> don't know what kind of problem you see.)

What _is_ the "old structure" when resizing opaquely?  It might be
easiest to store window sizes as fractions.  When resizing a frame, the
fractions don't change (so the internal window configuration snaps to
the closest integral value).  When resizing individual windows, the
fractions are made whole again, matching the character positions of the
frame.

Note that storing stuff in that manner also allows repeated toggles of
tool-bar-mode and similar to revert to the original frame configuration
painlessly since the outer window edges (which can't be repositioned
within a frame) retain the original fractions indefinitely as long as
the frame itself is not resized manually.

-- 
David Kastrup





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

* Re: moving window handling into lisp
  2009-08-16 11:14                                                               ` Lennart Borgman
  2009-08-16 12:12                                                                 ` David Kastrup
@ 2009-08-16 12:17                                                                 ` martin rudalics
  2009-08-16 12:26                                                                   ` Lennart Borgman
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 12:17 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel

 > What is problematic with that if we save pointers to the old structure
 > as I suggested? (I am not saying there aren't any problem, I just
 > don't know what kind of problem you see.)

We would have to save multiple before-frame-size-change window
configurations, compare them in a non-trivial way at every subsequent
frame-resizing (we probably should not revert explicit window-resizing
operations that happened since the save but probably ignore
`fit-window-to-buffer' operations), and get rid of saved configurations
when they are no more useful.  All this is very non-trivial.

martin




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

* Re: moving window handling into lisp
  2009-08-16 11:16                                                               ` Lennart Borgman
@ 2009-08-16 12:17                                                                 ` martin rudalics
  2009-08-16 12:29                                                                   ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 12:17 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stephen J. Turnbull, emacs-devel

 >> We could just show the selected window of that frame and save the old
 >> configuration somewhere.  The problem of undeleting windows raises its
 >> ugly head again :-(
 >
 > Exactly which problem?

That of whether undeleting a window should restore its previous
identity.

martin




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

* Re: moving window handling into lisp
  2009-08-16 11:18                                                 ` Lennart Borgman
@ 2009-08-16 12:17                                                   ` martin rudalics
  2009-08-16 12:30                                                     ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 12:17 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel, Stefan Monnier, rms

 >>> I've often found
 >>> windows that cannot be resized below some threshold (often dialog
 >>> windows).  Try it with `evolution', for example: I can't make it
 >>> narrower than 879 pixels.
 >> But dialogue windows are handled specially by most WMs.
 >
 > On w32 this is not special to dialogue windows.

Dialogue windows are always special with tiling WMs.  Or did you mean
that on w32 there are non-dialogue (or other special popup) windows that
can't be resized?

martin




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

* Re: moving window handling into lisp
  2009-08-16 12:12                                                                 ` David Kastrup
@ 2009-08-16 12:19                                                                   ` Lennart Borgman
  2009-08-16 15:17                                                                   ` martin rudalics
  1 sibling, 0 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 12:19 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

On Sun, Aug 16, 2009 at 2:12 PM, David Kastrup<dak@gnu.org> wrote:

> What _is_ the "old structure" when resizing opaquely?  It might be
> easiest to store window sizes as fractions.

I think it is a good idea to store the fractions as goals (which must
be mixed with other goals to so it might be a bit complicated).




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

* Re: moving window handling into lisp
  2009-08-16 12:17                                                                 ` martin rudalics
@ 2009-08-16 12:26                                                                   ` Lennart Borgman
  2009-08-16 15:18                                                                     ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 12:26 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

On Sun, Aug 16, 2009 at 2:17 PM, martin rudalics<rudalics@gmx.at> wrote:
>> What is problematic with that if we save pointers to the old structure
>> as I suggested? (I am not saying there aren't any problem, I just
>> don't know what kind of problem you see.)
>
> We would have to save multiple before-frame-size-change window
> configurations


Why multiple?


> compare them in a non-trivial way at every subsequent
> frame-resizing


Is not that exactly what we are doing when we are resizing? You just
put back the original structure and try resizing again.


> and get rid of saved configurations
> when they are no more useful.


There is only one: the "does-not-fit-configuration". And it should not
be a window-configuration, just a pointer to the old windows.


> All this is very non-trivial.
>
> martin
>




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

* Re: moving window handling into lisp
  2009-08-16 12:17                                                                 ` martin rudalics
@ 2009-08-16 12:29                                                                   ` Lennart Borgman
  2009-08-16 15:18                                                                     ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 12:29 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stephen J. Turnbull, emacs-devel

On Sun, Aug 16, 2009 at 2:17 PM, martin rudalics<rudalics@gmx.at> wrote:
>>> We could just show the selected window of that frame and save the old
>>> configuration somewhere.  The problem of undeleting windows raises its
>>> ugly head again :-(
>>
>> Exactly which problem?
>
> That of whether undeleting a window should restore its previous
> identity.


You are misunderstanding. There is no undeleting. There is no saved
window-configuration (ie what we normally call window-configuration).
This is not the way I suggest to do it.

Instead I suggested putting aside exactly the structure that is there
before resizing, replacing it with a single window. And putting it
back when it can fit again.


> martin
>




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

* Re: moving window handling into lisp
  2009-08-16 12:17                                                   ` martin rudalics
@ 2009-08-16 12:30                                                     ` Lennart Borgman
  0 siblings, 0 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-08-16 12:30 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel, Stefan Monnier, rms

On Sun, Aug 16, 2009 at 2:17 PM, martin rudalics<rudalics@gmx.at> wrote:
>>>> I've often found
>>>> windows that cannot be resized below some threshold (often dialog
>>>> windows).  Try it with `evolution', for example: I can't make it
>>>> narrower than 879 pixels.
>>> But dialogue windows are handled specially by most WMs.
>>
>> On w32 this is not special to dialogue windows.
>
> Dialogue windows are always special with tiling WMs.  Or did you mean
> that on w32 there are non-dialogue (or other special popup) windows that
> can't be resized?


The latter. It is a general callback on w32 that can be used with any window.


> martin
>




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

* Re: moving window handling into lisp
  2009-08-16 10:26                                                             ` martin rudalics
  2009-08-16 11:16                                                               ` Lennart Borgman
@ 2009-08-16 14:49                                                               ` Stephen J. Turnbull
  2009-08-16 15:31                                                                 ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-16 14:49 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lennart Borgman, emacs-devel

martin rudalics writes:

 >  > A (radical) alternative is to shrink the Emacs windows as much
 >  > as possible, then ignore further shrinkage.[1]
 > 
 > Ignoring `window-min-height' and `window-min-width' when shrinking
 > frames seems to do most of that job already.

Is that a joke?  If it isn't, I don't see how it applies.

 >  > The WM will shrink the shell widget's window, and the GUI server will
 >  > then clip the Emacs frame to fit.
 > 
 > This would usually clip off the echo area, I presume.

Yes, but the math and window repositioning to ensure that the echo
area is always visible is hardly rocket science.

 >  > user can get any work done anyway, and in that case the user will have
 >  > to tell the WM to resize Emacs to a usable size to get work done.  Why
 >  > not just leave Emacs's internal configuration as it is?
 > 
 > When I resize an Emacs frame because I temporarily want to work with
 > another application I usually don't care about the state of Emacs'
 > windows.

Then Emacs can act like the Linux OOM and kill windows randomly.  The
problem is for those of us who do care/those times when you care.

 > Leaving the frame configuration in some not very orderly state
 > doesn't strike me as very clean.

What "disorderly state"?  The *Emacs frame* is in the same orderly
state it was before, and as soon as you resize the shell to the
original size, you'll see it that way again -- with no other effort by
the Emacs user or the developers (assuming the same kind of trick is
available on Windows and Aqua -- making it work on non-Xt platforms
could be inordinately difficult, I admit).

 >  > Footnotes:
 >  > [1]  It might be a good idea to keep Emacs's "viewport" centered on
 >  > point in the selected Emacs window.  Then again, it might not.
 > 
 > We could just show the selected window of that frame and save the old
 > configuration somewhere.  The problem of undeleting windows raises its
 > ugly head again :-(

I am *so* not interested in talking about that. :-)




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

* Re: moving window handling into lisp
  2009-08-16 12:12                                                                 ` David Kastrup
  2009-08-16 12:19                                                                   ` Lennart Borgman
@ 2009-08-16 15:17                                                                   ` martin rudalics
  2009-08-16 16:15                                                                     ` David Kastrup
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 15:17 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

 > What _is_ the "old structure" when resizing opaquely?  It might be
 > easiest to store window sizes as fractions.  When resizing a frame, the
 > fractions don't change (so the internal window configuration snaps to
 > the closest integral value).  When resizing individual windows, the
 > fractions are made whole again, matching the character positions of the
 > frame.

I'm not sure how to understand the last sentence.  Why and how are
"fractions made whole again"?

 > Note that storing stuff in that manner also allows repeated toggles of
 > tool-bar-mode and similar to revert to the original frame configuration
 > painlessly since the outer window edges (which can't be repositioned
 > within a frame) retain the original fractions indefinitely as long as
 > the frame itself is not resized manually.

I suppose the outer window edges also change fractions when the window
is resized manually.  Or what am I missing?

Anyway note that we implicitly use a fractional approach when resizing a
frame.  The major obstacles to this are `window-min-height' and
`window-min-width' and fixed-size windows.  Also I'm not sure how to
handle window/buffer specific associations like `fit-window-to-buffer'
and `temp-buffer-resize-mode'.

martin




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

* Re: moving window handling into lisp
  2009-08-16 12:26                                                                   ` Lennart Borgman
@ 2009-08-16 15:18                                                                     ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 15:18 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel

 >> We would have to save multiple before-frame-size-change window
 >> configurations
 >
 >
 > Why multiple?

Would you store only the last one?  It might be jsut that of a final
adjustment of the frame by one line because the user wanted it that way.

 >> compare them in a non-trivial way at every subsequent
 >> frame-resizing
 >
 >
 > Is not that exactly what we are doing when we are resizing? You just
 > put back the original structure and try resizing again.

The window structure might have changed since the last frame-resizing.
Would you reinstall the old windows in that case?  Then you can use
`set-window-configuration'.  Note that I was talking about shrinking a
frame and reenlarging it at a later moment here.

martin




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

* Re: moving window handling into lisp
  2009-08-16 12:29                                                                   ` Lennart Borgman
@ 2009-08-16 15:18                                                                     ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 15:18 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stephen J. Turnbull, emacs-devel

 > You are misunderstanding. There is no undeleting. There is no saved
 > window-configuration (ie what we normally call window-configuration).
 > This is not the way I suggest to do it.
 >
 > Instead I suggested putting aside exactly the structure that is there
 > before resizing, replacing it with a single window. And putting it
 > back when it can fit again.

The canonical way to "put a structure aside" is a window-configuration.
Otherwise you'd have to decide whether windows put aside show up on
`window-list', can be used by `display-buffer', ...  You'd wind up
reinventing the wheel.

martin




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

* Re: moving window handling into lisp
  2009-08-16 14:49                                                               ` Stephen J. Turnbull
@ 2009-08-16 15:31                                                                 ` martin rudalics
  2009-08-16 16:28                                                                   ` Stephen J. Turnbull
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-16 15:31 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Lennart Borgman, emacs-devel

 >  >  > A (radical) alternative is to shrink the Emacs windows as much
 >  >  > as possible, then ignore further shrinkage.[1]
 >  >
 >  > Ignoring `window-min-height' and `window-min-width' when shrinking
 >  > frames seems to do most of that job already.
 >
 > Is that a joke?  If it isn't, I don't see how it applies.

You would first have to tell me what "shrink the Emacs windows as much
as possible" means.

 > Yes, but the math and window repositioning to ensure that the echo
 > area is always visible is hardly rocket science.

To see the echo area an Emacs frame must be at least four lines tall
(with an enabled menubar) here.  Are four lines your minimum size?

 > Then Emacs can act like the Linux OOM and kill windows randomly.  The
 > problem is for those of us who do care/those times when you care.

Sorry, this is an issue you have to discuss with Jan.

 >  > Leaving the frame configuration in some not very orderly state
 >  > doesn't strike me as very clean.
 >
 > What "disorderly state"?  The *Emacs frame* is in the same orderly
 > state it was before, and as soon as you resize the shell to the
 > original size, you'll see it that way again -- with no other effort by
 > the Emacs user or the developers (assuming the same kind of trick is
 > available on Windows and Aqua -- making it work on non-Xt platforms
 > could be inordinately difficult, I admit).

This is yet another question on how Emacs interacts with the various WMs
it supports.  Jan can possibly tell you more.

martin




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

* Re: moving window handling into lisp
  2009-08-16 15:17                                                                   ` martin rudalics
@ 2009-08-16 16:15                                                                     ` David Kastrup
  2009-08-16 19:24                                                                       ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: David Kastrup @ 2009-08-16 16:15 UTC (permalink / raw)
  To: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> What _is_ the "old structure" when resizing opaquely?  It might be
>> easiest to store window sizes as fractions.  When resizing a frame, the
>> fractions don't change (so the internal window configuration snaps to
>> the closest integral value).  When resizing individual windows, the
>> fractions are made whole again, matching the character positions of the
>> frame.
>
> I'm not sure how to understand the last sentence.  Why and how are
> "fractions made whole again"?

A fraction for a window border position remains a fraction (of the frame
size) if it is an inherent result of resizing the frame.  If the user
adjusts individual window borders, however, their new position is an
integer since it is not an implicit result of frame resizing.

In a nutshell: whatever position is manipulated _directly_ is made an
integer at the time of the manipulation.  Window borders that are only
repositioned as an implicit (proportionate) result of some resizing
operation, do the bookkeeping of their position as a fraction that
corresponds to the resized ratios.

>> Note that storing stuff in that manner also allows repeated toggles of
>> tool-bar-mode and similar to revert to the original frame configuration
>> painlessly since the outer window edges (which can't be repositioned
>> within a frame) retain the original fractions indefinitely as long as
>> the frame itself is not resized manually.
>
> I suppose the outer window edges also change fractions when the window
> is resized manually.  Or what am I missing?

Resizing manually manipulates the outer window edges directly.  So they
are candidates for integral representations as a result of the
manipulation.

-- 
David Kastrup





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

* Re: moving window handling into lisp
  2009-08-16 15:31                                                                 ` martin rudalics
@ 2009-08-16 16:28                                                                   ` Stephen J. Turnbull
  2009-08-16 19:25                                                                     ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-16 16:28 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lennart Borgman, emacs-devel

martin rudalics writes:

 > This is yet another question on how Emacs interacts with the various WMs
 > it supports.

Absolutely nothing I've said depends on interactions with WMs.  That's
why it's so radical (and elegant, if I do say so myself).  All I
require is that you can have a child window that is *any* size and
position relative to the parent, and that window managers do not
directly manage children of top-level windows.  That is true in X.

Let's try putting it this way: if the frame shrinks to the point that
for some reason Emacs cannot fit into it without deleting a window,
Emacs gives up on fitting into the frame, and maintains its window
configuration as is.

In X, you're done, if you want: the lower right portion of the
contents of the frame will be clipped.  Alternatively, Emacs can
translate the position of the contents so that some selected portion
is visible in the "viewport"[1] created by the toplevel window, and
everything that "slops over" is clipped.  I don't know how other GUIs
handle this.

Footnotes: 
[1]  Look up the Viewport and Panner widgets in the Athena Widgets
(Xaw) documentation.





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

* Re: moving window handling into lisp
  2009-08-16 16:15                                                                     ` David Kastrup
@ 2009-08-16 19:24                                                                       ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 19:24 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

 > A fraction for a window border position remains a fraction (of the frame
 > size) if it is an inherent result of resizing the frame.  If the user
 > adjusts individual window borders, however, their new position is an
 > integer since it is not an implicit result of frame resizing.
 >
 > In a nutshell: whatever position is manipulated _directly_ is made an
 > integer at the time of the manipulation.  Window borders that are only
 > repositioned as an implicit (proportionate) result of some resizing
 > operation, do the bookkeeping of their position as a fraction that
 > corresponds to the resized ratios.

Very neat idea, indeed.  As a matter of fact this should solve the frame
re-resizing problem completely.

martin




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

* Re: moving window handling into lisp
  2009-08-16 16:28                                                                   ` Stephen J. Turnbull
@ 2009-08-16 19:25                                                                     ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-16 19:25 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Lennart Borgman, emacs-devel

 > In X, you're done, if you want: the lower right portion of the
 > contents of the frame will be clipped.  Alternatively, Emacs can
 > translate the position of the contents so that some selected portion
 > is visible in the "viewport"[1] created by the toplevel window, and
 > everything that "slops over" is clipped.  I don't know how other GUIs
 > handle this.

I suppose we do have to find a solution that fits them.

martin




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

* Re: moving window handling into lisp
@ 2009-08-17 19:06 grischka
  2009-08-18  7:13 ` martin rudalics
  2009-08-18 11:38 ` Lennart Borgman
  0 siblings, 2 replies; 130+ messages in thread
From: grischka @ 2009-08-17 19:06 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel

From: martin rudalics
> > In a nutshell: whatever position is manipulated _directly_ is made an
> > integer at the time of the manipulation.  Window borders that are only
> > repositioned as an implicit (proportionate) result of some resizing
> > operation, do the bookkeeping of their position as a fraction that
> > corresponds to the resized ratios.
>
>
> Very neat idea, indeed.  As a matter of fact this should solve the frame
> re-resizing problem completely.

To solve a problem it not only needs the right algorithm but also the
right implementation.

Take for example proportional resizing as it is currently.  If I make a
frame with two windows side by side, 20 and 70 chars wide and if I maximize
the frame, the window widths are now 63 and 113, and if I un-maximize it
again the widths are now 31 and 59.  That clearly is not a problem that
can be solved by ideas, as neat as they may be.  It is plain simple broken
math.

--- grischka





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

* Re: moving window handling into lisp
  2009-08-17 19:06 grischka
@ 2009-08-18  7:13 ` martin rudalics
  2009-08-18 11:38 ` Lennart Borgman
  1 sibling, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-18  7:13 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

 > Take for example proportional resizing as it is currently.  If I make a
 > frame with two windows side by side, 20 and 70 chars wide and if I maximize
 > the frame, the window widths are now 63 and 113, and if I un-maximize it
 > again the widths are now 31 and 59.  That clearly is not a problem that
 > can be solved by ideas, as neat as they may be.  It is plain simple broken
 > math.

This means that maximizing a frame increases all windows by the same
amount, demaximizing the frame decreases them proportionally.  If we use
David's approach, then maximizing a frame will increase all windows
proportionally too.

martin





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

* Re: moving window handling into lisp
  2009-08-17 19:06 grischka
  2009-08-18  7:13 ` martin rudalics
@ 2009-08-18 11:38 ` Lennart Borgman
  2009-08-19  9:15   ` grischka
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-18 11:38 UTC (permalink / raw)
  To: grischka; +Cc: rudalics, emacs-devel

On Mon, Aug 17, 2009 at 9:06 PM, grischka<grishka@gmx.de> wrote:

> That clearly is not a problem that
> can be solved by ideas, as neat as they may be.  It is plain simple broken
> math.


I would say that it is missing information, not broken math. After
(premature) rounding the information is simply gone. (And David's idea
cures that.)




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

* Re: moving window handling into lisp
  2009-08-18 11:38 ` Lennart Borgman
@ 2009-08-19  9:15   ` grischka
  2009-08-19 12:45     ` martin rudalics
  2009-08-19 13:01     ` Lennart Borgman
  0 siblings, 2 replies; 130+ messages in thread
From: grischka @ 2009-08-19  9:15 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: rudalics, emacs-devel

Lennart Borgman wrote:
> On Mon, Aug 17, 2009 at 9:06 PM, grischka<grishka@gmx.de> wrote:
> 
>> That clearly is not a problem that
>> can be solved by ideas, as neat as they may be.  It is plain simple broken
>> math.
> 
> 
> I would say that it is missing information, not broken math. After
> (premature) rounding the information is simply gone. (And David's idea
> cures that.)
> 

In theory, switching from normal to maximized state and back again does not
loose information at all.

--- grischka





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

* Re: moving window handling into lisp
  2009-08-19  9:15   ` grischka
@ 2009-08-19 12:45     ` martin rudalics
  2009-08-20 11:45       ` grischka
  2009-08-19 13:01     ` Lennart Borgman
  1 sibling, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-19 12:45 UTC (permalink / raw)
  To: grischka; +Cc: Lennart Borgman, emacs-devel

 > In theory, switching from normal to maximized state and back again does not
 > loose information at all.

In principle, Emacs windows should not be less than `window-min-height'
lines tall.  But an application can temporarily bind that variable to a
smaller value during resizing and leave around a window of less height.
Such windows usually don't harm when maximizing the frame but won't get
us back the previous state when switching back to normal.

On the other hand, switching from maximized to normal and back again
will fail more frequently due to `window-min-height'.  Note also that
the issues I mention here are not reponsible for the bad behavior you
observed earlier.  (Not directly, at least.)

martin




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

* Re: moving window handling into lisp
  2009-08-19  9:15   ` grischka
  2009-08-19 12:45     ` martin rudalics
@ 2009-08-19 13:01     ` Lennart Borgman
  1 sibling, 0 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-08-19 13:01 UTC (permalink / raw)
  To: grischka; +Cc: rudalics, emacs-devel

On Wed, Aug 19, 2009 at 11:15 AM, grischka<grishka@gmx.de> wrote:
> Lennart Borgman wrote:
>>
>> On Mon, Aug 17, 2009 at 9:06 PM, grischka<grishka@gmx.de> wrote:
>>
>>> That clearly is not a problem that
>>> can be solved by ideas, as neat as they may be.  It is plain simple
>>> broken
>>> math.
>>
>>
>> I would say that it is missing information, not broken math. After
>> (premature) rounding the information is simply gone. (And David's idea
>> cures that.)
>>
>
> In theory, switching from normal to maximized state and back again does not
> loose information at all.

Which theory?




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

* Re: moving window handling into lisp
  2009-08-19 12:45     ` martin rudalics
@ 2009-08-20 11:45       ` grischka
  2009-08-20 12:51         ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: grischka @ 2009-08-20 11:45 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lennart Borgman, emacs-devel

martin rudalics wrote:
>  > In theory, switching from normal to maximized state and back again 
> does not
>  > loose information at all.
> 
> In principle, Emacs windows should not be less than `window-min-height'
> lines tall.  But an application can temporarily bind that variable to a
> smaller value during resizing and leave around a window of less height.
> Such windows usually don't harm when maximizing the frame but won't get
> us back the previous state when switching back to normal.

You can't blame packages that they go through any hack to defend
their layout against the unpredictable interventions from the
distributed fuzzy-machine, err... emacs window-management.

> On the other hand, switching from maximized to normal and back again
> will fail more frequently due to `window-min-height'.  Note also that
> the issues I mention here are not reponsible for the bad behavior you
> observed earlier.  (Not directly, at least.)

Me thinks there are much more thoughts spend on 'window-min-height'
now than there possibly were at the time when it was first introduced.

--- grischka

> martin
> 





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

* Re: moving window handling into lisp
  2009-08-20 11:45       ` grischka
@ 2009-08-20 12:51         ` martin rudalics
  2009-08-20 13:05           ` David Kastrup
  2009-08-20 19:35           ` grischka
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-20 12:51 UTC (permalink / raw)
  To: grischka; +Cc: Lennart Borgman, emacs-devel

 >> In principle, Emacs windows should not be less than `window-min-height'
 >> lines tall.  But an application can temporarily bind that variable to a
 >> smaller value during resizing and leave around a window of less height.
 >> Such windows usually don't harm when maximizing the frame but won't get
 >> us back the previous state when switching back to normal.
 >
 > You can't blame packages that they go through any hack to defend
 > their layout against the unpredictable interventions from the
 > distributed fuzzy-machine, err... emacs window-management.

We must defend such packages against any attempts to simplify Emacs
window-management at their cost.

 > Me thinks there are much more thoughts spend on 'window-min-height'
 > now than there possibly were at the time when it was first introduced.

Not really.  Any window-manager has to deal with the possibility that a
window gets to small when its parent-window shrinks.  All we can do is
make such cases occur rarely, in practice.

martin




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

* Re: moving window handling into lisp
  2009-08-20 12:51         ` martin rudalics
@ 2009-08-20 13:05           ` David Kastrup
  2009-08-20 15:08             ` martin rudalics
  2009-08-20 19:35           ` grischka
  1 sibling, 1 reply; 130+ messages in thread
From: David Kastrup @ 2009-08-20 13:05 UTC (permalink / raw)
  To: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> Not really.  Any window-manager has to deal with the possibility that a
> window gets to small when its parent-window shrinks.  All we can do is
> make such cases occur rarely, in practice.

Well, one could just stop shrinking the window.

To wit: in single-window frames, the contents get scrolled left/right as
needed to have the cursor on-frame.  In multiple-window frames, one
could equally well scroll the whole window configuration.  Sure, C-x o
might cause window borders to jump around...

It might at least keep windows accessible in a somewhat
predictable/intuitive manner.

-- 
David Kastrup





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

* Re: moving window handling into lisp
  2009-08-20 13:05           ` David Kastrup
@ 2009-08-20 15:08             ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-20 15:08 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

 >> Not really.  Any window-manager has to deal with the possibility that a
 >> window gets to small when its parent-window shrinks.  All we can do is
 >> make such cases occur rarely, in practice.
 >
 > Well, one could just stop shrinking the window.

There's always a corner case where you can't (unless you use zero-size
windows).

What I wanted (and still want) to express is that the the cases where we
really _have to_ delete windows because there's no other choice are very
rare.  And in those cases we shouldn't care too much, IMHO.

 > To wit: in single-window frames, the contents get scrolled left/right as
 > needed to have the cursor on-frame.  In multiple-window frames, one
 > could equally well scroll the whole window configuration.  Sure, C-x o
 > might cause window borders to jump around...
 >
 > It might at least keep windows accessible in a somewhat
 > predictable/intuitive manner.

This would be a solution, indeed.  For Emacs 25.1, though ;-)

martin




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

* Re: moving window handling into lisp
       [not found]                 ` <4A8D66D5.3000600@gmx.at>
@ 2009-08-20 15:41                   ` Lennart Borgman
  2009-08-20 18:15                     ` martin rudalics
  2009-08-21  0:19                     ` Richard Stallman
  0 siblings, 2 replies; 130+ messages in thread
From: Lennart Borgman @ 2009-08-20 15:41 UTC (permalink / raw)
  To: martin rudalics, Emacs-Devel devel

On Thu, Aug 20, 2009 at 5:08 PM, martin rudalics<rudalics@gmx.at> wrote:
>>> You should be able to use it for standard cases.  For more complicated
>>> cases `adjust-window-trailing-edge' will do its own resizing (and maybe
>>> delete some window along the way).  And it's the complicated cases we
>>> have to test.
>>
>> What I wrote is for the most complicated cases. Can you tell me more
>> exactly what you think does not work? You may have seen something I
>> have not seen.
>
> `adjust-window-trailing-edge', as a last consequence, calls size_window
> with nodelete_p zero, so it's allowed to delete windows.  I thought you
> wanted to avoid that.


Thanks. I did not know adjust-window-trailing-edge could delete
windows. The doc string does not tell about that. I thought it was
correct. Could you please try to get the doc string corrected to
reflect the functions current state?


>>>>> The first thing we need for each window are some functions like
>>>>> `window-parent-window', `window-prev-window', `window-next-window',
>>>>> `window-vchild', `window-hchild', `window-left-column', and
>>>>> `window-top-line'.  This should be simple.
>>>> They are in principle already available through window-tree. But yes,
>>>> having them more explicitly would be fine.
>>> Are you sure?  Then you could write the necessary wrappers.
>>
>>
>> Of course I am sure. I am using that in winsav.el. But I do not think
>> it is a good idea to write wrappers on that level. Why do you think
>> that?
>
> If you have the wrappers at hand, use them.  We can write these
> functions and think how to call them later.


I do not have them, they are not written in that form. I meant that
the information from Emacs about windows is exposed through
window-tree.


>>>>> Next we need `window-set-new-height' and `window-set-new-width' to set
>>>>> and `window-new-height' and `window-new-width' to get the new values
>>>>> for
>>>>> a window's height and width and a function called
>>>>> `window-set-new-sizes'
>>>>> which copies the new values into the old values (checking whether they
>>>> Maybe. It have to be calculated the way I have said before. Is not
>>>> that clear yet?
>>> But you have to _assign_ these values somehow (unless you try it with
>>> `adjust-window-trailing-edge').
>>
>> But I have said many times that they preferrably should be applied to
>> a whole level at once. That would be much cleaner.
>>
>> What problems do you see with that?
>
> I'm just confused, that's my only problem.  You never told me what you
> really want.  What does "they preferrably should be applied to a whole
> level at once" mean?


Oh, sorry, then I must have been unclear.

The algorithm computes level by level in the second pass (ie on its
way down) how the windows should be sized. So you have the sizes for
all windows on that level at once. You can of course use
adjust-window-trailing-edge (setting restcrictions temporary to be
able to do that), but it seems much easier to be able to set them all
at once. The routines we have now for setting window sizes does
checking that has already been done by my functions then.


>>>>> But I'm not yet sure how we can integrate the resizing algorithm into
>>>>> `delete-window'.  Think of a frame composed of two windows where one is
>>>>> a leaf window and the other a combined window with many subwindows.
>>>>> When deleting the leaf window we have to resize the combined window
>>>>> which means to run a resize algorithm which _must not fail_ to produce
>>>>> a
>>>>> perfectly valid result.  So I'm afraid that I do have to run some sort
>>>>> of a rudimentary resize algorithm in C first and apply our algorithm
>>>>> afterwards :-(
>>>> Hm. There must be something you are missing here. Why do you believe
>>>> that my algorithm can't be used. This is exactly a situation where it
>>>> can be used.
>>> When do you call it?  If you call it before the window gets deleted,
>>> _you_ have to delete the window (and all its subwindows).  If you call
>>> it after the window gets deleted but before the others are resized, the
>>> Elisp call occurs in an invalid window configuration.  How would you
>>> handle that?
>>
>>
>> The elisp code I wrote does not in any way care if the configuration
>> is valid or not. It just looks at the available size and the
>> restrictions. Is not that clear? What problem do you see with that?
>
> I can't call Elisp code in an invalid configuration.  Suppose your
> algorithm decides that it cannot resize.  What shall the display engine
> display then?  The invalid configuration?


I am trying to understand what you mean here. You can call my routines
before deletion. It does not depend on the actuall configuration, just
the fictive configuration you tell about.


>>>>> As far as frame-resizing and the necessary deletion of windows is
>>>>> concerned I think we should really run our algorithm and, if it fails,
>>>>> simply delete the least recently used window until it doesn't fail any
>>>>> more (in the worst case this will resize a fixed-size window).
>>>> So you still think we should delete windows? I do not.
>>> If someone eventually comes up with a solution that handles frame
>>> resizing (and minibuffer resizing!) I'll be the first to go for it.
>>
>> I have suggested one. You have not replied to it.
>
> No one ever has suggested a practicable solution.  AFAICT you proposed
> to ask the user what to do in that case.  That's not practicable IMO.


Not really. I suggested:

- showing an alternate single window with information that the windows
does not fit
- and also keep the other configuration so you can put it back when
the window gets large enough again.
- this should be kept by just swapping a pointer between that single
window with information and the "real" configuration.

What do you find not practical about this? (The alternate single
window should just say something like "your windows does not fit,
please make the frame larger".)


>>>> Did not Stefan say he want to avoid it too?
>>> He did not provide a solution for it - and I suppose he's smart enough
>>> not to propose one.
>>
>> You are misunderstanding him. He wants ideas. Of course he knows about
>> the difficulties.
>
> Stefan earlier said in this thread to
>
> - either somehow make it possible to undelete windows (I'd *much* rather
>  not, but maybe if we make it sufficiently restrictive it'd be OK).
> - or maybe avoid deleting the window in this case, instead leave it
>  a size-0, and delete it at some later time (when would that be?).
> - prevent frame resizing that would require deleting a window.
>
> and that's where we still are more or less.  Everything I heard from
> people since that was not told from an implementor's POV.


Hm. I answered to that that I think it is better to use a single
alternate window like above. That is very much an implementors POV.
Why don't you think it is? (I believe maybe you think so because I do
not adhere to the old routines, but I am not sure.)

I did not go into details, but:

- undeleting seems terribly confusing from a users point of view.
- size-0 windows in a case like this would be the same.
- we probably can't prevetn resizing with all window managers.


>>>> Did you seriously try to understand my suggestion for how to handle it?
>>> Did you have a serious suggestion?
>>
>> Yes.
>>
>> Martin, can I take this to the list again. I thought we would save
>> time this way, but I am starting to doubt it. Can I send this mail to
>> the list?
>
> Sure, go ahead ;-)


Ok, done. It took it off list since I thought we should discuss boring
details, but the got back to principal discussion again so here we are
on the list again!


> martin
>




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

* Re: moving window handling into lisp
  2009-08-20 15:41                   ` Lennart Borgman
@ 2009-08-20 18:15                     ` martin rudalics
  2009-08-20 23:08                       ` Lennart Borgman
  2009-08-21 19:34                       ` Stefan Monnier
  2009-08-21  0:19                     ` Richard Stallman
  1 sibling, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-20 18:15 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Emacs-Devel devel

 > Thanks. I did not know adjust-window-trailing-edge could delete
 > windows.

It resurrects them via `set-window-configuration'.  But size_window can
delete them temporarily.  Most of this discussion was triggered by
Stefan's being unhappy with that.

 > The doc string does not tell about that. I thought it was
 > correct. Could you please try to get the doc string corrected to
 > reflect the functions current state?

Every resize operation may delete windows.  But some like the minibuffer
resize operations and `adjust-window-trailing-edge' save the
window-configuration around resize calls to avoid that windows get
deleted.  I'm not sure whether that's of any help for you, though.

 > The algorithm computes level by level in the second pass (ie on its
 > way down) how the windows should be sized. So you have the sizes for
 > all windows on that level at once.

I still don't understand what a "level" is.

 > You can of course use
 > adjust-window-trailing-edge (setting restcrictions temporary to be
 > able to do that), but it seems much easier to be able to set them all
 > at once. The routines we have now for setting window sizes does
 > checking that has already been done by my functions then.

But that's what the functions `set-new-window-height' and
`set-new-window-width' I proposed earlier should do.

 >> I can't call Elisp code in an invalid configuration.  Suppose your
 >> algorithm decides that it cannot resize.  What shall the display engine
 >> display then?  The invalid configuration?
 >
 > I am trying to understand what you mean here. You can call my routines
 > before deletion.

I can't because at that time the window still exists and you don't
delete windows.  I need a resize function that's executed _as part of_
the Emacs command `delete-window'.

 > It does not depend on the actuall configuration, just
 > the fictive configuration you tell about.

How do I tell it about a "fictive configuration"?  You want all those
links to the next, previous, parent windows be valid, I suppose.

 > Not really. I suggested:
 >
 > - showing an alternate single window with information that the windows
 > does not fit
 > - and also keep the other configuration so you can put it back when
 > the window gets large enough again.
 > - this should be kept by just swapping a pointer between that single
 > window with information and the "real" configuration.

The canonical way to handle this is keeping "the other configuration" in
a window-configuration, something Stefan wants to avoid.  I don't get at
what you mean by "pointer swapping".  If such pointer swapping were as
easy as you believe, we could have used that all the time instead of
saving window-configurations.

 > What do you find not practical about this? (The alternate single
 > window should just say something like "your windows does not fit,
 > please make the frame larger".)

Do you know any application proposing to enlarge its window?

 > - undeleting seems terribly confusing from a users point of view.

You do undelete all the time.  It's completely transparent.

 > - size-0 windows in a case like this would be the same.

Many applications do that.  But they don't have a built-in tiling window
manager like Emacs.

 > - we probably can't prevetn resizing with all window managers.

martin




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

* Re: moving window handling into lisp
  2009-08-20 12:51         ` martin rudalics
  2009-08-20 13:05           ` David Kastrup
@ 2009-08-20 19:35           ` grischka
  2009-08-21 12:22             ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: grischka @ 2009-08-20 19:35 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics wrote:
>  >> In principle, Emacs windows should not be less than `window-min-height'
>  >> lines tall.  But an application can temporarily bind that variable to a
>  >> smaller value during resizing and leave around a window of less height.
>  >> Such windows usually don't harm when maximizing the frame but won't get
>  >> us back the previous state when switching back to normal.
>  >
>  > You can't blame packages that they go through any hack to defend
>  > their layout against the unpredictable interventions from the
>  > distributed fuzzy-machine, err... emacs window-management.
> 
> We must defend such packages against any attempts to simplify Emacs
> window-management at their cost.

The distributed fuzzy-machine cannot be simplified because it defends
itself by, well, being distributed.

>  > Me thinks there are much more thoughts spend on 'window-min-height'
>  > now than there possibly were at the time when it was first introduced.
> 
> Not really.  Any window-manager has to deal with the possibility that a
> window gets to small when its parent-window shrinks.  All we can do is
> make such cases occur rarely, in practice.

Window-managers don't deal with shrinking parent windows.  They deal
with fixed desktop/root windows.

With individual applications it's called "layout-manager", which exist
in the various GUI toolkits.

layout-managers are invisible containers that allow you to place
components like widgets or windows of other layout-managers within,
and to set a policy how these components are arranged, such as "box",
"grid", "flow", ...

The concept of min-size exists too, though individually for each
component, and it actually means what it says, that is "keep this
thing at least that large".  Consequently a case of "too small" can
never happen.

--- grischka

> 
> martin
> 





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

* Re: moving window handling into lisp
  2009-08-20 18:15                     ` martin rudalics
@ 2009-08-20 23:08                       ` Lennart Borgman
  2009-08-21 12:40                         ` martin rudalics
  2009-08-21 19:34                       ` Stefan Monnier
  1 sibling, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-20 23:08 UTC (permalink / raw)
  To: martin rudalics; +Cc: Emacs-Devel devel

On Thu, Aug 20, 2009 at 8:15 PM, martin rudalics<rudalics@gmx.at> wrote:

> Every resize operation may delete windows.  But some like the minibuffer
> resize operations and `adjust-window-trailing-edge' save the
> window-configuration around resize calls to avoid that windows get
> deleted.  I'm not sure whether that's of any help for you, though.


Thanks. I had no idea about that. I will think about it.


>> The algorithm computes level by level in the second pass (ie on its
>> way down) how the windows should be sized. So you have the sizes for
>> all windows on that level at once.
>
> I still don't understand what a "level" is.


All children to a window are on the same level.


>> You can of course use
>> adjust-window-trailing-edge (setting restcrictions temporary to be
>> able to do that), but it seems much easier to be able to set them all
>> at once. The routines we have now for setting window sizes does
>> checking that has already been done by my functions then.
>
> But that's what the functions `set-new-window-height' and
> `set-new-window-width' I proposed earlier should do.


Do I understand you right, do you say: These should set the size
without any checking.


>>> I can't call Elisp code in an invalid configuration.  Suppose your
>>> algorithm decides that it cannot resize.  What shall the display engine
>>> display then?  The invalid configuration?
>>
>> I am trying to understand what you mean here. You can call my routines
>> before deletion.
>
> I can't because at that time the window still exists and you don't
> delete windows.  I need a resize function that's executed _as part of_
> the Emacs command `delete-window'.
>
>> It does not depend on the actuall configuration, just
>> the fictive configuration you tell about.
>
> How do I tell it about a "fictive configuration"?  You want all those
> links to the next, previous, parent windows be valid, I suppose.


You can make a lisp copy of the configuration. This copy should
contain just the info needed to compute the new sizes. If you want the
sizes after deletion then just do not include the window you want to
delete in the copy.


>> Not really. I suggested:
>>
>> - showing an alternate single window with information that the windows
>> does not fit
>> - and also keep the other configuration so you can put it back when
>> the window gets large enough again.
>> - this should be kept by just swapping a pointer between that single
>> window with information and the "real" configuration.
>
> The canonical way to handle this is keeping "the other configuration" in
> a window-configuration, something Stefan wants to avoid.  I don't get at
> what you mean by "pointer swapping".  If such pointer swapping were as
> easy as you believe, we could have used that all the time instead of
> saving window-configurations.


I thought a window-configuration was a copy with the information
necessary to recreate the window configuration. That is a totally
different thing and can't be done the way I suggest.


I am not sure that what I suggest is that very easy to do. I thought
you should comment on it, but we are miscommunicating for some reason.

I have not looked at the implementation, but I know you have so I am
asking you. (I have rephrased and clarified my question below.)

I guessed there must be some pointer (in a general sense) for each
frame to the root window. I do not know the actual implementation, but
I just glanced at it. Unfortunately it takes some time for me to read
C so I guess a little. I can see there is a Lisp_Object called
root_window in struct frame. This is the pointer I am talking about.

My question (and suggestion) to you is this: Would it be possible to
temporarily replace the frames root_window with a new window when the
frame size gets so small that the window configuration does not fit?
Whether this is easy (or perhaps even possible) is of course dependent
on the details in this implementation.

It depends on for example on how drawing of windows are done. Is
drawing of a frame something that starts from the frame and then goes
down to look at the windows? Or does the windows live a life on their
on in this regard? I have assumed the former when I suggested to just
swap the roor_window pointer. You know more about the implementation
details and can probably give a better answer.


Maybe I should have explained this from the beginning, but I believed
you should answer something like the above to my suggestion. I am
sorry for beeing too short.


>> What do you find not practical about this? (The alternate single
>> window should just say something like "your windows does not fit,
>> please make the frame larger".)
>
> Do you know any application proposing to enlarge its window?


I thinks I have seen such cases, yes. (But I do not remember where now.)

You seem to suggest that it would be hard to understand for the user.
In that case, why?


>> - undeleting seems terribly confusing from a users point of view.
>
> You do undelete all the time.  It's completely transparent.


How can it be transparent if windows disappears and reappears? I must
be misunderstanding you somehow...


>> - size-0 windows in a case like this would be the same.
>
> Many applications do that.


Can you explain how you mean?


>> - we probably can't prevetn resizing with all window managers.
>
> martin
>




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

* Re: moving window handling into lisp
  2009-08-20 15:41                   ` Lennart Borgman
  2009-08-20 18:15                     ` martin rudalics
@ 2009-08-21  0:19                     ` Richard Stallman
  2009-08-21 12:40                       ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Richard Stallman @ 2009-08-21  0:19 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: rudalics, emacs-devel

One of the benefits of moving window resizing into Lisp
is that people will be able to easiy try out various different
ways of doing it.  So we need not try to decide the best way
by a discussion about abstractions now.

It will be possible to have different resizing strategies for
different situations, too.  Responding to a window manager need not be
the same as responding to the user's dragging a boundary.




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

* Re: moving window handling into lisp
  2009-08-20 19:35           ` grischka
@ 2009-08-21 12:22             ` martin rudalics
  2009-08-21 19:32               ` Stefan Monnier
  2009-08-24 13:10               ` grischka
  0 siblings, 2 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-21 12:22 UTC (permalink / raw)
  To: grischka; +Cc: emacs-devel

 > The distributed fuzzy-machine cannot be simplified because it defends
 > itself by, well, being distributed.

The weak point of that machine is the size_window routine which IIUC is
called by most of these distributed components.

 >>  > Me thinks there are much more thoughts spend on 'window-min-height'
 >>  > now than there possibly were at the time when it was first introduced.
 >>
 >> Not really.  Any window-manager has to deal with the possibility that a
 >> window gets to small when its parent-window shrinks.  All we can do is
 >> make such cases occur rarely, in practice.
 >
 > Window-managers don't deal with shrinking parent windows.  They deal
 > with fixed desktop/root windows.

I obviously meant "any Emacs window-manager" here.  I don't even know
whether desktop window-managers use concepts like parent-windows or the
split-window paradigm.

 > With individual applications it's called "layout-manager", which exist
 > in the various GUI toolkits.
 >
 > layout-managers are invisible containers that allow you to place
 > components like widgets or windows of other layout-managers within,
 > and to set a policy how these components are arranged, such as "box",
 > "grid", "flow", ...
 >
 > The concept of min-size exists too, though individually for each
 > component, and it actually means what it says, that is "keep this
 > thing at least that large".  Consequently a case of "too small" can
 > never happen.

So if a component doesn't fit it's iconified in some sense of that word?

martin




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

* Re: moving window handling into lisp
  2009-08-20 23:08                       ` Lennart Borgman
@ 2009-08-21 12:40                         ` martin rudalics
  2009-08-21 13:58                           ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-21 12:40 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Emacs-Devel devel

 >>> The algorithm computes level by level in the second pass (ie on its
 >>> way down) how the windows should be sized. So you have the sizes for
 >>> all windows on that level at once.
 >> I still don't understand what a "level" is.
 >
 > All children to a window are on the same level.

So you want a routine to set the sizes of all children of a window?
What would you want to pass to that routine?  A list?

 > Do I understand you right, do you say: These should set the size
 > without any checking.

The new size of one window.  Applying the new sizes of all windows is
done transactionally, all at once (or none at all if there's a failure).

 > You can make a lisp copy of the configuration. This copy should
 > contain just the info needed to compute the new sizes. If you want the
 > sizes after deletion then just do not include the window you want to
 > delete in the copy.

And who does delete the window _and_ resize the remaining ones?

 > I guessed there must be some pointer (in a general sense) for each
 > frame to the root window. I do not know the actual implementation, but
 > I just glanced at it. Unfortunately it takes some time for me to read
 > C so I guess a little. I can see there is a Lisp_Object called
 > root_window in struct frame. This is the pointer I am talking about.
 >
 > My question (and suggestion) to you is this: Would it be possible to
 > temporarily replace the frames root_window with a new window when the
 > frame size gets so small that the window configuration does not fit?
 > Whether this is easy (or perhaps even possible) is of course dependent
 > on the details in this implementation.
 >
 > It depends on for example on how drawing of windows are done. Is
 > drawing of a frame something that starts from the frame and then goes
 > down to look at the windows? Or does the windows live a life on their
 > on in this regard? I have assumed the former when I suggested to just
 > swap the roor_window pointer. You know more about the implementation
 > details and can probably give a better answer.

It would get us into hell's kitchen to just swap some pointers.  The
more so because you want redisplay to happen in between.  What do you
think window-configurations have been invented for?

 > You seem to suggest that it would be hard to understand for the user.
 > In that case, why?

Because at the time the window-manager shrinks my Emacs frame I usually
want to work with some other application.

 >> You do undelete all the time.  It's completely transparent.
 >
 > How can it be transparent if windows disappears and reappears? I must
 > be misunderstanding you somehow...

There might be no redisplay in between.

 >>> - size-0 windows in a case like this would be the same.
 >> Many applications do that.
 >
 > Can you explain how you mean?

In many applications (Thunderbird is one of them) I can make subwindows
disappear completely by dragging one of their borders and make them
reappear later by dragging on the border where they disappeared.

martin




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

* Re: moving window handling into lisp
  2009-08-21  0:19                     ` Richard Stallman
@ 2009-08-21 12:40                       ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-21 12:40 UTC (permalink / raw)
  To: rms; +Cc: Lennart Borgman, emacs-devel

 > One of the benefits of moving window resizing into Lisp
 > is that people will be able to easiy try out various different
 > ways of doing it.  So we need not try to decide the best way
 > by a discussion about abstractions now.
 >
 > It will be possible to have different resizing strategies for
 > different situations, too.  Responding to a window manager need not be
 > the same as responding to the user's dragging a boundary.

Currently, resizing a window W vertically is implemented by the
following routines:

- `enlarge_window' resizes W by stealing/giving space from/to windows
   above and/or below W and may delete windows when they get too small.
   `enlarge_window' does it's job by always calling `set_window_height'
   (see below) with the NODELETE argument 0 so it essentially always gets
   it's job done.  Note that `enlarge_window' is the routine implementing
   the commands `enlarge-window' and `shrink-window' so the majority of
   Emacs' window resizing operations is done here.

- `set_window_height' deletes windows when called by `enlarge_window'
   and display initialization (but this should hardly matter) and
   currently tries to not delete windows when called by the frame
   resizing routines (unless there's no other way because the windows
   won't fit).  Generally, `set-window_height' only serves as an
   interface to `size_window' (see below).

- `size_window' is the basic resizing routine.  It currently can either
   delete other windows unconditionally, delete other windows only when
   they shrink below `window-min-height', or delete them when they shrink
   to zero.  It apparently doesn't handle fixed-size windows correctly
   and does a poor job re-resizing windows.

- `adjust_window_trailing_edge' resizes W by stealing/giving space
   from/to the window below W and does not delete windows when they get
   too small.  `adjust_window_trailing_edge' is used when dragging a
   modeline or vertical divider and calls size_window with the NODELETE
   argument 0.  Due to its ability to not delete any windows it's also
   called by `balance-windows-area'.  To avoid that a window gets deleted
   it saves and restores window-configuration but this could be likely
   resolved by having it call size_window with NODELETE non-zero.  Due to
   the bug in `size_window', `adjust_window_trailing_edge' doesn't handle
   fixed-size windows correctly.

- `delete_window' resizes either the sibling above or below W and is not
   allowed to delete other windows.  So inherently `delete_window' is not
   able to handle fixed-size windows correctly even if size_window were.

- `split-window' resizes only W (where W is the window that shall be
   split) and does not delete any other window.  Currently,
   `split-window' is trivial because it operates on leaf windows only.
   As a consequence, you can, for example, never create a full-width
   window in a frame with two side-by-side windows without deleting one
   of these windows first which I consider a considerable drawback.  If
   `split-window' were allowed to split internal windows, some more
   intelligent resizing routine would be needed.

- `resize_mini_window' shrinks windows above W (where W is the
   minibuffer window) using a routine called `shrink_window_lowest_first'
   which does not delete windows.  `resize_mini_window' can also enlarge
   other windows by calling `enlarge_window' which should not delete any
   window (but I'm not 100% sure about that).  Also `resize_mini_window'
   saves the original sizes of windows shrunk/enlarged in the
   `orig_total_lines' and `orig_top_line' slots and uses these to restore
   the original values when it's job is done (something like a built-in
   version of saving and restoring the window configuration)

With the exception of `resize_mini_window' similar behaviors apply for
resizing W horizontally.

Even if we don't implement resizing in Elisp the following issues have
not been discussed yet:

- Whether resizing may delete other windows depends on the interface to
   size_window chosen.  We can easily make `enlarge-window' not delete
   other windows by giving it an optional `no-delete' argument.  It's not
   clear though whether `size_window' does handle the NODELETE argument
   always correctly.

- Many parts of Emacs might rely on the ability of `enlarge-window' to
   delete other windows.  (It's hard to say which because there are too
   many.)  So some intelligent way of deleting other windows might be
   needed anyway if we wanted `enlarge-window' to not delete any windows.

- Ideally, we would have one function doing the job of `size_window' and
   that function could be used by `resize_mini_window' as well.  That
   function would probably take all the arguments `size_window' currently
   does.  And that function would have to handle fixed-size windows
   correctly and re-resize windows using David's fractional heights and
   widths.

martin




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

* Re: moving window handling into lisp
  2009-08-21 12:40                         ` martin rudalics
@ 2009-08-21 13:58                           ` Lennart Borgman
  2009-08-22 11:00                             ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-21 13:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: Emacs-Devel devel

On Fri, Aug 21, 2009 at 2:40 PM, martin rudalics<rudalics@gmx.at> wrote:
>>>> The algorithm computes level by level in the second pass (ie on its
>>>> way down) how the windows should be sized. So you have the sizes for
>>>> all windows on that level at once.
>>> I still don't understand what a "level" is.
>>
>> All children to a window are on the same level.
>
> So you want a routine to set the sizes of all children of a window?
> What would you want to pass to that routine?  A list?


Yes, but I am starting to wonder a bit what I really want. It looks to
me like I instead could use your new functions+remove restriction
check. See below.


>> Do I understand you right, do you say: These should set the size
>> without any checking.
>
> The new size of one window.  Applying the new sizes of all windows is
> done transactionally, all at once (or none at all if there's a failure).


There are some ideas here that are rather similar but differs a bit.
You and Stefan have been talking about the idea about treating the
size changes as transactions with possible roll back.

That seems ok to me. But I choosed a little bit different route. I am
trying to make the calculations first and only apply them if new sizes
fit. However with my idea there is still the problem of applying the
new sizes without bumping into any restriction during the applying
phase. This could happen even if you know that the final result will
fit.

That was the reason I asked for a function above to set the sizes of
all children at once. But such a function will not help since bumbing
into restrictions can happen further down the tree also.

So what I need is still a way to apply the new sizes without
restriction checks during that phase. Am I clear enough when I try to
explain this? How should I do to avoid the restrictions in this phase?


>> You can make a lisp copy of the configuration. This copy should
>> contain just the info needed to compute the new sizes. If you want the
>> sizes after deletion then just do not include the window you want to
>> delete in the copy.
>
> And who does delete the window _and_ resize the remaining ones?


You ... ;-)

Yes, I know that this is lacking. I have been wondering about this
part. It is not clear to me how resizing and deletion/creation of
windows are tighed together in the current code. I think those parts
should be broken up. Can you please try to explain how things are now
and if you see some way to brake those things apart?


>> I guessed there must be some pointer (in a general sense) for each
>> frame to the root window. I do not know the actual implementation, but
>> I just glanced at it. Unfortunately it takes some time for me to read
>> C so I guess a little. I can see there is a Lisp_Object called
>> root_window in struct frame. This is the pointer I am talking about.
>>
>> My question (and suggestion) to you is this: Would it be possible to
>> temporarily replace the frames root_window with a new window when the
>> frame size gets so small that the window configuration does not fit?
>> Whether this is easy (or perhaps even possible) is of course dependent
>> on the details in this implementation.
>>
>> It depends on for example on how drawing of windows are done. Is
>> drawing of a frame something that starts from the frame and then goes
>> down to look at the windows? Or does the windows live a life on their
>> on in this regard? I have assumed the former when I suggested to just
>> swap the roor_window pointer. You know more about the implementation
>> details and can probably give a better answer.
>
> It would get us into hell's kitchen to just swap some pointers.  The
> more so because you want redisplay to happen in between.  What do you
> think window-configurations have been invented for?


Window configurations was invented for this situation. It has a much
broader use.

But if you say it is impossible to switch this pointer then I surely
assume that you are right (since you know better about how the code
has been structured).

Then I assume that window configurations must be used to get my
suggestion to work. The drawback I see then is that window pointers
migh gets lost. Are there any way around that?


>> You seem to suggest that it would be hard to understand for the user.
>> In that case, why?
>
> Because at the time the window-manager shrinks my Emacs frame I usually
> want to work with some other application.


I am sorry, but I can't see why that should make it harder to
understand. The text to show can of course be changed to avoid some
confusion. Does not that help?


>>> You do undelete all the time.  It's completely transparent.
>>
>> How can it be transparent if windows disappears and reappears? I must
>> be misunderstanding you somehow...
>
> There might be no redisplay in between.


How can you avoid that when the frame gets too small?


>>>> - size-0 windows in a case like this would be the same.
>>> Many applications do that.
>>
>> Can you explain how you mean?
>
> In many applications (Thunderbird is one of them) I can make subwindows
> disappear completely by dragging one of their borders and make them
> reappear later by dragging on the border where they disappeared.


Are there no sign at all that there are 0-size windows there?


> martin
>




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

* Re: moving window handling into lisp
  2009-08-21 12:22             ` martin rudalics
@ 2009-08-21 19:32               ` Stefan Monnier
  2009-08-22  4:55                 ` Stephen J. Turnbull
  2009-08-24 13:10               ` grischka
  1 sibling, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-08-21 19:32 UTC (permalink / raw)
  To: martin rudalics; +Cc: grischka, emacs-devel

> So if a component doesn't fit it's iconified in some sense of that word?

No, what I tend to see (under X11) is that some X-windows just refuse to
be shrunk past a certain size.

A quick test shows that Firefox handles the issue by letting the
window-manager shrink the window at will (down to 1x1 pixels), but its
content stops shrinking at some point (so some of the content is
clipped).

OTOH Empathy and Evolution seem to impose some minimal size below which
the window doesn't shrink.  I don't know enough about the underlying
protocol to know how they might do that, but presumably it's either done
by telling the W-M beforehand what is the minimal size, or it's done
after the fact by "rejecting" the resize request.

Either way sounds good enough for me, so I don't see any need to ever
delete a window in response to a frame (or window) resize.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-20 18:15                     ` martin rudalics
  2009-08-20 23:08                       ` Lennart Borgman
@ 2009-08-21 19:34                       ` Stefan Monnier
  2009-08-22 11:01                         ` martin rudalics
  1 sibling, 1 reply; 130+ messages in thread
From: Stefan Monnier @ 2009-08-21 19:34 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lennart Borgman, Emacs-Devel devel

>> Thanks. I did not know adjust-window-trailing-edge could delete
>> windows.

> It resurrects them via `set-window-configuration'.  But size_window
> can delete them temporarily.  Most of this discussion was triggered by
> Stefan's being unhappy with that.

I'm not really unhappy about it.  I just pointed out that we may need to
change the implementation depending on some changes we may want to do to
window-configurations (e.g. to allow restoring them into other frames).


        Stefan




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

* Re: moving window handling into lisp
  2009-08-21 19:32               ` Stefan Monnier
@ 2009-08-22  4:55                 ` Stephen J. Turnbull
  2009-08-23  1:01                   ` Stefan Monnier
  0 siblings, 1 reply; 130+ messages in thread
From: Stephen J. Turnbull @ 2009-08-22  4:55 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, grischka, emacs-devel

Stefan Monnier writes:

 > A quick test shows that Firefox handles the issue by letting the
 > window-manager shrink the window at will (down to 1x1 pixels), but its
 > content stops shrinking at some point (so some of the content is
 > clipped).

FWIW, this is exactly the policy I suggested.  So Mozilla has a time
machine ....

 > OTOH Empathy and Evolution seem to impose some minimal size below which
 > the window doesn't shrink.  I don't know enough about the underlying
 > protocol to know how they might do that, but presumably it's either done
 > by telling the W-M beforehand what is the minimal size,

That's it.  In X11, these are called "window manager hints", and as
the name suggests, the window manager is free to ignore them.  If the
user doesn't like that behavior, they'll install a different window
manager, so you had better be prepared to deal with such window
managers -- it's the user's preference.

 > or it's done after the fact by "rejecting" the resize request.

Can't be done in X11, I don't know about other GUIs.





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

* Re: moving window handling into lisp
  2009-08-21 13:58                           ` Lennart Borgman
@ 2009-08-22 11:00                             ` martin rudalics
  2009-08-22 13:45                               ` Lennart Borgman
  0 siblings, 1 reply; 130+ messages in thread
From: martin rudalics @ 2009-08-22 11:00 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Emacs-Devel devel

 > There are some ideas here that are rather similar but differs a bit.
 > You and Stefan have been talking about the idea about treating the
 > size changes as transactions with possible roll back.
 >
 > That seems ok to me. But I choosed a little bit different route. I am
 > trying to make the calculations first and only apply them if new sizes
 > fit.

That's fine.  But it won't harm to check twice whether the sizes really
fit.

 > However with my idea there is still the problem of applying the
 > new sizes without bumping into any restriction during the applying
 > phase. This could happen even if you know that the final result will
 > fit.
 >
 > That was the reason I asked for a function above to set the sizes of
 > all children at once. But such a function will not help since bumbing
 > into restrictions can happen further down the tree also.
 >
 > So what I need is still a way to apply the new sizes without
 > restriction checks during that phase. Am I clear enough when I try to
 > explain this? How should I do to avoid the restrictions in this phase?

What problems do you have doing your calculations using copies of the
original sizes?  We can initialize these with the current values and
retrieve via `window-new-height' and `window-new-width'.

 > Yes, I know that this is lacking. I have been wondering about this
 > part. It is not clear to me how resizing and deletion/creation of
 > windows are tighed together in the current code. I think those parts
 > should be broken up.

It's not entirely trivial to do that.  Resizing during window deletion
must succeed, at least in a second attempt.  So if we want to do this in
Elisp we must be able to resize fixed-size windows and never issue a
failure.

 > Can you please try to explain how things are now
 > and if you see some way to brake those things apart?

I explained that in another post:

- `delete_window' resizes either the sibling above or below W and is not
   allowed to delete other windows.  So inherently `delete_window' is not
   able to handle fixed-size windows correctly even if size_window were.

To handle fixed-size windows "more" correctly `delete_window' should be
able to operate on all windows.  Obviously, in a two-window case with
the only other window fixed-size we have to resize that other window.

 > Then I assume that window configurations must be used to get my
 > suggestion to work. The drawback I see then is that window pointers
 > migh gets lost. Are there any way around that?

Which window pointers get lost?

 > I am sorry, but I can't see why that should make it harder to
 > understand. The text to show can of course be changed to avoid some
 > confusion. Does not that help?

Like "you can restore the previous configuration within a suitable
frame-size" by hitting ...  Maybe.  Let's add it to the set of possible
solutions.

 >>>> You do undelete all the time.  It's completely transparent.
 >>> How can it be transparent if windows disappears and reappears? I must
 >>> be misunderstanding you somehow...
 >> There might be no redisplay in between.
 >
 > How can you avoid that when the frame gets too small?

`adjust-window-trailing-edge' can temporarily delete a window and
resurrect it without the user noticing because there's no redisplay in
between.  When you program in Elisp you can try to inhibit redisplay but
I would not recommend that.  In any case, I don't understand how this
should relate to frames getting to small.

 >> In many applications (Thunderbird is one of them) I can make subwindows
 >> disappear completely by dragging one of their borders and make them
 >> reappear later by dragging on the border where they disappeared.
 >
 > Are there no sign at all that there are 0-size windows there?

Thunderbird leaves a horizontal divider behind.

martin




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

* Re: moving window handling into lisp
  2009-08-21 19:34                       ` Stefan Monnier
@ 2009-08-22 11:01                         ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-22 11:01 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Lennart Borgman, Emacs-Devel devel

 >> It resurrects them via `set-window-configuration'.  But size_window
 >> can delete them temporarily.  Most of this discussion was triggered by
 >> Stefan's being unhappy with that.
 >
 > I'm not really unhappy about it.  I just pointed out that we may need to
 > change the implementation depending on some changes we may want to do to
 > window-configurations (e.g. to allow restoring them into other frames).

These issues are unrelated.  Here I can "clone" a window-configuration
(that is, an object returned by `current-window-configuration') into an
arbitrary window.  `set-window-configuration' is completely unaffected
by that.

martin




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

* Re: moving window handling into lisp
  2009-08-22 11:00                             ` martin rudalics
@ 2009-08-22 13:45                               ` Lennart Borgman
  2009-08-22 14:17                                 ` martin rudalics
  0 siblings, 1 reply; 130+ messages in thread
From: Lennart Borgman @ 2009-08-22 13:45 UTC (permalink / raw)
  To: martin rudalics; +Cc: Emacs-Devel devel

On Sat, Aug 22, 2009 at 1:00 PM, martin rudalics<rudalics@gmx.at> wrote:

>> So what I need is still a way to apply the new sizes without
>> restriction checks during that phase. Am I clear enough when I try to
>> explain this? How should I do to avoid the restrictions in this phase?
>
> What problems do you have doing your calculations using copies of the
> original sizes?  We can initialize these with the current values and
> retrieve via `window-new-height' and `window-new-width'.


The problem is maybe my broken English... ;-)

There is no problem doing calculations on copies. With "apply" I mean
applying the calculated sizes to Emacs windows.


>> Yes, I know that this is lacking. I have been wondering about this
>> part. It is not clear to me how resizing and deletion/creation of
>> windows are tighed together in the current code. I think those parts
>> should be broken up.
>
> It's not entirely trivial to do that.  Resizing during window deletion
> must succeed, at least in a second attempt.  So if we want to do this in
> Elisp we must be able to resize fixed-size windows and never issue a
> failure.


Yes. I expect we may have to change/override the rules in such cases.
This should be built into the routines doing the calculations.


>> Then I assume that window configurations must be used to get my
>> suggestion to work. The drawback I see then is that window pointers
>> migh gets lost. Are there any way around that?
>
> Which window pointers get lost?


I thought that using window configurations you create new windows
instead of the old ones when restoring the configuration into the
frame. Is not that how it works?

If it is then some elisp code might have pointers to the windows.


> Like "you can restore the previous configuration within a suitable
> frame-size" by hitting ...  Maybe.  Let's add it to the set of possible
> solutions.


Fine.


>>>>> You do undelete all the time.  It's completely transparent.
>>>> How can it be transparent if windows disappears and reappears? I must
>>>> be misunderstanding you somehow...
>>> There might be no redisplay in between.
>>
>> How can you avoid that when the frame gets too small?
>
> `adjust-window-trailing-edge' can temporarily delete a window and
> resurrect it without the user noticing because there's no redisplay in
> between.  When you program in Elisp you can try to inhibit redisplay but
> I would not recommend that.  In any case, I don't understand how this
> should relate to frames getting to small.


There must be some misunderstanding here. Let us skip it for the moment.


>>> In many applications (Thunderbird is one of them) I can make subwindows
>>> disappear completely by dragging one of their borders and make them
>>> reappear later by dragging on the border where they disappeared.
>>
>> Are there no sign at all that there are 0-size windows there?
>
> Thunderbird leaves a horizontal divider behind.


Thanks. What would be the corresponing divider in Emacs? I mean a mode
line for example takes one screen line and would take some space ... -
and then perhaps it will not fit...




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

* Re: moving window handling into lisp
  2009-08-22 13:45                               ` Lennart Borgman
@ 2009-08-22 14:17                                 ` martin rudalics
  0 siblings, 0 replies; 130+ messages in thread
From: martin rudalics @ 2009-08-22 14:17 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Emacs-Devel devel

 > There is no problem doing calculations on copies. With "apply" I mean
 > applying the calculated sizes to Emacs windows.

That's what a function `apply-new-window-sizes' would be for.

 >>> Then I assume that window configurations must be used to get my
 >>> suggestion to work. The drawback I see then is that window pointers
 >>> migh gets lost. Are there any way around that?
 >> Which window pointers get lost?
 >
 > I thought that using window configurations you create new windows
 > instead of the old ones when restoring the configuration into the
 > frame. Is not that how it works?

Doing `set-window-configuration' within the old frame resurrects the old
windows.

 > If it is then some elisp code might have pointers to the windows.

The complete window structure is saved within the configuration together
with a pointer to the window.  This also means that the respective
windows can't be GCed as long as a pointer to the configuration exists.

 > Thanks. What would be the corresponing divider in Emacs? I mean a mode
 > line for example takes one screen line and would take some space ... -
 > and then perhaps it will not fit...

One item on my wishlist are horizontal and vertical dividers I can
display independently from modelines and/or scrollbars.  When I
currently want to drag a vertical divider with the mouse I have to do it
from a fringe :-(

martin




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

* Re: moving window handling into lisp
  2009-08-22  4:55                 ` Stephen J. Turnbull
@ 2009-08-23  1:01                   ` Stefan Monnier
  0 siblings, 0 replies; 130+ messages in thread
From: Stefan Monnier @ 2009-08-23  1:01 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: martin rudalics, grischka, emacs-devel

>> A quick test shows that Firefox handles the issue by letting the
>> window-manager shrink the window at will (down to 1x1 pixels), but its
>> content stops shrinking at some point (so some of the content is
>> clipped).

> FWIW, this is exactly the policy I suggested.  So Mozilla has a time
> machine ....

>> OTOH Empathy and Evolution seem to impose some minimal size below which
>> the window doesn't shrink.  I don't know enough about the underlying
>> protocol to know how they might do that, but presumably it's either done
>> by telling the W-M beforehand what is the minimal size,

> That's it.  In X11, these are called "window manager hints", and as
> the name suggests, the window manager is free to ignore them.  If the
> user doesn't like that behavior, they'll install a different window
> manager, so you had better be prepared to deal with such window
> managers -- it's the user's preference.

Yes: the app should simply tell what are the limits it thinks are good,
and if the W-M shrinks more you get Firefox-style behavior.
In any case: no need to delete any of our windows.


        Stefan




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

* Re: moving window handling into lisp
  2009-08-21 12:22             ` martin rudalics
  2009-08-21 19:32               ` Stefan Monnier
@ 2009-08-24 13:10               ` grischka
  1 sibling, 0 replies; 130+ messages in thread
From: grischka @ 2009-08-24 13:10 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics wrote:
>  > The distributed fuzzy-machine cannot be simplified because it defends
>  > itself by, well, being distributed.
> 
> The weak point of that machine is the size_window routine which IIUC is
> called by most of these distributed components.

It is true that it can weaken the machine if only one routine exists
to access some fundamental functionality.  In such case it would try
to force the implementation of other routines to do somehow the same
thing, just not quite.

There are signs that it has already started to do so with size_window,
e.g. the out-factored shrink_window with a ratio formula somehow
different from the one used for enlarging (as we know by now).

>  >>  > Me thinks there are much more thoughts spend on 'window-min-height'
>  >>  > now than there possibly were at the time when it was first 
> introduced.
>  >>
>  >> Not really.  Any window-manager has to deal with the possibility that a
>  >> window gets to small when its parent-window shrinks.  All we can do is
>  >> make such cases occur rarely, in practice.
>  >
>  > Window-managers don't deal with shrinking parent windows.  They deal
>  > with fixed desktop/root windows.
> 
> I obviously meant "any Emacs window-manager" here.  I don't even know
> whether desktop window-managers use concepts like parent-windows or the
> split-window paradigm.
> 
>  > With individual applications it's called "layout-manager", which exist
>  > in the various GUI toolkits.
>  >
>  > layout-managers are invisible containers that allow you to place
>  > components like widgets or windows of other layout-managers within,
>  > and to set a policy how these components are arranged, such as "box",
>  > "grid", "flow", ...
>  >
>  > The concept of min-size exists too, though individually for each
>  > component, and it actually means what it says, that is "keep this
>  > thing at least that large".  Consequently a case of "too small" can
>  > never happen.
> 
> So if a component doesn't fit it's iconified in some sense of that word?

"Doesn't fit" can only mean that the component can't cope with the
situation by automatic adjustment.

In that case the user is expected to fix the situation manually,
either by configuring the interface, (e.g. removing other components),
or by upgrading the display hardware (such as when you can't see the
OK buttons on some dialogs more frequently).

In any case, iconification (in any sense of the word) belongs to manual
configuration, not to automatic adjustments.

--- grischka

> 
> martin
> 





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

end of thread, other threads:[~2009-08-24 13:10 UTC | newest]

Thread overview: 130+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-27  8:32 moving window handling into lisp Miles Bader
2009-07-27 13:37 ` martin rudalics
2009-07-27 13:41   ` Lennart Borgman
2009-07-27 13:45     ` martin rudalics
2009-07-27 13:58       ` Lennart Borgman
2009-07-27 14:35         ` martin rudalics
2009-07-27 14:41           ` Lennart Borgman
2009-07-27 15:02             ` martin rudalics
2009-07-27 15:28               ` Lennart Borgman
2009-07-27 16:52                 ` martin rudalics
2009-07-27 16:58                   ` Lennart Borgman
2009-07-27 18:18                   ` Stefan Monnier
2009-07-28  7:38                     ` martin rudalics
2009-07-28  9:39                       ` Lennart Borgman
2009-07-28 12:25                         ` martin rudalics
     [not found]                           ` <e01d8a50907280532kcff2d1w15567a430668a502@mail.gmail.com>
2009-07-28 13:23                             ` martin rudalics
2009-07-28 13:44                               ` Lennart Borgman
2009-07-29  9:04                                 ` martin rudalics
2009-07-28 13:47                       ` Stefan Monnier
2009-07-28 14:11                         ` Lennart Borgman
2009-07-29  9:05                         ` martin rudalics
2009-07-29 14:05                           ` Stefan Monnier
2009-08-01  2:20                             ` Miles Bader
2009-08-03 21:29                               ` Stefan Monnier
2009-08-11  9:18                             ` martin rudalics
2009-08-11 19:16                               ` Stefan Monnier
2009-08-11 19:29                                 ` Lennart Borgman
2009-08-12  8:57                                   ` martin rudalics
2009-08-12  9:02                                     ` Lennart Borgman
2009-08-12 13:33                                       ` martin rudalics
2009-08-12 15:57                                         ` Lennart Borgman
2009-08-12 17:05                                           ` martin rudalics
2009-08-12 19:39                                             ` Lennart Borgman
2009-08-12 21:10                                               ` Lennart Borgman
2009-08-13  9:55                                                 ` martin rudalics
2009-08-13  9:57                                                   ` Lennart Borgman
2009-08-13 10:25                                                     ` Lennart Borgman
2009-08-13 11:32                                                       ` Lennart Borgman
2009-08-13 12:49                                                         ` Lennart Borgman
2009-08-13 13:56                                                           ` martin rudalics
2009-08-13 16:43                                                             ` Lennart Borgman
2009-08-13 18:07                                                               ` martin rudalics
2009-08-14  1:13                                                                 ` Lennart Borgman
2009-08-14  7:18                                                                   ` martin rudalics
2009-08-14 11:21                                                                     ` Lennart Borgman
2009-08-14 13:21                                                                       ` martin rudalics
2009-08-12  8:56                                 ` martin rudalics
2009-08-13  2:32                                   ` Stefan Monnier
2009-08-13  9:54                                     ` martin rudalics
2009-08-13 17:00                                       ` Stefan Monnier
2009-08-13 18:09                                         ` martin rudalics
2009-08-14  1:47                                           ` Stephen J. Turnbull
2009-08-14  7:17                                             ` martin rudalics
2009-08-14  6:42                                       ` Richard Stallman
2009-08-14  7:18                                         ` martin rudalics
2009-08-14 20:56                                           ` Richard Stallman
2009-08-15 10:12                                             ` martin rudalics
2009-08-15 19:47                                               ` Stefan Monnier
2009-08-14 15:39                                         ` Stefan Monnier
2009-08-14 15:42                                           ` Lennart Borgman
2009-08-14 18:26                                             ` Stefan Monnier
2009-08-15 10:12                                           ` martin rudalics
2009-08-15 11:02                                             ` Lennart Borgman
2009-08-15 12:44                                               ` martin rudalics
2009-08-15 13:35                                                 ` David Kastrup
2009-08-15 13:39                                                   ` Lennart Borgman
2009-08-15 16:11                                                     ` martin rudalics
2009-08-15 16:19                                                       ` Lennart Borgman
2009-08-15 17:37                                                         ` martin rudalics
2009-08-15 18:18                                                           ` Lennart Borgman
2009-08-16 10:25                                                             ` martin rudalics
2009-08-16 11:14                                                               ` Lennart Borgman
2009-08-16 12:12                                                                 ` David Kastrup
2009-08-16 12:19                                                                   ` Lennart Borgman
2009-08-16 15:17                                                                   ` martin rudalics
2009-08-16 16:15                                                                     ` David Kastrup
2009-08-16 19:24                                                                       ` martin rudalics
2009-08-16 12:17                                                                 ` martin rudalics
2009-08-16 12:26                                                                   ` Lennart Borgman
2009-08-16 15:18                                                                     ` martin rudalics
2009-08-15 19:05                                                           ` Stephen J. Turnbull
2009-08-16 10:26                                                             ` martin rudalics
2009-08-16 11:16                                                               ` Lennart Borgman
2009-08-16 12:17                                                                 ` martin rudalics
2009-08-16 12:29                                                                   ` Lennart Borgman
2009-08-16 15:18                                                                     ` martin rudalics
2009-08-16 14:49                                                               ` Stephen J. Turnbull
2009-08-16 15:31                                                                 ` martin rudalics
2009-08-16 16:28                                                                   ` Stephen J. Turnbull
2009-08-16 19:25                                                                     ` martin rudalics
2009-08-15 15:07                                                   ` Jan Djärv
2009-08-15 15:38                                                     ` David Kastrup
2009-08-15 16:07                                                   ` martin rudalics
2009-08-15 18:21                                                     ` Stephen J. Turnbull
2009-08-16 10:25                                                       ` martin rudalics
2009-08-15 19:51                                             ` Stefan Monnier
2009-08-16 10:26                                               ` martin rudalics
2009-08-16 11:18                                                 ` Lennart Borgman
2009-08-16 12:17                                                   ` martin rudalics
2009-08-16 12:30                                                     ` Lennart Borgman
2009-07-27 14:00   ` Miles Bader
2009-07-27 14:36     ` martin rudalics
     [not found] ` <4A87F8B8.6050102@gmx.at>
     [not found]   ` <e01d8a50908160523r12216cffm34060d2793943785@mail.gmail.com>
     [not found]     ` <4A882312.6020106@gmx.at>
     [not found]       ` <e01d8a50908191816p2d9e978dw6aa0623c79dd8699@mail.gmail.com>
     [not found]         ` <4A8D12B3.6070502@gmx.at>
     [not found]           ` <e01d8a50908200219o69f67900lb9fa9368e9aadf62@mail.gmail.com>
     [not found]             ` <4A8D46C9.1010108@gmx.at>
     [not found]               ` <e01d8a50908200622y101e5b2bq9fb5874cbb8c81fe@mail.gmail.com>
     [not found]                 ` <4A8D66D5.3000600@gmx.at>
2009-08-20 15:41                   ` Lennart Borgman
2009-08-20 18:15                     ` martin rudalics
2009-08-20 23:08                       ` Lennart Borgman
2009-08-21 12:40                         ` martin rudalics
2009-08-21 13:58                           ` Lennart Borgman
2009-08-22 11:00                             ` martin rudalics
2009-08-22 13:45                               ` Lennart Borgman
2009-08-22 14:17                                 ` martin rudalics
2009-08-21 19:34                       ` Stefan Monnier
2009-08-22 11:01                         ` martin rudalics
2009-08-21  0:19                     ` Richard Stallman
2009-08-21 12:40                       ` martin rudalics
  -- strict thread matches above, loose matches on Subject: below --
2009-08-17 19:06 grischka
2009-08-18  7:13 ` martin rudalics
2009-08-18 11:38 ` Lennart Borgman
2009-08-19  9:15   ` grischka
2009-08-19 12:45     ` martin rudalics
2009-08-20 11:45       ` grischka
2009-08-20 12:51         ` martin rudalics
2009-08-20 13:05           ` David Kastrup
2009-08-20 15:08             ` martin rudalics
2009-08-20 19:35           ` grischka
2009-08-21 12:22             ` martin rudalics
2009-08-21 19:32               ` Stefan Monnier
2009-08-22  4:55                 ` Stephen J. Turnbull
2009-08-23  1:01                   ` Stefan Monnier
2009-08-24 13:10               ` grischka
2009-08-19 13:01     ` Lennart Borgman

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