# HG changeset patch # User Richard M. Stallman # Date 855426893 0 # Node ID 8516fb50f3e536d6b4d8b75eb1d1ff206ebb6eb9 # Parent 643e0f90e153c67e4fc81eb65eeb98ddb7c06cb3 (change_window_height): Take size from multiple siblings, nearest ones first, when that can be done without deleting any of them. diff -r 643e0f90e153 -r 8516fb50f3e5 src/window.c --- a/src/window.c Sat Feb 08 18:34:21 1997 +0000 +++ b/src/window.c Sat Feb 08 18:34:53 1997 +0000 @@ -2497,6 +2497,8 @@ register int (*setsizefun) () = (widthflag ? set_window_width : set_window_height); + int maximum; + Lisp_Object next, prev; check_min_window_sizes (); @@ -2545,22 +2547,71 @@ if (delta == 0) return; - if (!NILP (p->next) - && (*sizefun) (p->next) - delta >= MINSIZE (p->next)) + /* Find the total we can get from other siblings. */ + maximum = 0; + for (next = p->next; ! NILP (next); next = XWINDOW (next)->next) + maximum += (*sizefun) (next) - MINSIZE (next); + for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev) + maximum += (*sizefun) (prev) - MINSIZE (prev); + + /* If we can get it all from them, do so. */ + if (delta < maximum) { - (*setsizefun) (p->next, (*sizefun) (p->next) - delta, 0); - (*setsizefun) (window, *sizep + delta, 0); - CURBEG (p->next) += delta; - /* This does not change size of p->next, - but it propagates the new top edge to its children */ - (*setsizefun) (p->next, (*sizefun) (p->next), 0); - } - else if (!NILP (p->prev) - && (*sizefun) (p->prev) - delta >= MINSIZE (p->prev)) - { - (*setsizefun) (p->prev, (*sizefun) (p->prev) - delta, 0); - CURBEG (window) -= delta; - (*setsizefun) (window, *sizep + delta, 0); + Lisp_Object first_unaffected; + Lisp_Object first_affected; + + next = p->next; + prev = p->prev; + first_affected = window; + /* Look at one sibling at a time, + moving away from this window in both directions alternately, + and take as much as we can get without deleting that sibling. */ + while (delta > 0) + { + if (delta == 0) + break; + if (! NILP (next)) + { + int this_one = (*sizefun) (next) - MINSIZE (next); + if (this_one > delta) + this_one = delta; + + (*setsizefun) (next, (*sizefun) (next) - this_one, 0); + (*setsizefun) (window, *sizep + this_one, 0); + + delta -= this_one; + next = XWINDOW (next)->next; + } + if (delta == 0) + break; + if (! NILP (prev)) + { + int this_one = (*sizefun) (prev) - MINSIZE (prev); + if (this_one > delta) + this_one = delta; + + first_affected = prev; + + (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0); + (*setsizefun) (window, *sizep + this_one, 0); + + delta -= this_one; + prev = XWINDOW (prev)->prev; + } + } + + /* Now recalculate the edge positions of all the windows affected, + based on the new sizes. */ + first_unaffected = next; + prev = first_affected; + for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected); + prev = next, next = XWINDOW (next)->next) + { + CURBEG (next) = CURBEG (prev) + (*sizefun) (prev); + /* This does not change size of NEXT, + but it propagates the new top edge to its children */ + (*setsizefun) (next, (*sizefun) (next), 0); + } } else {