all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* resizing frames and windows
@ 2008-04-28 14:57 martin rudalics
  2008-04-29 14:30 ` Chong Yidong
  2008-04-29 16:11 ` Chong Yidong
  0 siblings, 2 replies; 6+ messages in thread
From: martin rudalics @ 2008-04-28 14:57 UTC (permalink / raw)
  To: emacs-devel

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

Dear developers,

attached find a patch for dispnew.c, window.h, and window.c which tries
to fix some problems wrt window resizing.  Please tell me whether it
applies and whether you can build Emacs with it (I currently cannot do
that with the most recent development sources).

In addition please try to answer the following questions (the two
functions at the bottom might be useful for these tests):

(1) Maximize a frame, create some minimal windows (one-line,
     two-columns) in it, and demaximize the frame.  Are all windows
     preserved?

(2) Same as (1) but try to create a no-way-out configuration where
     demaximizing the frame cannot avoid deleting some window(s) - for
     example, because you have two side-by-side windows and the
     demaximized frame can accomodate at most one such window.  Does
     resizing behave reasonably?

(3) Save the window-configurations of (1) and (2) in a maximized frame,
     demaximize the frame, change the layout arbitrarily, and set the
     window configuration to the saved one.  Does the resulting
     configuration appear reasonable?

(4) Split some window vertically, and repeatedly apply
     `my-enlarge-window'.  Is the other window deleted when its height
     drops below `window-min-height'?  Does it for other (possibly
     invalid) values of `window-min-height'?

(5) Split some window horizontally, and repeatedly apply
     `my-enlarge-window-horizontally'.  Is the other window deleted when
     its width drops below `window-min-width'?  Does it for other
     (possibly invalid) values of `window-min-width'?

(6) Create a one-line window at the bottom of the frame and try to
     resize the minibuffer.  Is the one-line window's modeline retained?

(7) After all these tests: Does customizing `window-min-height' and
     `window-min-width' work as expected?

Some of these issues were more or less broken in Emacsen I built over
the previous months.  Please help me to eliminate these problems.

Pretty please.


(defun my-enlarge-window ()
   (interactive)
   (let ((window-min-height 1))
     (enlarge-window 1)))

(defun my-enlarge-window-horizontally ()
   (interactive)
   (let ((window-min-width 2))
     (enlarge-window 1 t)))

[-- Attachment #2: resize-windows.patch --]
[-- Type: text/plain, Size: 48610 bytes --]

*** dispnew.c	Mon Mar 10 00:49:46 2008
--- dispnew.c	Mon Apr 28 10:53:18 2008
***************
*** 6341,6347 ****
  			     (newheight
  			      - 1
  			      - FRAME_TOP_MARGIN (f)),
! 			      0);
  	  XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
  		       newheight - 1);
  	  set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
--- 6341,6347 ----
  			     (newheight
  			      - 1
  			      - FRAME_TOP_MARGIN (f)),
! 			     2);
  	  XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
  		       newheight - 1);
  	  set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
***************
*** 6349,6355 ****
        else
  	/* Frame has just one top-level window.  */
  	set_window_height (FRAME_ROOT_WINDOW (f),
! 			   newheight - FRAME_TOP_MARGIN (f), 0);
  
        if (FRAME_TERMCAP_P (f) && !pretend)
  	FrameRows (FRAME_TTY (f)) = newheight;
--- 6349,6355 ----
        else
  	/* Frame has just one top-level window.  */
  	set_window_height (FRAME_ROOT_WINDOW (f),
! 			   newheight - FRAME_TOP_MARGIN (f), 2);
  
        if (FRAME_TERMCAP_P (f) && !pretend)
  	FrameRows (FRAME_TTY (f)) = newheight;
***************
*** 6357,6363 ****
  
    if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
      {
!       set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0);
        if (FRAME_HAS_MINIBUF_P (f))
  	set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
  
--- 6357,6363 ----
  
    if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
      {
!       set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2);
        if (FRAME_HAS_MINIBUF_P (f))
  	set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
  
*** window.h	Mon Jan 28 19:05:10 2008
--- window.h	Mon Apr 28 10:54:02 2008
***************
*** 222,229 ****
      /* If redisplay in this window goes beyond this buffer position,
         must run the redisplay-end-trigger-hook.  */
      Lisp_Object redisplay_end_trigger;
!     /* Non-nil means don't delete this window for becoming "too small".  */
!     Lisp_Object too_small_ok;
  
      /* Original window height and top before mini-window was
         enlarged. */
--- 222,230 ----
      /* If redisplay in this window goes beyond this buffer position,
         must run the redisplay-end-trigger-hook.  */
      Lisp_Object redisplay_end_trigger;
!     /* Non-nil means resizing windows will attempt to resize this window
!        proportionally.  */
!     Lisp_Object resize_proportionally;
  
      /* Original window height and top before mini-window was
         enlarged. */
***************
*** 337,356 ****
  #define WINDOW_FRAME_LINE_HEIGHT(W) \
    (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
  
! 
! /* Return the frame width in canonical column units.
     This includes scroll bars and fringes.  */
  
  #define WINDOW_TOTAL_COLS(W) \
    (XFASTINT ((W)->total_cols))
  
! /* Return the frame height in canonical line units.
     This includes header and mode lines, if any.  */
  
  #define WINDOW_TOTAL_LINES(W) \
    (XFASTINT ((W)->total_lines))
  
- 
  /* Return the total pixel width of window W.  */
  
  #define WINDOW_TOTAL_WIDTH(W) \
--- 338,355 ----
  #define WINDOW_FRAME_LINE_HEIGHT(W) \
    (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
  
! /* Return the width of window W in canonical column units.
     This includes scroll bars and fringes.  */
  
  #define WINDOW_TOTAL_COLS(W) \
    (XFASTINT ((W)->total_cols))
  
! /* Return the height of window W in canonical line units.
     This includes header and mode lines, if any.  */
  
  #define WINDOW_TOTAL_LINES(W) \
    (XFASTINT ((W)->total_lines))
  
  /* Return the total pixel width of window W.  */
  
  #define WINDOW_TOTAL_WIDTH(W) \

*** window.c	Wed Apr  2 22:15:44 2008
--- window.c	Mon Apr 28 11:08:24 2008
***************
*** 65,73 ****
  static void window_scroll P_ ((Lisp_Object, int, int, int));
  static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
  static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
! static int window_min_size_1 P_ ((struct window *, int));
! static int window_min_size_2 P_ ((struct window *, int));
! static int window_min_size P_ ((struct window *, int, int, int *));
  static void size_window P_ ((Lisp_Object, int, int, int, int, int));
  static int freeze_window_start P_ ((struct window *, void *));
  static int window_fixed_size_p P_ ((struct window *, int, int));
--- 65,73 ----
  static void window_scroll P_ ((Lisp_Object, int, int, int));
  static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
  static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
! static int window_min_size_1 P_ ((struct window *, int, int));
! static int window_min_size_2 P_ ((struct window *, int, int));
! static int window_min_size P_ ((struct window *, int, int, int, int *));
  static void size_window P_ ((Lisp_Object, int, int, int, int, int));
  static int freeze_window_start P_ ((struct window *, void *));
  static int window_fixed_size_p P_ ((struct window *, int, int));
***************
*** 299,304 ****
--- 299,305 ----
    p->fringes_outside_margins = Qnil;
    p->scroll_bar_width = Qnil;
    p->vertical_scroll_bar_type = Qt;
+   p->resize_proportionally = Qnil;
  
    Vwindow_list = Qnil;
    return val;
***************
*** 2550,2567 ****
  #define MIN_SAFE_WINDOW_WIDTH  (2)
  #define MIN_SAFE_WINDOW_HEIGHT (1)
  
! /* Make sure that window_min_height and window_min_width are
!    not too small; if they are, set them to safe minima.  */
  
! static void
! check_min_window_sizes ()
! {
!   /* Smaller values might permit a crash.  */
!   if (window_min_width < MIN_SAFE_WINDOW_WIDTH)
!     window_min_width = MIN_SAFE_WINDOW_WIDTH;
!   if (window_min_height < MIN_SAFE_WINDOW_HEIGHT)
!     window_min_height = MIN_SAFE_WINDOW_HEIGHT;
! }
  
  /* If *ROWS or *COLS are too small a size for FRAME, set them to the
     minimum allowable size.  */
--- 2551,2561 ----
  #define MIN_SAFE_WINDOW_WIDTH  (2)
  #define MIN_SAFE_WINDOW_HEIGHT (1)
  
! /* For wp non-zero the total number of columns of window w.  Otherwise
!    the total number of lines of w.  */
  
! #define WINDOW_TOTAL_SIZE(w, wp) \
!   (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
  
  /* If *ROWS or *COLS are too small a size for FRAME, set them to the
     minimum allowable size.  */
***************
*** 2608,2614 ****
  
        if (width_p)
  	{
! 	  /* A horiz. combination is fixed-width if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2602,2608 ----
  
        if (width_p)
  	{
! 	  /* A horizontal combination is fixed-width if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2616,2622 ****
  	}
        else
  	{
! 	  /* A horiz. combination is fixed-height if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2610,2616 ----
  	}
        else
  	{
! 	  /* A horizontal combination is fixed-height if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2629,2635 ****
  
        if (width_p)
  	{
! 	  /* A vert. combination is fixed-width if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2623,2629 ----
  
        if (width_p)
  	{
! 	  /* A vertical combination is fixed-width if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2637,2643 ****
  	}
        else
  	{
! 	  /* A vert. combination is fixed-height if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2631,2637 ----
  	}
        else
  	{
! 	  /* A vertical combination is fixed-height if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2689,2808 ****
    return fixed_p;
  }
  
! /* Return the minimum size for leaf window W.  WIDTH_P non-zero means
!    take into account fringes and the scrollbar of W.  WIDTH_P zero means
!    take into account mode-line of W.  Return 1 for the minibuffer.  */
  
  static int
! window_min_size_2 (w, width_p)
       struct window *w;
!      int width_p;
  {
!   int size;
!   
    if (width_p)
!     size = max (window_min_width,
! 		(MIN_SAFE_WINDOW_WIDTH
  		 + WINDOW_FRINGE_COLS (w)
! 		 + WINDOW_SCROLL_BAR_COLS (w)));
    else if (MINI_WINDOW_P (w))
!     size = 1;
    else
!     size = max (window_min_height,
! 		(MIN_SAFE_WINDOW_HEIGHT
! 		 /* Don't count the header-line here.  It would break
! 		    splitting a window with a header-line when the new
! 		    window shall have a height of two (calculator does
! 		    that). */
! 		 + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
! 
!   return size;
  }
  
! /* Return the minimum size of window W, not taking fixed-width windows
!    into account.  WIDTH_P non-zero means return the minimum width,
!    otherwise return the minimum height.  If W is a combination window,
!    compute the minimum size from the minimum sizes of W's children.  */
  
  static int
! window_min_size_1 (w, width_p)
       struct window *w;
!      int width_p;
  {
    struct window *c;
    int size;
  
    if (!NILP (w->hchild))
      {
        c = XWINDOW (w->hchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The min width of a horizontal combination is
! 	     the sum of the min widths of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, width_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The min height a horizontal combination equals
! 	     the maximum of all min height of its children.  */
  	  while (c)
  	    {
! 	      int min_size = window_min_size_1 (c, width_p);
! 	      size = max (min_size, size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else if (!NILP (w->vchild))
      {
        c = XWINDOW (w->vchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The min width of a vertical combination is
! 	     the maximum of the min widths of its children.  */
  	  while (c)
  	    {
! 	      int min_size = window_min_size_1 (c, width_p);
! 	      size = max (min_size, size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The min height of a vertical combination equals
! 	     the sum of the min height of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, width_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else
!     size = window_min_size_2 (w, width_p);
  
    return size;
  }
  
- 
  /* Return the minimum size of window W, taking fixed-size windows into
!    account.  WIDTH_P non-zero means return the minimum width,
!    otherwise return the minimum height.  IGNORE_FIXED_P non-zero means
!    ignore if W is fixed-size.  Set *FIXED to 1 if W is fixed-size
!    unless FIXED is null.  */
  
  static int
! window_min_size (w, width_p, ignore_fixed_p, fixed)
       struct window *w;
!      int width_p, ignore_fixed_p, *fixed;
  {
    int size, fixed_p;
  
--- 2683,2812 ----
    return fixed_p;
  }
  
! /* Return minimum size of leaf window W.  WIDTH_P non-zero means return
!    the minimum width of W, WIDTH_P zero means return the minimum height
!    of W.  SAFE_P non-zero means ignore window-min-height|width but just
!    return values that won't crash Emacs and don't hide components like
!    fringes, scrollbars, or modelines.  If WIDTH_P is zero and W is the
!    minibuffer window, always return 1.  */
  
  static int
! window_min_size_2 (w, width_p, safe_p)
       struct window *w;
!      int width_p, safe_p;
  {
!   /* We should consider buffer-local values of window_min_height and
!      window_min_width here.  */
    if (width_p)
!     {
!       int safe_size = (MIN_SAFE_WINDOW_WIDTH
  		 + WINDOW_FRINGE_COLS (w)
! 		       + WINDOW_SCROLL_BAR_COLS (w));
! 
!       return safe_p ? safe_size : max (window_min_width, safe_size);
!     }
    else if (MINI_WINDOW_P (w))
!     return 1;
    else
!     {
!       int safe_size = (MIN_SAFE_WINDOW_HEIGHT
! 		       + ((BUFFERP (w->buffer)
! 			   && !NILP (XBUFFER (w->buffer)->mode_line_format))
! 			  ? 1 : 0));
! 
!       return safe_p ? safe_size : max (window_min_height, safe_size);
!     }
  }
  
! /* Return minimum size of window W, not taking fixed-width windows into
!    account.  WIDTH_P non-zero means return the minimum width, otherwise
!    return the minimum height.  SAFE_P non-zero means ignore
!    window-min-height|width but just return values that won't crash Emacs
!    and don't hide components like fringes, scrollbars, or modelines.  If
!    W is a combination window, compute the minimum size from the minimum
!    sizes of W's children.  */
  
  static int
! window_min_size_1 (w, width_p, safe_p)
       struct window *w;
!      int width_p, safe_p;
  {
    struct window *c;
    int size;
  
    if (!NILP (w->hchild))
      {
+       /* W is a horizontal combination.  */
        c = XWINDOW (w->hchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The minimum width of a horizontal combination is the sum of
! 	     the minimum widths of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, 1, safe_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The minimum height of a horizontal combination is the
! 	     maximum of the minimum heights of its children.  */
  	  while (c)
  	    {
! 	      size = max (window_min_size_1 (c, 0, safe_p), size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else if (!NILP (w->vchild))
      {
+       /* W is a vertical combination.  */
        c = XWINDOW (w->vchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The minimum width of a vertical combination is the maximum
! 	     of the minimum widths of its children.  */
  	  while (c)
  	    {
! 	      size = max (window_min_size_1 (c, 1, safe_p), size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The minimum height of a vertical combination is the sum of
! 	     the minimum height of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, 0, safe_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else
!     /* W is a leaf window.  */
!     size = window_min_size_2 (w, width_p, safe_p);
  
    return size;
  }
  
  /* Return the minimum size of window W, taking fixed-size windows into
!    account.  WIDTH_P non-zero means return the minimum width, otherwise
!    return the minimum height.  SAFE_P non-zero means ignore
!    window-min-height|width but just return values that won't crash Emacs
!    and don't hide components like fringes, scrollbars, or modelines.
!    IGNORE_FIXED_P non-zero means ignore if W is fixed-size.  Set *FIXED
!    to 1 if W is fixed-size unless FIXED is null.  */
  
  static int
! window_min_size (w, width_p, safe_p, ignore_fixed_p, fixed)
       struct window *w;
!      int width_p, safe_p, ignore_fixed_p, *fixed;
  {
    int size, fixed_p;
  
***************
*** 2815,2823 ****
      *fixed = fixed_p;
  
    if (fixed_p)
!     size = width_p ? XFASTINT (w->total_cols) : XFASTINT (w->total_lines);
    else
!     size = window_min_size_1 (w, width_p);
  
    return size;
  }
--- 2819,2827 ----
      *fixed = fixed_p;
  
    if (fixed_p)
!     size = WINDOW_TOTAL_SIZE (w, width_p);
    else
!     size = window_min_size_1 (w, width_p, safe_p);
  
    return size;
  }
***************
*** 2859,2893 ****
    return 1;
  }
  
! /* Calculate new sizes for windows in the list FORWARD when the window size
!    goes from TOTAL to SIZE.  TOTAL must be greater than SIZE.
!    The number of windows in FORWARD is NCHILDREN, and the number that
!    can shrink is SHRINKABLE.
!    The minimum size a window can have is MIN_SIZE.
!    If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
!    If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
!    shrinking rows.
  
     This function returns an allocated array of new sizes that the caller
!    must free.  The size -1 means the window is fixed and RESIZE_FIXED_P
!    is zero.  Array index 0 refers to the first window in FORWARD, 1 to
!    the second, and so on.
! 
!    This function tries to keep windows at least at the minimum size
!    and resize other windows before it resizes any window to zero (i.e.
!    delete that window).
! 
!    Windows are resized proportional to their size, so bigger windows
!    shrink more than smaller windows.  */
  static int *
! shrink_windows (total, size, nchildren, shrinkable,
!                 min_size, resize_fixed_p, forward, width_p)
!      int total, size, nchildren, shrinkable, min_size;
!      int resize_fixed_p, width_p;
       Lisp_Object forward;
  {
    int available_resize = 0;
!   int *new_sizes;
    struct window *c;
    Lisp_Object child;
    int smallest = total;
--- 2863,2900 ----
    return 1;
  }
  
! /* Calculate new sizes for windows in the list FORWARD when their
!    compound size goes from TOTAL to SIZE.  TOTAL must be greater than
!    SIZE.  The number of windows in FORWARD is NCHILDREN, and the number
!    that can shrink is SHRINKABLE.  Fixed-size windows may be shrunk if
!    and only if RESIZE_FIXED_P is non-zero.  WIDTH_P non-zero means
!    shrink columns, otherwise shrink lines.
! 
!    SAFE_P zero means windows may be sized down to window-min-height
!    lines (window-min-window columns for WIDTH_P non-zero).  SAFE_P
!    non-zero means windows may be sized down to their minimum safe sizes
!    taking into account the space needed to display modelines, fringes,
!    and scrollbars.
  
     This function returns an allocated array of new sizes that the caller
!    must free.  A size -1 means the window is fixed and RESIZE_FIXED_P is
!    zero.  A size zero means the window shall be deleted.  Array index 0
!    refers to the first window in FORWARD, 1 to the second, and so on.
! 
!    This function resizes windows proportionally to their size.  It also
!    tries to preserve smaller windows by resizing larger windows before
!    resizing any window to zero.  If resize_proportionally is non-nil for
!    a specific window, it will attempt to strictly resize that window
!    proportionally, even at the expense of deleting smaller windows.  */
  static int *
! shrink_windows (total, size, nchildren, shrinkable, resize_fixed_p,
! 		forward, width_p, safe_p)
!      int total, size, nchildren, shrinkable;
!      int resize_fixed_p, width_p, safe_p;
       Lisp_Object forward;
  {
    int available_resize = 0;
!   int *new_sizes, *min_sizes;
    struct window *c;
    Lisp_Object child;
    int smallest = total;
***************
*** 2896,2916 ****
    int i;
  
    new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
  
    for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
      {
        int child_size;
  
        c = XWINDOW (child);
!       child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
  
!       if (! resize_fixed_p && window_fixed_size_p (c, width_p, 0))
          new_sizes[i] = -1;
        else
          {
            new_sizes[i] = child_size;
!           if (child_size > min_size)
!             available_resize += child_size - min_size;
          }
      }
    /* We might need to shrink some windows to zero.  Find the smallest
--- 2903,2926 ----
    int i;
  
    new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
+   min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
  
    for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
      {
        int child_size;
  
        c = XWINDOW (child);
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
  
!       if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
          new_sizes[i] = -1;
        else
          {
            new_sizes[i] = child_size;
!           min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
!           if (child_size > min_sizes[i]
! 	      && NILP (c->resize_proportionally))
!             available_resize += child_size - min_sizes[i];
          }
      }
    /* We might need to shrink some windows to zero.  Find the smallest
***************
*** 2927,2934 ****
            {
              /* Resize this window down to zero.  */
              new_sizes[i] = 0;
!             if (smallest > min_size)
!               available_resize -= smallest - min_size;
              available_resize += smallest;
              --shrinkable;
              total_removed += smallest;
--- 2937,2944 ----
            {
              /* Resize this window down to zero.  */
              new_sizes[i] = 0;
!             if (smallest > min_sizes[i])
!               available_resize -= smallest - min_sizes[i];
              available_resize += smallest;
              --shrinkable;
              total_removed += smallest;
***************
*** 2946,2956 ****
       proportional to its size.  */
    for (i = 0; i < nchildren; ++i)
      {
!       if (new_sizes[i] > min_size)
          {
!           int to_shrink = total_shrink*new_sizes[i]/total;
!           if (new_sizes[i] - to_shrink < min_size)
!             to_shrink = new_sizes[i] - min_size;
            new_sizes[i] -= to_shrink;
            total_removed += to_shrink;
          }
--- 2956,2967 ----
       proportional to its size.  */
    for (i = 0; i < nchildren; ++i)
      {
!       if (new_sizes[i] > min_sizes[i])
          {
!           int to_shrink = total_shrink * new_sizes[i] / total;
! 
!           if (new_sizes[i] - to_shrink < min_sizes[i])
!             to_shrink = new_sizes[i] - min_sizes[i];
            new_sizes[i] -= to_shrink;
            total_removed += to_shrink;
          }
***************
*** 2971,2977 ****
            }
  
        for (i = 0; i < nchildren; ++i)
!         if (new_sizes[i] > min_size)
            {
              --new_sizes[i];
              ++total_removed;
--- 2982,2988 ----
            }
  
        for (i = 0; i < nchildren; ++i)
!         if (new_sizes[i] > min_sizes[i])
            {
              --new_sizes[i];
              ++total_removed;
***************
*** 2981,2987 ****
              break;
            }
  
- 
        /* Special case, only one window left.  */
        if (nonzero_sizes == 1)
          break;
--- 2992,2997 ----
***************
*** 3001,3022 ****
          }
      }
  
    return new_sizes;
  }
  
  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
!    WINDOW's width.  Resize WINDOW's children, if any, so that they
!    keep their proportionate size relative to WINDOW.
  
     If FIRST_ONLY is 1, change only the first of WINDOW's children when
     they are in series.  If LAST_ONLY is 1, change only the last of
     WINDOW's children when they are in series.
  
     Propagate WINDOW's top or left edge position to children.  Delete
!    windows that become too small unless NODELETE_P is non-zero.
! 
!    If NODELETE_P is 2, that means we do delete windows that are
!    too small, even if they were too small before!  */
  
  static void
  size_window (window, size, width_p, nodelete_p, first_only, last_only)
--- 3011,3034 ----
          }
      }
  
+   xfree (min_sizes);
+ 
    return new_sizes;
  }
  
  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
!    WINDOW's width.  Resize WINDOW's children, if any, so that they keep
!    their proportionate size relative to WINDOW.
  
     If FIRST_ONLY is 1, change only the first of WINDOW's children when
     they are in series.  If LAST_ONLY is 1, change only the last of
     WINDOW's children when they are in series.
  
     Propagate WINDOW's top or left edge position to children.  Delete
!    windows that become too small unless NODELETE_P is 1.  When
!    NODELETE_P equals 2 do not honor settings for window-min-height and
!    window-min-width when resizing windows but use safe defaults instead.
!    This should give better behavior when resizing frames.  */
  
  static void
  size_window (window, size, width_p, nodelete_p, first_only, last_only)
***************
*** 3027,3073 ****
    struct window *w = XWINDOW (window);
    struct window *c;
    Lisp_Object child, *forward, *sideward;
!   int old_size, min_size, safe_min_size;
  
-   check_min_window_sizes ();
    size = max (0, size);
  
!   /* If the window has been "too small" at one point,
!      don't delete it for being "too small" in the future.
!      Preserve it as long as that is at all possible.  */
!   if (width_p)
!     {
!       old_size = WINDOW_TOTAL_COLS (w);
!       min_size = window_min_width;
!       safe_min_size = window_min_size_2 (w, 1);
!     }
!   else
!     {
!       old_size = XINT (w->total_lines);
!       min_size = window_min_height;
!       safe_min_size = window_min_size_2 (w, 0);
!     }
! 
!   if (old_size < min_size && nodelete_p != 2)
!     w->too_small_ok = Qt;
! 
!   /* Move the following test here since otherwise the
!      preceding test doesn't make sense.  martin. */
!   if (nodelete_p == 2)
!     nodelete_p = 0;
! 
!   /* Maybe delete WINDOW if it's too small.  */
!   if (nodelete_p != 1 && !NILP (w->parent))
      {
!       if (!MINI_WINDOW_P (w) && !NILP (w->too_small_ok))
! 	min_size = width_p ? MIN_SAFE_WINDOW_WIDTH : MIN_SAFE_WINDOW_HEIGHT;
!       if (min_size < safe_min_size)
! 	min_size = safe_min_size;
!       if (size < min_size)
! 	{
! 	  delete_window (window);
! 	  return;
! 	}
      }
  
    /* Set redisplay hints.  */
--- 3039,3054 ----
    struct window *w = XWINDOW (window);
    struct window *c;
    Lisp_Object child, *forward, *sideward;
!   int old_size = WINDOW_TOTAL_SIZE (w, width_p);
  
    size = max (0, size);
  
!   /* Delete WINDOW if it's too small.  */
!   if (nodelete_p != 1 && !NILP (w->parent)
!       && size < window_min_size_1 (w, width_p, nodelete_p == 2))
      {
!       delete_window (window);
!       return;
      }
  
    /* Set redisplay hints.  */
***************
*** 3117,3125 ****
  	  last_child = child;
  	}
  
!       child_size = XINT (width_p ? c->total_cols : c->total_lines);
!       size_window (last_child,
! 		   size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward) && first_only)
--- 3098,3105 ----
  	  last_child = child;
  	}
  
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
!       size_window (last_child, size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward) && first_only)
***************
*** 3135,3143 ****
        else
  	c->top_line = w->top_line;
  
!       child_size = XINT (width_p ? c->total_cols : c->total_lines);
!       size_window (child,
! 		   size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward))
--- 3115,3122 ----
        else
  	c->top_line = w->top_line;
  
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
!       size_window (child, size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward))
***************
*** 3155,3161 ****
  	  int child_size;
  
  	  c = XWINDOW (child);
! 	  child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
  	  total += child_size;
  
  	  if (window_fixed_size_p (c, width_p, 0))
--- 3134,3140 ----
  	  int child_size;
  
  	  c = XWINDOW (child);
! 	  child_size = WINDOW_TOTAL_SIZE (c, width_p);
  	  total += child_size;
  
  	  if (window_fixed_size_p (c, width_p, 0))
***************
*** 3174,3181 ****
  	 value of extra takes care of rounding errors.  */
        n = resize_fixed_p ? nchildren : nchildren - nfixed;
        if (size < total && n > 1)
!         new_sizes = shrink_windows (total, size, nchildren, n, min_size,
!                                     resize_fixed_p, *forward, width_p);
        else
          {
            each = (size - total) / n;
--- 3153,3161 ----
  	 value of extra takes care of rounding errors.  */
        n = resize_fixed_p ? nchildren : nchildren - nfixed;
        if (size < total && n > 1)
!         new_sizes = shrink_windows (total, size, nchildren, n,
!                                     resize_fixed_p, *forward, width_p,
! 				    nodelete_p == 2);
        else
          {
            each = (size - total) / n;
***************
*** 3190,3196 ****
  	  int new_size, old_size;
  
  	  c = XWINDOW (child);
! 	  old_size = width_p ? XFASTINT (c->total_cols) : XFASTINT (c->total_lines);
  	  new_size = old_size;
  
  	  /* The top or left edge position of this child equals the
--- 3170,3176 ----
  	  int new_size, old_size;
  
  	  c = XWINDOW (child);
! 	  old_size = WINDOW_TOTAL_SIZE (c, width_p);
  	  new_size = old_size;
  
  	  /* The top or left edge position of this child equals the
***************
*** 3207,3213 ****
  	      extra = 0;
  	    }
  
! 	  /* Set new height.  Note that size_window also propagates
  	     edge positions to children, so it's not a no-op if we
  	     didn't change the child's size.  */
  	  size_window (child, new_size, width_p, 1, first_only, last_only);
--- 3187,3193 ----
  	      extra = 0;
  	    }
  
! 	  /* Set new size.  Note that size_window also propagates
  	     edge positions to children, so it's not a no-op if we
  	     didn't change the child's size.  */
  	  size_window (child, new_size, width_p, 1, first_only, last_only);
***************
*** 3223,3243 ****
        xassert (size == last_pos - first_pos);
  
        /* Now delete any children that became too small.  */
!       if (!nodelete_p)
  	for (child = *forward; !NILP (child); child = c->next)
  	  {
  	    int child_size;
  	    c = XWINDOW (child);
! 	    child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
! 	    size_window (child, child_size, width_p, 2, first_only, last_only);
  	  }
      }
  }
  
  /* Set WINDOW's height to HEIGHT, and recursively change the height of
!    WINDOW's children.  NODELETE non-zero means don't delete windows
!    that become too small in the process.  (The caller should check
!    later and do so if appropriate.)  */
  
  void
  set_window_height (window, height, nodelete)
--- 3203,3228 ----
        xassert (size == last_pos - first_pos);
  
        /* Now delete any children that became too small.  */
!       if (nodelete_p != 1)
  	for (child = *forward; !NILP (child); child = c->next)
  	  {
  	    int child_size;
+ 
  	    c = XWINDOW (child);
! 	    child_size = WINDOW_TOTAL_SIZE (c, width_p);
! 	    size_window (child, child_size, width_p, nodelete_p,
! 			 first_only, last_only);
  	  }
      }
  }
  
  /* Set WINDOW's height to HEIGHT, and recursively change the height of
!    WINDOW's children.  NODELETE zero means windows that have become
!    smaller than window-min-height in the process may be deleted.
!    NODELETE 1 means never delete windows that become too small in the
!    process.  (The caller should check later and do so if appropriate.)
!    NODELETE 2 means delete only windows that have become too small to be
!    displayed correctly.  */
  
  void
  set_window_height (window, height, nodelete)
***************
*** 3248,3258 ****
    size_window (window, height, 0, nodelete, 0, 0);
  }
  
- 
  /* Set WINDOW's width to WIDTH, and recursively change the width of
!    WINDOW's children.  NODELETE non-zero means don't delete windows
!    that become too small in the process.  (The caller should check
!    later and do so if appropriate.)  */
  
  void
  set_window_width (window, width, nodelete)
--- 3233,3245 ----
    size_window (window, height, 0, nodelete, 0, 0);
  }
  
  /* Set WINDOW's width to WIDTH, and recursively change the width of
!    WINDOW's children.  NODELETE zero means windows that have become
!    smaller than window-min-width in the process may be deleted.
!    NODELETE 1 means never delete windows that become too small in the
!    process.  (The caller should check later and do so if appropriate.)
!    NODELETE 2 means delete only windows that have become too small to be
!    displayed correctly.  */
  
  void
  set_window_width (window, width, nodelete)
***************
*** 3359,3365 ****
      }
        }
    }
!   
    run_funs (global_wcch);
    unbind_to (count, Qnil);
  }
--- 3346,3352 ----
      }
        }
    }
! 
    run_funs (global_wcch);
    unbind_to (count, Qnil);
  }
***************
*** 4124,4135 ****
    else if (window_fixed_size_p (o, !NILP (horflag), 0))
      error ("Attempt to split fixed-size window");
  
-   check_min_window_sizes ();
- 
    if (NILP (horflag))
      {
!       int window_safe_height = window_min_size_2 (o, 0);
!       
        if (size_int < window_safe_height)
  	error ("Window height %d too small (after splitting)", size_int);
        if (size_int + window_safe_height > XFASTINT (o->total_lines))
--- 4111,4120 ----
    else if (window_fixed_size_p (o, !NILP (horflag), 0))
      error ("Attempt to split fixed-size window");
  
    if (NILP (horflag))
      {
!       int window_safe_height = window_min_size_2 (o, 0, 0);
! 
        if (size_int < window_safe_height)
  	error ("Window height %d too small (after splitting)", size_int);
        if (size_int + window_safe_height > XFASTINT (o->total_lines))
***************
*** 4145,4152 ****
      }
    else
      {
!       int window_safe_width = window_min_size_2 (o, 1);
!       
        if (size_int < window_safe_width)
  	error ("Window width %d too small (after splitting)", size_int);
        if (size_int + window_safe_width > XFASTINT (o->total_cols))
--- 4130,4137 ----
      }
    else
      {
!       int window_safe_width = window_min_size_2 (o, 1, 0);
! 
        if (size_int < window_safe_width)
  	error ("Window width %d too small (after splitting)", size_int);
        if (size_int + window_safe_width > XFASTINT (o->total_cols))
***************
*** 4277,4288 ****
    *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
  
  
! /* Enlarge WINDOW by DELTA.
!    HORIZ_FLAG nonzero means enlarge it horizontally;
!    zero means do it vertically.
  
     Siblings of the selected window are resized to fulfill the size
!    request.  If they become too small in the process, they will be
     deleted.  */
  
  static void
--- 4262,4272 ----
    *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
  
  
! /* Enlarge WINDOW by DELTA.  HORIZ_FLAG nonzero means enlarge it
!    horizontally; zero means do it vertically.
  
     Siblings of the selected window are resized to fulfill the size
!    request.  If they become too small in the process, they may be
     deleted.  */
  
  static void
***************
*** 4299,4308 ****
    void (*setsizefun) P_ ((Lisp_Object, int, int))
      = (horiz_flag ? set_window_width : set_window_height);
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    /* Give up if this window cannot be resized.  */
    if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
      error ("Window is not resizable");
--- 4283,4288 ----
***************
*** 4339,4349 ****
  		/* This is a main window followed by a minibuffer.  */
  		: !NILP (p->next) ? ((*sizefun) (p->next)
  				     - window_min_size (XWINDOW (p->next),
! 							horiz_flag, 0, 0))
  		/* This is a minibuffer following a main window.  */
  		: !NILP (p->prev) ? ((*sizefun) (p->prev)
  				     - window_min_size (XWINDOW (p->prev),
! 							horiz_flag, 0, 0))
  		/* This is a frame with only one window, a minibuffer-only
  		   or a minibufferless frame.  */
  		: (delta = 0));
--- 4319,4329 ----
  		/* This is a main window followed by a minibuffer.  */
  		: !NILP (p->next) ? ((*sizefun) (p->next)
  				     - window_min_size (XWINDOW (p->next),
! 							horiz_flag, 0, 0, 0))
  		/* This is a minibuffer following a main window.  */
  		: !NILP (p->prev) ? ((*sizefun) (p->prev)
  				     - window_min_size (XWINDOW (p->prev),
! 							horiz_flag, 0, 0, 0))
  		/* This is a frame with only one window, a minibuffer-only
  		   or a minibufferless frame.  */
  		: (delta = 0));
***************
*** 4355,4361 ****
        delta = maxdelta;
    }
  
!   if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0))
      {
        delete_window (window);
        return;
--- 4335,4342 ----
        delta = maxdelta;
    }
  
!   if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
! 					       horiz_flag, 0, 0, 0))
      {
        delete_window (window);
        return;
***************
*** 4368,4377 ****
    maximum = 0;
    for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
      maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
! 						    horiz_flag, 0, 0);
    for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
      maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
! 						    horiz_flag, 0, 0);
  
    /* If we can get it all from them without deleting them, do so.  */
    if (delta <= maximum)
--- 4349,4358 ----
    maximum = 0;
    for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
      maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
! 						    horiz_flag, 0, 0, 0);
    for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
      maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
! 						    horiz_flag, 0, 0, 0);
  
    /* If we can get it all from them without deleting them, do so.  */
    if (delta <= maximum)
***************
*** 4392,4399 ****
  	  if (! NILP (next))
  	    {
  	      int this_one = ((*sizefun) (next)
! 			      - window_min_size (XWINDOW (next),
! 						 horiz_flag, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
--- 4373,4380 ----
  	  if (! NILP (next))
  	    {
  	      int this_one = ((*sizefun) (next)
! 			      - window_min_size (XWINDOW (next), horiz_flag,
! 						 0, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
***************
*** 4414,4421 ****
  	  if (! NILP (prev))
  	    {
  	      int this_one = ((*sizefun) (prev)
! 			      - window_min_size (XWINDOW (prev),
! 						 horiz_flag, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
--- 4395,4402 ----
  	  if (! NILP (prev))
  	    {
  	      int this_one = ((*sizefun) (prev)
! 			      - window_min_size (XWINDOW (prev), horiz_flag,
! 						 0, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
***************
*** 4474,4480 ****
  
  	  /* Delete any siblings that come after WINDOW.
  	     Note that if START is not WINDOW, then WINDOW still
! 	     Fhas siblings, so WINDOW has not yet replaced its parent.  */
  	  tem = start;
  	  while (! EQ (tem, window))
  	    {
--- 4455,4461 ----
  
  	  /* Delete any siblings that come after WINDOW.
  	     Note that if START is not WINDOW, then WINDOW still
! 	     has siblings, so WINDOW has not yet replaced its parent.  */
  	  tem = start;
  	  while (! EQ (tem, window))
  	    {
***************
*** 4511,4517 ****
  
  	     The number of children n equals the number of resizable
  	     children of this window + 1 because we know window itself
! 	     is resizable (otherwise we would have signalled an error).  */
  
  	  struct window *w = XWINDOW (window);
  	  Lisp_Object s;
--- 4492,4502 ----
  
  	     The number of children n equals the number of resizable
  	     children of this window + 1 because we know window itself
! 	     is resizable (otherwise we would have signalled an error).
! 
! 	     This reasoning is not correct when other windows become too
! 	     small and shrink_windows refuses to delete them.  Below we
! 	     use resize_proportionally to work around this problem.  */
  
  	  struct window *w = XWINDOW (window);
  	  Lisp_Object s;
***************
*** 4532,4543 ****
  	  (*setsizefun) (window, XINT (*sizep) + delta1, 0);
  
  	  /* Squeeze out delta1 lines or columns from our parent,
! 	     shriking this window and siblings proportionately.
! 	     This brings parent back to correct size.
! 	     Delta1 was calculated so this makes this window the desired size,
! 	     taking it all out of the siblings.  */
  	  (*setsizefun) (parent, opht, 0);
! 
  	}
      }
  
--- 4517,4533 ----
  	  (*setsizefun) (window, XINT (*sizep) + delta1, 0);
  
  	  /* Squeeze out delta1 lines or columns from our parent,
! 	     shrinking this window and siblings proportionately.  This
! 	     brings parent back to correct size.  Delta1 was calculated
! 	     so this makes this window the desired size, taking it all
! 	     out of the siblings.
! 
! 	     Temporarily set resize_proportionally to Qt to assure that,
! 	     if necessary, shrink_windows deletes smaller windows rather
! 	     than shrink this window.  */
! 	  w->resize_proportionally = Qt;
  	  (*setsizefun) (parent, opht, 0);
! 	  w->resize_proportionally = Qnil;
  	}
      }
  
***************
*** 4567,4576 ****
    Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
    int delcount = window_deletion_count;
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    CHECK_WINDOW (window);
  
    /* Give up if this window cannot be resized.  */
--- 4557,4562 ----
***************
*** 4625,4631 ****
  
        /* Don't make this window too small.  */
        if (XINT (CURSIZE (window)) + delta
! 	  < window_min_size_2 (XWINDOW (window), horiz_flag))
  	{
  	  Fset_window_configuration (old_config);
  	  error ("Cannot adjust window size as specified");
--- 4611,4617 ----
  
        /* Don't make this window too small.  */
        if (XINT (CURSIZE (window)) + delta
! 	  < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
  	{
  	  Fset_window_configuration (old_config);
  	  error ("Cannot adjust window size as specified");
***************
*** 4778,4790 ****
        for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
  	last_child = child;
  
!       /* Assign new heights.  We leave only MIN_SAFE_WINDOW_HEIGHT.  */
        for (child = last_child; delta && !NILP (child); child = c->prev)
  	{
  	  int this_one;
  
  	  c = XWINDOW (child);
! 	  this_one = XFASTINT (c->total_lines) - MIN_SAFE_WINDOW_HEIGHT;
  
  	  if (this_one > delta)
  	    this_one = delta;
--- 4764,4776 ----
        for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
  	last_child = child;
  
!       /* Size children down to their safe heights.  */
        for (child = last_child; delta && !NILP (child); child = c->prev)
  	{
  	  int this_one;
  
  	  c = XWINDOW (child);
! 	  this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
  
  	  if (this_one > delta)
  	    this_one = delta;
***************
*** 4887,4902 ****
    xassert (MINI_WINDOW_P (w));
    xassert (delta >= 0);
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    /* Compute how much we can enlarge the mini-window without deleting
       other windows.  */
    root = XWINDOW (FRAME_ROOT_WINDOW (f));
    if (delta)
      {
!       int min_height = window_min_size (root, 0, 0, 0);
        if (XFASTINT (root->total_lines) - delta < min_height)
  	/* Note that the root window may already be smaller than
  	   min_height.  */
--- 4873,4884 ----
    xassert (MINI_WINDOW_P (w));
    xassert (delta >= 0);
  
    /* Compute how much we can enlarge the mini-window without deleting
       other windows.  */
    root = XWINDOW (FRAME_ROOT_WINDOW (f));
    if (delta)
      {
!       int min_height = window_min_size (root, 0, 0, 0, 0);
        if (XFASTINT (root->total_lines) - delta < min_height)
  	/* Note that the root window may already be smaller than
  	   min_height.  */
***************
*** 6164,6170 ****
    Lisp_Object left_margin_cols, right_margin_cols;
    Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
    Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
!   Lisp_Object dedicated;
  };
  
  #define SAVED_WINDOW_N(swv,n) \
--- 6146,6152 ----
    Lisp_Object left_margin_cols, right_margin_cols;
    Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
    Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
!   Lisp_Object dedicated, resize_proportionally;
  };
  
  #define SAVED_WINDOW_N(swv,n) \
***************
*** 6327,6337 ****
  				     * sizeof (struct window *));
        n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
  
-       /* Temporarily avoid any problems with windows that are smaller
- 	 than they are supposed to be.  */
-       window_min_height = 1;
-       window_min_width = 1;
- 
        /* Kludge Alert!
  	 Mark all windows now on frame as "deleted".
  	 Restoring the new configuration "undeletes" any that are in it.
--- 6309,6314 ----
***************
*** 6398,6403 ****
--- 6375,6381 ----
  	  w->scroll_bar_width = p->scroll_bar_width;
  	  w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
  	  w->dedicated = p->dedicated;
+ 	  w->resize_proportionally = p->resize_proportionally;
  	  XSETFASTINT (w->last_modified, 0);
  	  XSETFASTINT (w->last_overlay_modified, 0);
  
***************
*** 6527,6536 ****
    if (!NILP (new_current_buffer))
      Fset_buffer (new_current_buffer);
  
-   /* Restore the minimum heights recorded in the configuration.  */
-   window_min_height = data->min_height;
-   window_min_width = data->min_width;
- 
    Vminibuf_scroll_window = data->minibuf_scroll_window;
    minibuf_selected_window = data->minibuf_selected_window;
  
--- 6505,6510 ----
***************
*** 6666,6671 ****
--- 6640,6646 ----
        p->scroll_bar_width = w->scroll_bar_width;
        p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
        p->dedicated = w->dedicated;
+       p->resize_proportionally = w->resize_proportionally;
        if (!NILP (w->buffer))
  	{
  	  /* Save w's value of point in the window configuration.
***************
*** 6753,6760 ****
    data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
    data->root_window = FRAME_ROOT_WINDOW (f);
    data->focus_frame = FRAME_FOCUS_FRAME (f);
-   data->min_height = window_min_height;
-   data->min_width = window_min_width;
    tem = Fmake_vector (make_number (n_windows), Qnil);
    data->saved_windows = tem;
    for (i = 0; i < n_windows; i++)
--- 6728,6733 ----
***************
*** 7611,7622 ****
    Vsplit_window_preferred_function = Qnil;
  
    DEFVAR_INT ("window-min-height", &window_min_height,
! 	      doc: /* *Delete any window less than this tall (including its mode line).
! The value is in line units. */);
    window_min_height = 4;
  
    DEFVAR_INT ("window-min-width", &window_min_width,
! 	      doc: /* *Delete any window less than this wide (measured in characters).  */);
    window_min_width = 10;
  
    DEFVAR_LISP ("scroll-preserve-screen-position",
--- 7584,7604 ----
    Vsplit_window_preferred_function = Qnil;
  
    DEFVAR_INT ("window-min-height", &window_min_height,
! 	      doc: /* Allow deleting windows less than this tall.
! The value is measured in line units.  If a window wants a modeline it
! is counted as one line.
! 
! Emacs honors settings of this variable when enlarging or shrinking
! windows vertically.  A value less than 1 is invalid.  */);
    window_min_height = 4;
  
    DEFVAR_INT ("window-min-width", &window_min_width,
! 	      doc: /* Allow deleting windows less than this wide.
! The value is measured in characters and includes any fringes or
! the scrollbar.
! 
! Emacs honors settings of this variable when enlarging or shrinking
! windows horizontally.  A value less than 2 is invalid.  */);
    window_min_width = 10;
  
    DEFVAR_LISP ("scroll-preserve-screen-position",



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

* Re: resizing frames and windows
  2008-04-28 14:57 resizing frames and windows martin rudalics
@ 2008-04-29 14:30 ` Chong Yidong
  2008-04-29 14:56   ` martin rudalics
  2008-04-29 16:11 ` Chong Yidong
  1 sibling, 1 reply; 6+ messages in thread
From: Chong Yidong @ 2008-04-29 14:30 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> attached find a patch for dispnew.c, window.h, and window.c which tries
> to fix some problems wrt window resizing.  Please tell me whether it
> applies and whether you can build Emacs with it (I currently cannot do
> that with the most recent development sources).

It applies, but compilation fails:

window.c: In function ‘Fdisplay_buffer’:
window.c:3853: error: too few arguments to function ‘window_min_size_2’
window.c:3868: error: too few arguments to function ‘window_min_size_2’

Are you missing a piece from your patch?




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

* Re: resizing frames and windows
  2008-04-29 14:30 ` Chong Yidong
@ 2008-04-29 14:56   ` martin rudalics
  2008-04-29 15:52     ` Chong Yidong
  0 siblings, 1 reply; 6+ messages in thread
From: martin rudalics @ 2008-04-29 14:56 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

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

Thanks for trying!

 > It applies, but compilation fails:
 >
 > window.c: In function ‘Fdisplay_buffer’:
 > window.c:3853: error: too few arguments to function ‘window_min_size_2’
 > window.c:3868: error: too few arguments to function ‘window_min_size_2’
 >
 > Are you missing a piece from your patch?

Honestly I didn't care about these - my `display-buffer' is in window.el
for quite some time.  Please try again with the versions of window.h and
dispnew.c I sent earlier and the patch for window.c now attached.  Sorry
for the inconvenience.

[-- Attachment #2: window-fixed.patch --]
[-- Type: text/plain, Size: 46131 bytes --]

*** window.c	Wed Apr  2 22:15:44 2008
--- window.c	Tue Apr 29 16:39:42 2008
***************
*** 65,73 ****
  static void window_scroll P_ ((Lisp_Object, int, int, int));
  static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
  static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
! static int window_min_size_1 P_ ((struct window *, int));
! static int window_min_size_2 P_ ((struct window *, int));
! static int window_min_size P_ ((struct window *, int, int, int *));
  static void size_window P_ ((Lisp_Object, int, int, int, int, int));
  static int freeze_window_start P_ ((struct window *, void *));
  static int window_fixed_size_p P_ ((struct window *, int, int));
--- 65,73 ----
  static void window_scroll P_ ((Lisp_Object, int, int, int));
  static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
  static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
! static int window_min_size_1 P_ ((struct window *, int, int));
! static int window_min_size_2 P_ ((struct window *, int, int));
! static int window_min_size P_ ((struct window *, int, int, int, int *));
  static void size_window P_ ((Lisp_Object, int, int, int, int, int));
  static int freeze_window_start P_ ((struct window *, void *));
  static int window_fixed_size_p P_ ((struct window *, int, int));
***************
*** 299,304 ****
--- 299,305 ----
    p->fringes_outside_margins = Qnil;
    p->scroll_bar_width = Qnil;
    p->vertical_scroll_bar_type = Qt;
+   p->resize_proportionally = Qnil;
  
    Vwindow_list = Qnil;
    return val;
***************
*** 2550,2567 ****
  #define MIN_SAFE_WINDOW_WIDTH  (2)
  #define MIN_SAFE_WINDOW_HEIGHT (1)
  
! /* Make sure that window_min_height and window_min_width are
!    not too small; if they are, set them to safe minima.  */
  
! static void
! check_min_window_sizes ()
! {
!   /* Smaller values might permit a crash.  */
!   if (window_min_width < MIN_SAFE_WINDOW_WIDTH)
!     window_min_width = MIN_SAFE_WINDOW_WIDTH;
!   if (window_min_height < MIN_SAFE_WINDOW_HEIGHT)
!     window_min_height = MIN_SAFE_WINDOW_HEIGHT;
! }
  
  /* If *ROWS or *COLS are too small a size for FRAME, set them to the
     minimum allowable size.  */
--- 2551,2561 ----
  #define MIN_SAFE_WINDOW_WIDTH  (2)
  #define MIN_SAFE_WINDOW_HEIGHT (1)
  
! /* For wp non-zero the total number of columns of window w.  Otherwise
!    the total number of lines of w.  */
  
! #define WINDOW_TOTAL_SIZE(w, wp) \
!   (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
  
  /* If *ROWS or *COLS are too small a size for FRAME, set them to the
     minimum allowable size.  */
***************
*** 2608,2614 ****
  
        if (width_p)
  	{
! 	  /* A horiz. combination is fixed-width if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2602,2608 ----
  
        if (width_p)
  	{
! 	  /* A horizontal combination is fixed-width if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2616,2622 ****
  	}
        else
  	{
! 	  /* A horiz. combination is fixed-height if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2610,2616 ----
  	}
        else
  	{
! 	  /* A horizontal combination is fixed-height if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2629,2635 ****
  
        if (width_p)
  	{
! 	  /* A vert. combination is fixed-width if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2623,2629 ----
  
        if (width_p)
  	{
! 	  /* A vertical combination is fixed-width if one of if its
  	     children is.  */
  	  while (c && !window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2637,2643 ****
  	}
        else
  	{
! 	  /* A vert. combination is fixed-height if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
--- 2631,2637 ----
  	}
        else
  	{
! 	  /* A vertical combination is fixed-height if all of if its
  	     children are.  */
  	  while (c && window_fixed_size_p (c, width_p, 0))
  	    c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
***************
*** 2689,2808 ****
    return fixed_p;
  }
  
! /* Return the minimum size for leaf window W.  WIDTH_P non-zero means
!    take into account fringes and the scrollbar of W.  WIDTH_P zero means
!    take into account mode-line of W.  Return 1 for the minibuffer.  */
  
  static int
! window_min_size_2 (w, width_p)
       struct window *w;
!      int width_p;
  {
!   int size;
!   
    if (width_p)
!     size = max (window_min_width,
! 		(MIN_SAFE_WINDOW_WIDTH
  		 + WINDOW_FRINGE_COLS (w)
! 		 + WINDOW_SCROLL_BAR_COLS (w)));
    else if (MINI_WINDOW_P (w))
!     size = 1;
    else
!     size = max (window_min_height,
! 		(MIN_SAFE_WINDOW_HEIGHT
! 		 /* Don't count the header-line here.  It would break
! 		    splitting a window with a header-line when the new
! 		    window shall have a height of two (calculator does
! 		    that). */
! 		 + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
! 
!   return size;
  }
  
! /* Return the minimum size of window W, not taking fixed-width windows
!    into account.  WIDTH_P non-zero means return the minimum width,
!    otherwise return the minimum height.  If W is a combination window,
!    compute the minimum size from the minimum sizes of W's children.  */
  
  static int
! window_min_size_1 (w, width_p)
       struct window *w;
!      int width_p;
  {
    struct window *c;
    int size;
  
    if (!NILP (w->hchild))
      {
        c = XWINDOW (w->hchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The min width of a horizontal combination is
! 	     the sum of the min widths of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, width_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The min height a horizontal combination equals
! 	     the maximum of all min height of its children.  */
  	  while (c)
  	    {
! 	      int min_size = window_min_size_1 (c, width_p);
! 	      size = max (min_size, size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else if (!NILP (w->vchild))
      {
        c = XWINDOW (w->vchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The min width of a vertical combination is
! 	     the maximum of the min widths of its children.  */
  	  while (c)
  	    {
! 	      int min_size = window_min_size_1 (c, width_p);
! 	      size = max (min_size, size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The min height of a vertical combination equals
! 	     the sum of the min height of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, width_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else
!     size = window_min_size_2 (w, width_p);
  
    return size;
  }
  
- 
  /* Return the minimum size of window W, taking fixed-size windows into
!    account.  WIDTH_P non-zero means return the minimum width,
!    otherwise return the minimum height.  IGNORE_FIXED_P non-zero means
!    ignore if W is fixed-size.  Set *FIXED to 1 if W is fixed-size
!    unless FIXED is null.  */
  
  static int
! window_min_size (w, width_p, ignore_fixed_p, fixed)
       struct window *w;
!      int width_p, ignore_fixed_p, *fixed;
  {
    int size, fixed_p;
  
--- 2683,2812 ----
    return fixed_p;
  }
  
! /* Return minimum size of leaf window W.  WIDTH_P non-zero means return
!    the minimum width of W, WIDTH_P zero means return the minimum height
!    of W.  SAFE_P non-zero means ignore window-min-height|width but just
!    return values that won't crash Emacs and don't hide components like
!    fringes, scrollbars, or modelines.  If WIDTH_P is zero and W is the
!    minibuffer window, always return 1.  */
  
  static int
! window_min_size_2 (w, width_p, safe_p)
       struct window *w;
!      int width_p, safe_p;
  {
!   /* We should consider buffer-local values of window_min_height and
!      window_min_width here.  */
    if (width_p)
!     {
!       int safe_size = (MIN_SAFE_WINDOW_WIDTH
  		 + WINDOW_FRINGE_COLS (w)
! 		       + WINDOW_SCROLL_BAR_COLS (w));
! 
!       return safe_p ? safe_size : max (window_min_width, safe_size);
!     }
    else if (MINI_WINDOW_P (w))
!     return 1;
    else
!     {
!       int safe_size = (MIN_SAFE_WINDOW_HEIGHT
! 		       + ((BUFFERP (w->buffer)
! 			   && !NILP (XBUFFER (w->buffer)->mode_line_format))
! 			  ? 1 : 0));
! 
!       return safe_p ? safe_size : max (window_min_height, safe_size);
!     }
  }
  
! /* Return minimum size of window W, not taking fixed-width windows into
!    account.  WIDTH_P non-zero means return the minimum width, otherwise
!    return the minimum height.  SAFE_P non-zero means ignore
!    window-min-height|width but just return values that won't crash Emacs
!    and don't hide components like fringes, scrollbars, or modelines.  If
!    W is a combination window, compute the minimum size from the minimum
!    sizes of W's children.  */
  
  static int
! window_min_size_1 (w, width_p, safe_p)
       struct window *w;
!      int width_p, safe_p;
  {
    struct window *c;
    int size;
  
    if (!NILP (w->hchild))
      {
+       /* W is a horizontal combination.  */
        c = XWINDOW (w->hchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The minimum width of a horizontal combination is the sum of
! 	     the minimum widths of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, 1, safe_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The minimum height of a horizontal combination is the
! 	     maximum of the minimum heights of its children.  */
  	  while (c)
  	    {
! 	      size = max (window_min_size_1 (c, 0, safe_p), size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else if (!NILP (w->vchild))
      {
+       /* W is a vertical combination.  */
        c = XWINDOW (w->vchild);
        size = 0;
  
        if (width_p)
  	{
! 	  /* The minimum width of a vertical combination is the maximum
! 	     of the minimum widths of its children.  */
  	  while (c)
  	    {
! 	      size = max (window_min_size_1 (c, 1, safe_p), size);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
        else
  	{
! 	  /* The minimum height of a vertical combination is the sum of
! 	     the minimum height of its children.  */
  	  while (c)
  	    {
! 	      size += window_min_size_1 (c, 0, safe_p);
  	      c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
  	    }
  	}
      }
    else
!     /* W is a leaf window.  */
!     size = window_min_size_2 (w, width_p, safe_p);
  
    return size;
  }
  
  /* Return the minimum size of window W, taking fixed-size windows into
!    account.  WIDTH_P non-zero means return the minimum width, otherwise
!    return the minimum height.  SAFE_P non-zero means ignore
!    window-min-height|width but just return values that won't crash Emacs
!    and don't hide components like fringes, scrollbars, or modelines.
!    IGNORE_FIXED_P non-zero means ignore if W is fixed-size.  Set *FIXED
!    to 1 if W is fixed-size unless FIXED is null.  */
  
  static int
! window_min_size (w, width_p, safe_p, ignore_fixed_p, fixed)
       struct window *w;
!      int width_p, safe_p, ignore_fixed_p, *fixed;
  {
    int size, fixed_p;
  
***************
*** 2815,2823 ****
      *fixed = fixed_p;
  
    if (fixed_p)
!     size = width_p ? XFASTINT (w->total_cols) : XFASTINT (w->total_lines);
    else
!     size = window_min_size_1 (w, width_p);
  
    return size;
  }
--- 2819,2827 ----
      *fixed = fixed_p;
  
    if (fixed_p)
!     size = WINDOW_TOTAL_SIZE (w, width_p);
    else
!     size = window_min_size_1 (w, width_p, safe_p);
  
    return size;
  }
***************
*** 2859,2893 ****
    return 1;
  }
  
! /* Calculate new sizes for windows in the list FORWARD when the window size
!    goes from TOTAL to SIZE.  TOTAL must be greater than SIZE.
!    The number of windows in FORWARD is NCHILDREN, and the number that
!    can shrink is SHRINKABLE.
!    The minimum size a window can have is MIN_SIZE.
!    If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
!    If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
!    shrinking rows.
  
     This function returns an allocated array of new sizes that the caller
!    must free.  The size -1 means the window is fixed and RESIZE_FIXED_P
!    is zero.  Array index 0 refers to the first window in FORWARD, 1 to
!    the second, and so on.
! 
!    This function tries to keep windows at least at the minimum size
!    and resize other windows before it resizes any window to zero (i.e.
!    delete that window).
! 
!    Windows are resized proportional to their size, so bigger windows
!    shrink more than smaller windows.  */
  static int *
! shrink_windows (total, size, nchildren, shrinkable,
!                 min_size, resize_fixed_p, forward, width_p)
!      int total, size, nchildren, shrinkable, min_size;
!      int resize_fixed_p, width_p;
       Lisp_Object forward;
  {
    int available_resize = 0;
!   int *new_sizes;
    struct window *c;
    Lisp_Object child;
    int smallest = total;
--- 2863,2900 ----
    return 1;
  }
  
! /* Calculate new sizes for windows in the list FORWARD when their
!    compound size goes from TOTAL to SIZE.  TOTAL must be greater than
!    SIZE.  The number of windows in FORWARD is NCHILDREN, and the number
!    that can shrink is SHRINKABLE.  Fixed-size windows may be shrunk if
!    and only if RESIZE_FIXED_P is non-zero.  WIDTH_P non-zero means
!    shrink columns, otherwise shrink lines.
! 
!    SAFE_P zero means windows may be sized down to window-min-height
!    lines (window-min-window columns for WIDTH_P non-zero).  SAFE_P
!    non-zero means windows may be sized down to their minimum safe sizes
!    taking into account the space needed to display modelines, fringes,
!    and scrollbars.
  
     This function returns an allocated array of new sizes that the caller
!    must free.  A size -1 means the window is fixed and RESIZE_FIXED_P is
!    zero.  A size zero means the window shall be deleted.  Array index 0
!    refers to the first window in FORWARD, 1 to the second, and so on.
! 
!    This function resizes windows proportionally to their size.  It also
!    tries to preserve smaller windows by resizing larger windows before
!    resizing any window to zero.  If resize_proportionally is non-nil for
!    a specific window, it will attempt to strictly resize that window
!    proportionally, even at the expense of deleting smaller windows.  */
  static int *
! shrink_windows (total, size, nchildren, shrinkable, resize_fixed_p,
! 		forward, width_p, safe_p)
!      int total, size, nchildren, shrinkable;
!      int resize_fixed_p, width_p, safe_p;
       Lisp_Object forward;
  {
    int available_resize = 0;
!   int *new_sizes, *min_sizes;
    struct window *c;
    Lisp_Object child;
    int smallest = total;
***************
*** 2896,2916 ****
    int i;
  
    new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
  
    for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
      {
        int child_size;
  
        c = XWINDOW (child);
!       child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
  
!       if (! resize_fixed_p && window_fixed_size_p (c, width_p, 0))
          new_sizes[i] = -1;
        else
          {
            new_sizes[i] = child_size;
!           if (child_size > min_size)
!             available_resize += child_size - min_size;
          }
      }
    /* We might need to shrink some windows to zero.  Find the smallest
--- 2903,2926 ----
    int i;
  
    new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
+   min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
  
    for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
      {
        int child_size;
  
        c = XWINDOW (child);
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
  
!       if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
          new_sizes[i] = -1;
        else
          {
            new_sizes[i] = child_size;
!           min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
!           if (child_size > min_sizes[i]
! 	      && NILP (c->resize_proportionally))
!             available_resize += child_size - min_sizes[i];
          }
      }
    /* We might need to shrink some windows to zero.  Find the smallest
***************
*** 2927,2934 ****
            {
              /* Resize this window down to zero.  */
              new_sizes[i] = 0;
!             if (smallest > min_size)
!               available_resize -= smallest - min_size;
              available_resize += smallest;
              --shrinkable;
              total_removed += smallest;
--- 2937,2944 ----
            {
              /* Resize this window down to zero.  */
              new_sizes[i] = 0;
!             if (smallest > min_sizes[i])
!               available_resize -= smallest - min_sizes[i];
              available_resize += smallest;
              --shrinkable;
              total_removed += smallest;
***************
*** 2946,2956 ****
       proportional to its size.  */
    for (i = 0; i < nchildren; ++i)
      {
!       if (new_sizes[i] > min_size)
          {
!           int to_shrink = total_shrink*new_sizes[i]/total;
!           if (new_sizes[i] - to_shrink < min_size)
!             to_shrink = new_sizes[i] - min_size;
            new_sizes[i] -= to_shrink;
            total_removed += to_shrink;
          }
--- 2956,2967 ----
       proportional to its size.  */
    for (i = 0; i < nchildren; ++i)
      {
!       if (new_sizes[i] > min_sizes[i])
          {
!           int to_shrink = total_shrink * new_sizes[i] / total;
! 
!           if (new_sizes[i] - to_shrink < min_sizes[i])
!             to_shrink = new_sizes[i] - min_sizes[i];
            new_sizes[i] -= to_shrink;
            total_removed += to_shrink;
          }
***************
*** 2971,2977 ****
            }
  
        for (i = 0; i < nchildren; ++i)
!         if (new_sizes[i] > min_size)
            {
              --new_sizes[i];
              ++total_removed;
--- 2982,2988 ----
            }
  
        for (i = 0; i < nchildren; ++i)
!         if (new_sizes[i] > min_sizes[i])
            {
              --new_sizes[i];
              ++total_removed;
***************
*** 2981,2987 ****
              break;
            }
  
- 
        /* Special case, only one window left.  */
        if (nonzero_sizes == 1)
          break;
--- 2992,2997 ----
***************
*** 3001,3022 ****
          }
      }
  
    return new_sizes;
  }
  
  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
!    WINDOW's width.  Resize WINDOW's children, if any, so that they
!    keep their proportionate size relative to WINDOW.
  
     If FIRST_ONLY is 1, change only the first of WINDOW's children when
     they are in series.  If LAST_ONLY is 1, change only the last of
     WINDOW's children when they are in series.
  
     Propagate WINDOW's top or left edge position to children.  Delete
!    windows that become too small unless NODELETE_P is non-zero.
! 
!    If NODELETE_P is 2, that means we do delete windows that are
!    too small, even if they were too small before!  */
  
  static void
  size_window (window, size, width_p, nodelete_p, first_only, last_only)
--- 3011,3034 ----
          }
      }
  
+   xfree (min_sizes);
+ 
    return new_sizes;
  }
  
  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
!    WINDOW's width.  Resize WINDOW's children, if any, so that they keep
!    their proportionate size relative to WINDOW.
  
     If FIRST_ONLY is 1, change only the first of WINDOW's children when
     they are in series.  If LAST_ONLY is 1, change only the last of
     WINDOW's children when they are in series.
  
     Propagate WINDOW's top or left edge position to children.  Delete
!    windows that become too small unless NODELETE_P is 1.  When
!    NODELETE_P equals 2 do not honor settings for window-min-height and
!    window-min-width when resizing windows but use safe defaults instead.
!    This should give better behavior when resizing frames.  */
  
  static void
  size_window (window, size, width_p, nodelete_p, first_only, last_only)
***************
*** 3027,3073 ****
    struct window *w = XWINDOW (window);
    struct window *c;
    Lisp_Object child, *forward, *sideward;
!   int old_size, min_size, safe_min_size;
  
-   check_min_window_sizes ();
    size = max (0, size);
  
!   /* If the window has been "too small" at one point,
!      don't delete it for being "too small" in the future.
!      Preserve it as long as that is at all possible.  */
!   if (width_p)
!     {
!       old_size = WINDOW_TOTAL_COLS (w);
!       min_size = window_min_width;
!       safe_min_size = window_min_size_2 (w, 1);
!     }
!   else
!     {
!       old_size = XINT (w->total_lines);
!       min_size = window_min_height;
!       safe_min_size = window_min_size_2 (w, 0);
!     }
! 
!   if (old_size < min_size && nodelete_p != 2)
!     w->too_small_ok = Qt;
! 
!   /* Move the following test here since otherwise the
!      preceding test doesn't make sense.  martin. */
!   if (nodelete_p == 2)
!     nodelete_p = 0;
! 
!   /* Maybe delete WINDOW if it's too small.  */
!   if (nodelete_p != 1 && !NILP (w->parent))
      {
!       if (!MINI_WINDOW_P (w) && !NILP (w->too_small_ok))
! 	min_size = width_p ? MIN_SAFE_WINDOW_WIDTH : MIN_SAFE_WINDOW_HEIGHT;
!       if (min_size < safe_min_size)
! 	min_size = safe_min_size;
!       if (size < min_size)
! 	{
! 	  delete_window (window);
! 	  return;
! 	}
      }
  
    /* Set redisplay hints.  */
--- 3039,3054 ----
    struct window *w = XWINDOW (window);
    struct window *c;
    Lisp_Object child, *forward, *sideward;
!   int old_size = WINDOW_TOTAL_SIZE (w, width_p);
  
    size = max (0, size);
  
!   /* Delete WINDOW if it's too small.  */
!   if (nodelete_p != 1 && !NILP (w->parent)
!       && size < window_min_size_1 (w, width_p, nodelete_p == 2))
      {
!       delete_window (window);
!       return;
      }
  
    /* Set redisplay hints.  */
***************
*** 3117,3125 ****
  	  last_child = child;
  	}
  
!       child_size = XINT (width_p ? c->total_cols : c->total_lines);
!       size_window (last_child,
! 		   size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward) && first_only)
--- 3098,3105 ----
  	  last_child = child;
  	}
  
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
!       size_window (last_child, size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward) && first_only)
***************
*** 3135,3143 ****
        else
  	c->top_line = w->top_line;
  
!       child_size = XINT (width_p ? c->total_cols : c->total_lines);
!       size_window (child,
! 		   size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward))
--- 3115,3122 ----
        else
  	c->top_line = w->top_line;
  
!       child_size = WINDOW_TOTAL_SIZE (c, width_p);
!       size_window (child, size - old_size + child_size,
  		   width_p, nodelete_p, first_only, last_only);
      }
    else if (!NILP (*forward))
***************
*** 3155,3161 ****
  	  int child_size;
  
  	  c = XWINDOW (child);
! 	  child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
  	  total += child_size;
  
  	  if (window_fixed_size_p (c, width_p, 0))
--- 3134,3140 ----
  	  int child_size;
  
  	  c = XWINDOW (child);
! 	  child_size = WINDOW_TOTAL_SIZE (c, width_p);
  	  total += child_size;
  
  	  if (window_fixed_size_p (c, width_p, 0))
***************
*** 3174,3181 ****
  	 value of extra takes care of rounding errors.  */
        n = resize_fixed_p ? nchildren : nchildren - nfixed;
        if (size < total && n > 1)
!         new_sizes = shrink_windows (total, size, nchildren, n, min_size,
!                                     resize_fixed_p, *forward, width_p);
        else
          {
            each = (size - total) / n;
--- 3153,3161 ----
  	 value of extra takes care of rounding errors.  */
        n = resize_fixed_p ? nchildren : nchildren - nfixed;
        if (size < total && n > 1)
!         new_sizes = shrink_windows (total, size, nchildren, n,
!                                     resize_fixed_p, *forward, width_p,
! 				    nodelete_p == 2);
        else
          {
            each = (size - total) / n;
***************
*** 3190,3196 ****
  	  int new_size, old_size;
  
  	  c = XWINDOW (child);
! 	  old_size = width_p ? XFASTINT (c->total_cols) : XFASTINT (c->total_lines);
  	  new_size = old_size;
  
  	  /* The top or left edge position of this child equals the
--- 3170,3176 ----
  	  int new_size, old_size;
  
  	  c = XWINDOW (child);
! 	  old_size = WINDOW_TOTAL_SIZE (c, width_p);
  	  new_size = old_size;
  
  	  /* The top or left edge position of this child equals the
***************
*** 3207,3213 ****
  	      extra = 0;
  	    }
  
! 	  /* Set new height.  Note that size_window also propagates
  	     edge positions to children, so it's not a no-op if we
  	     didn't change the child's size.  */
  	  size_window (child, new_size, width_p, 1, first_only, last_only);
--- 3187,3193 ----
  	      extra = 0;
  	    }
  
! 	  /* Set new size.  Note that size_window also propagates
  	     edge positions to children, so it's not a no-op if we
  	     didn't change the child's size.  */
  	  size_window (child, new_size, width_p, 1, first_only, last_only);
***************
*** 3223,3243 ****
        xassert (size == last_pos - first_pos);
  
        /* Now delete any children that became too small.  */
!       if (!nodelete_p)
  	for (child = *forward; !NILP (child); child = c->next)
  	  {
  	    int child_size;
  	    c = XWINDOW (child);
! 	    child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
! 	    size_window (child, child_size, width_p, 2, first_only, last_only);
  	  }
      }
  }
  
  /* Set WINDOW's height to HEIGHT, and recursively change the height of
!    WINDOW's children.  NODELETE non-zero means don't delete windows
!    that become too small in the process.  (The caller should check
!    later and do so if appropriate.)  */
  
  void
  set_window_height (window, height, nodelete)
--- 3203,3228 ----
        xassert (size == last_pos - first_pos);
  
        /* Now delete any children that became too small.  */
!       if (nodelete_p != 1)
  	for (child = *forward; !NILP (child); child = c->next)
  	  {
  	    int child_size;
+ 
  	    c = XWINDOW (child);
! 	    child_size = WINDOW_TOTAL_SIZE (c, width_p);
! 	    size_window (child, child_size, width_p, nodelete_p,
! 			 first_only, last_only);
  	  }
      }
  }
  
  /* Set WINDOW's height to HEIGHT, and recursively change the height of
!    WINDOW's children.  NODELETE zero means windows that have become
!    smaller than window-min-height in the process may be deleted.
!    NODELETE 1 means never delete windows that become too small in the
!    process.  (The caller should check later and do so if appropriate.)
!    NODELETE 2 means delete only windows that have become too small to be
!    displayed correctly.  */
  
  void
  set_window_height (window, height, nodelete)
***************
*** 3248,3258 ****
    size_window (window, height, 0, nodelete, 0, 0);
  }
  
- 
  /* Set WINDOW's width to WIDTH, and recursively change the width of
!    WINDOW's children.  NODELETE non-zero means don't delete windows
!    that become too small in the process.  (The caller should check
!    later and do so if appropriate.)  */
  
  void
  set_window_width (window, width, nodelete)
--- 3233,3245 ----
    size_window (window, height, 0, nodelete, 0, 0);
  }
  
  /* Set WINDOW's width to WIDTH, and recursively change the width of
!    WINDOW's children.  NODELETE zero means windows that have become
!    smaller than window-min-width in the process may be deleted.
!    NODELETE 1 means never delete windows that become too small in the
!    process.  (The caller should check later and do so if appropriate.)
!    NODELETE 2 means delete only windows that have become too small to be
!    displayed correctly.  */
  
  void
  set_window_width (window, width, nodelete)
***************
*** 3359,3365 ****
      }
        }
    }
!   
    run_funs (global_wcch);
    unbind_to (count, Qnil);
  }
--- 3346,3352 ----
      }
        }
    }
! 
    run_funs (global_wcch);
    unbind_to (count, Qnil);
  }
***************
*** 3863,3869 ****
  	    && (window_height (window) >= split_height_threshold
  		|| (NILP (XWINDOW (window)->parent)))
  	    && (window_height (window)
! 		>= (2 * window_min_size_2 (XWINDOW (window), 0))))
  	  window = Fsplit_window (window, Qnil, Qnil);
        else
  	{
--- 3850,3856 ----
  	    && (window_height (window) >= split_height_threshold
  		|| (NILP (XWINDOW (window)->parent)))
  	    && (window_height (window)
! 		>= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
  	  window = Fsplit_window (window, Qnil, Qnil);
        else
  	{
***************
*** 3878,3884 ****
  		   && window_height (window) >= split_height_threshold)
  		  || (NILP (XWINDOW (window)->parent)))
  	      && (window_height (window)
! 		  >= (2 * window_min_size_2 (XWINDOW (window), 0))))
  	    window = Fsplit_window (window, Qnil, Qnil);
  	  else
  	    window = Fget_lru_window (frames, Qnil);
--- 3865,3871 ----
  		   && window_height (window) >= split_height_threshold)
  		  || (NILP (XWINDOW (window)->parent)))
  	      && (window_height (window)
! 		  >= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
  	    window = Fsplit_window (window, Qnil, Qnil);
  	  else
  	    window = Fget_lru_window (frames, Qnil);
***************
*** 4124,4135 ****
    else if (window_fixed_size_p (o, !NILP (horflag), 0))
      error ("Attempt to split fixed-size window");
  
-   check_min_window_sizes ();
- 
    if (NILP (horflag))
      {
!       int window_safe_height = window_min_size_2 (o, 0);
!       
        if (size_int < window_safe_height)
  	error ("Window height %d too small (after splitting)", size_int);
        if (size_int + window_safe_height > XFASTINT (o->total_lines))
--- 4111,4120 ----
    else if (window_fixed_size_p (o, !NILP (horflag), 0))
      error ("Attempt to split fixed-size window");
  
    if (NILP (horflag))
      {
!       int window_safe_height = window_min_size_2 (o, 0, 0);
! 
        if (size_int < window_safe_height)
  	error ("Window height %d too small (after splitting)", size_int);
        if (size_int + window_safe_height > XFASTINT (o->total_lines))
***************
*** 4145,4152 ****
      }
    else
      {
!       int window_safe_width = window_min_size_2 (o, 1);
!       
        if (size_int < window_safe_width)
  	error ("Window width %d too small (after splitting)", size_int);
        if (size_int + window_safe_width > XFASTINT (o->total_cols))
--- 4130,4137 ----
      }
    else
      {
!       int window_safe_width = window_min_size_2 (o, 1, 0);
! 
        if (size_int < window_safe_width)
  	error ("Window width %d too small (after splitting)", size_int);
        if (size_int + window_safe_width > XFASTINT (o->total_cols))
***************
*** 4277,4288 ****
    *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
  
  
! /* Enlarge WINDOW by DELTA.
!    HORIZ_FLAG nonzero means enlarge it horizontally;
!    zero means do it vertically.
  
     Siblings of the selected window are resized to fulfill the size
!    request.  If they become too small in the process, they will be
     deleted.  */
  
  static void
--- 4262,4272 ----
    *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
  
  
! /* Enlarge WINDOW by DELTA.  HORIZ_FLAG nonzero means enlarge it
!    horizontally; zero means do it vertically.
  
     Siblings of the selected window are resized to fulfill the size
!    request.  If they become too small in the process, they may be
     deleted.  */
  
  static void
***************
*** 4299,4308 ****
    void (*setsizefun) P_ ((Lisp_Object, int, int))
      = (horiz_flag ? set_window_width : set_window_height);
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    /* Give up if this window cannot be resized.  */
    if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
      error ("Window is not resizable");
--- 4283,4288 ----
***************
*** 4339,4349 ****
  		/* This is a main window followed by a minibuffer.  */
  		: !NILP (p->next) ? ((*sizefun) (p->next)
  				     - window_min_size (XWINDOW (p->next),
! 							horiz_flag, 0, 0))
  		/* This is a minibuffer following a main window.  */
  		: !NILP (p->prev) ? ((*sizefun) (p->prev)
  				     - window_min_size (XWINDOW (p->prev),
! 							horiz_flag, 0, 0))
  		/* This is a frame with only one window, a minibuffer-only
  		   or a minibufferless frame.  */
  		: (delta = 0));
--- 4319,4329 ----
  		/* This is a main window followed by a minibuffer.  */
  		: !NILP (p->next) ? ((*sizefun) (p->next)
  				     - window_min_size (XWINDOW (p->next),
! 							horiz_flag, 0, 0, 0))
  		/* This is a minibuffer following a main window.  */
  		: !NILP (p->prev) ? ((*sizefun) (p->prev)
  				     - window_min_size (XWINDOW (p->prev),
! 							horiz_flag, 0, 0, 0))
  		/* This is a frame with only one window, a minibuffer-only
  		   or a minibufferless frame.  */
  		: (delta = 0));
***************
*** 4355,4361 ****
        delta = maxdelta;
    }
  
!   if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0))
      {
        delete_window (window);
        return;
--- 4335,4342 ----
        delta = maxdelta;
    }
  
!   if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
! 					       horiz_flag, 0, 0, 0))
      {
        delete_window (window);
        return;
***************
*** 4368,4377 ****
    maximum = 0;
    for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
      maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
! 						    horiz_flag, 0, 0);
    for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
      maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
! 						    horiz_flag, 0, 0);
  
    /* If we can get it all from them without deleting them, do so.  */
    if (delta <= maximum)
--- 4349,4358 ----
    maximum = 0;
    for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
      maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
! 						    horiz_flag, 0, 0, 0);
    for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
      maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
! 						    horiz_flag, 0, 0, 0);
  
    /* If we can get it all from them without deleting them, do so.  */
    if (delta <= maximum)
***************
*** 4392,4399 ****
  	  if (! NILP (next))
  	    {
  	      int this_one = ((*sizefun) (next)
! 			      - window_min_size (XWINDOW (next),
! 						 horiz_flag, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
--- 4373,4380 ----
  	  if (! NILP (next))
  	    {
  	      int this_one = ((*sizefun) (next)
! 			      - window_min_size (XWINDOW (next), horiz_flag,
! 						 0, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
***************
*** 4414,4421 ****
  	  if (! NILP (prev))
  	    {
  	      int this_one = ((*sizefun) (prev)
! 			      - window_min_size (XWINDOW (prev),
! 						 horiz_flag, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
--- 4395,4402 ----
  	  if (! NILP (prev))
  	    {
  	      int this_one = ((*sizefun) (prev)
! 			      - window_min_size (XWINDOW (prev), horiz_flag,
! 						 0, 0, &fixed_p));
  	      if (!fixed_p)
  		{
  		  if (this_one > delta)
***************
*** 4474,4480 ****
  
  	  /* Delete any siblings that come after WINDOW.
  	     Note that if START is not WINDOW, then WINDOW still
! 	     Fhas siblings, so WINDOW has not yet replaced its parent.  */
  	  tem = start;
  	  while (! EQ (tem, window))
  	    {
--- 4455,4461 ----
  
  	  /* Delete any siblings that come after WINDOW.
  	     Note that if START is not WINDOW, then WINDOW still
! 	     has siblings, so WINDOW has not yet replaced its parent.  */
  	  tem = start;
  	  while (! EQ (tem, window))
  	    {
***************
*** 4511,4517 ****
  
  	     The number of children n equals the number of resizable
  	     children of this window + 1 because we know window itself
! 	     is resizable (otherwise we would have signalled an error).  */
  
  	  struct window *w = XWINDOW (window);
  	  Lisp_Object s;
--- 4492,4502 ----
  
  	     The number of children n equals the number of resizable
  	     children of this window + 1 because we know window itself
! 	     is resizable (otherwise we would have signalled an error).
! 
! 	     This reasoning is not correct when other windows become too
! 	     small and shrink_windows refuses to delete them.  Below we
! 	     use resize_proportionally to work around this problem.  */
  
  	  struct window *w = XWINDOW (window);
  	  Lisp_Object s;
***************
*** 4532,4543 ****
  	  (*setsizefun) (window, XINT (*sizep) + delta1, 0);
  
  	  /* Squeeze out delta1 lines or columns from our parent,
! 	     shriking this window and siblings proportionately.
! 	     This brings parent back to correct size.
! 	     Delta1 was calculated so this makes this window the desired size,
! 	     taking it all out of the siblings.  */
  	  (*setsizefun) (parent, opht, 0);
! 
  	}
      }
  
--- 4517,4533 ----
  	  (*setsizefun) (window, XINT (*sizep) + delta1, 0);
  
  	  /* Squeeze out delta1 lines or columns from our parent,
! 	     shrinking this window and siblings proportionately.  This
! 	     brings parent back to correct size.  Delta1 was calculated
! 	     so this makes this window the desired size, taking it all
! 	     out of the siblings.
! 
! 	     Temporarily set resize_proportionally to Qt to assure that,
! 	     if necessary, shrink_windows deletes smaller windows rather
! 	     than shrink this window.  */
! 	  w->resize_proportionally = Qt;
  	  (*setsizefun) (parent, opht, 0);
! 	  w->resize_proportionally = Qnil;
  	}
      }
  
***************
*** 4567,4576 ****
    Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
    int delcount = window_deletion_count;
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    CHECK_WINDOW (window);
  
    /* Give up if this window cannot be resized.  */
--- 4557,4562 ----
***************
*** 4625,4631 ****
  
        /* Don't make this window too small.  */
        if (XINT (CURSIZE (window)) + delta
! 	  < window_min_size_2 (XWINDOW (window), horiz_flag))
  	{
  	  Fset_window_configuration (old_config);
  	  error ("Cannot adjust window size as specified");
--- 4611,4617 ----
  
        /* Don't make this window too small.  */
        if (XINT (CURSIZE (window)) + delta
! 	  < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
  	{
  	  Fset_window_configuration (old_config);
  	  error ("Cannot adjust window size as specified");
***************
*** 4778,4790 ****
        for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
  	last_child = child;
  
!       /* Assign new heights.  We leave only MIN_SAFE_WINDOW_HEIGHT.  */
        for (child = last_child; delta && !NILP (child); child = c->prev)
  	{
  	  int this_one;
  
  	  c = XWINDOW (child);
! 	  this_one = XFASTINT (c->total_lines) - MIN_SAFE_WINDOW_HEIGHT;
  
  	  if (this_one > delta)
  	    this_one = delta;
--- 4764,4776 ----
        for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
  	last_child = child;
  
!       /* Size children down to their safe heights.  */
        for (child = last_child; delta && !NILP (child); child = c->prev)
  	{
  	  int this_one;
  
  	  c = XWINDOW (child);
! 	  this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
  
  	  if (this_one > delta)
  	    this_one = delta;
***************
*** 4887,4902 ****
    xassert (MINI_WINDOW_P (w));
    xassert (delta >= 0);
  
-   /* Check values of window_min_width and window_min_height for
-      validity.  */
-   check_min_window_sizes ();
- 
    /* Compute how much we can enlarge the mini-window without deleting
       other windows.  */
    root = XWINDOW (FRAME_ROOT_WINDOW (f));
    if (delta)
      {
!       int min_height = window_min_size (root, 0, 0, 0);
        if (XFASTINT (root->total_lines) - delta < min_height)
  	/* Note that the root window may already be smaller than
  	   min_height.  */
--- 4873,4884 ----
    xassert (MINI_WINDOW_P (w));
    xassert (delta >= 0);
  
    /* Compute how much we can enlarge the mini-window without deleting
       other windows.  */
    root = XWINDOW (FRAME_ROOT_WINDOW (f));
    if (delta)
      {
!       int min_height = window_min_size (root, 0, 0, 0, 0);
        if (XFASTINT (root->total_lines) - delta < min_height)
  	/* Note that the root window may already be smaller than
  	   min_height.  */
***************
*** 6164,6170 ****
    Lisp_Object left_margin_cols, right_margin_cols;
    Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
    Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
!   Lisp_Object dedicated;
  };
  
  #define SAVED_WINDOW_N(swv,n) \
--- 6146,6152 ----
    Lisp_Object left_margin_cols, right_margin_cols;
    Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
    Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
!   Lisp_Object dedicated, resize_proportionally;
  };
  
  #define SAVED_WINDOW_N(swv,n) \
***************
*** 6327,6337 ****
  				     * sizeof (struct window *));
        n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
  
-       /* Temporarily avoid any problems with windows that are smaller
- 	 than they are supposed to be.  */
-       window_min_height = 1;
-       window_min_width = 1;
- 
        /* Kludge Alert!
  	 Mark all windows now on frame as "deleted".
  	 Restoring the new configuration "undeletes" any that are in it.
--- 6309,6314 ----
***************
*** 6398,6403 ****
--- 6375,6381 ----
  	  w->scroll_bar_width = p->scroll_bar_width;
  	  w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
  	  w->dedicated = p->dedicated;
+ 	  w->resize_proportionally = p->resize_proportionally;
  	  XSETFASTINT (w->last_modified, 0);
  	  XSETFASTINT (w->last_overlay_modified, 0);
  
***************
*** 6527,6536 ****
    if (!NILP (new_current_buffer))
      Fset_buffer (new_current_buffer);
  
-   /* Restore the minimum heights recorded in the configuration.  */
-   window_min_height = data->min_height;
-   window_min_width = data->min_width;
- 
    Vminibuf_scroll_window = data->minibuf_scroll_window;
    minibuf_selected_window = data->minibuf_selected_window;
  
--- 6505,6510 ----
***************
*** 6666,6671 ****
--- 6640,6646 ----
        p->scroll_bar_width = w->scroll_bar_width;
        p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
        p->dedicated = w->dedicated;
+       p->resize_proportionally = w->resize_proportionally;
        if (!NILP (w->buffer))
  	{
  	  /* Save w's value of point in the window configuration.
***************
*** 6753,6760 ****
    data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
    data->root_window = FRAME_ROOT_WINDOW (f);
    data->focus_frame = FRAME_FOCUS_FRAME (f);
-   data->min_height = window_min_height;
-   data->min_width = window_min_width;
    tem = Fmake_vector (make_number (n_windows), Qnil);
    data->saved_windows = tem;
    for (i = 0; i < n_windows; i++)
--- 6728,6733 ----
***************
*** 7611,7622 ****
    Vsplit_window_preferred_function = Qnil;
  
    DEFVAR_INT ("window-min-height", &window_min_height,
! 	      doc: /* *Delete any window less than this tall (including its mode line).
! The value is in line units. */);
    window_min_height = 4;
  
    DEFVAR_INT ("window-min-width", &window_min_width,
! 	      doc: /* *Delete any window less than this wide (measured in characters).  */);
    window_min_width = 10;
  
    DEFVAR_LISP ("scroll-preserve-screen-position",
--- 7584,7604 ----
    Vsplit_window_preferred_function = Qnil;
  
    DEFVAR_INT ("window-min-height", &window_min_height,
! 	      doc: /* Allow deleting windows less than this tall.
! The value is measured in line units.  If a window wants a modeline it
! is counted as one line.
! 
! Emacs honors settings of this variable when enlarging or shrinking
! windows vertically.  A value less than 1 is invalid.  */);
    window_min_height = 4;
  
    DEFVAR_INT ("window-min-width", &window_min_width,
! 	      doc: /* Allow deleting windows less than this wide.
! The value is measured in characters and includes any fringes or
! the scrollbar.
! 
! Emacs honors settings of this variable when enlarging or shrinking
! windows horizontally.  A value less than 2 is invalid.  */);
    window_min_width = 10;
  
    DEFVAR_LISP ("scroll-preserve-screen-position",

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

* Re: resizing frames and windows
  2008-04-29 14:56   ` martin rudalics
@ 2008-04-29 15:52     ` Chong Yidong
  2008-04-29 16:10       ` martin rudalics
  0 siblings, 1 reply; 6+ messages in thread
From: Chong Yidong @ 2008-04-29 15:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> Honestly I didn't care about these - my `display-buffer' is in window.el
> for quite some time.  Please try again with the versions of window.h and
> dispnew.c I sent earlier and the patch for window.c now attached.

Thanks.  I also used the patch for window.h you sent earlier, which is
necessary for building.  With that, the compilation finishes with no
errors.  I'm running with the patched Emacs now, and I don't see any
bugs so far.  Let me know if you want to test anything specific.




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

* Re: resizing frames and windows
  2008-04-29 15:52     ` Chong Yidong
@ 2008-04-29 16:10       ` martin rudalics
  0 siblings, 0 replies; 6+ messages in thread
From: martin rudalics @ 2008-04-29 16:10 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

 > Thanks.  I also used the patch for window.h you sent earlier, which is
 > necessary for building.

To test frame resizing you'll also need to patch dispnew.c with the
patch I sent earlier.

 > With that, the compilation finishes with no
 > errors.  I'm running with the patched Emacs now, and I don't see any
 > bugs so far.

Please keep on running.

 > Let me know if you want to test anything specific.

You could try to look at the list from my first posting - in particular
the problem to demaximize a frame with small windows in it.

Thanks again for testing.





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

* Re: resizing frames and windows
  2008-04-28 14:57 resizing frames and windows martin rudalics
  2008-04-29 14:30 ` Chong Yidong
@ 2008-04-29 16:11 ` Chong Yidong
  1 sibling, 0 replies; 6+ messages in thread
From: Chong Yidong @ 2008-04-29 16:11 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

I forgot that you asked to do the following tasks, so here they are.
With the patched Emacs:

> (1) Maximize a frame, create some minimal windows (one-line,
>     two-columns) in it, and demaximize the frame.  Are all windows
>     preserved?

Yes.  The one-line window in particular still exists.

> (2) Same as (1) but try to create a no-way-out configuration where
>     demaximizing the frame cannot avoid deleting some window(s) - for
>     example, because you have two side-by-side windows and the
>     demaximized frame can accomodate at most one such window.  Does
>     resizing behave reasonably?

While maximized, I split the window vertically until the frame consists
entirely of two-line windows.  Upon unmaximizing, the windows that can't
fit are deleted.  Seems OK.

> (3) Save the window-configurations of (1) and (2) in a maximized frame,
>     demaximize the frame, change the layout arbitrarily, and set the
>     window configuration to the saved one.  Does the resulting
>     configuration appear reasonable?

This seems to work fine.

> (4) Split some window vertically, and repeatedly apply
>     `my-enlarge-window'.  Is the other window deleted when its height
>     drops below `window-min-height'?  Does it for other (possibly
>     invalid) values of `window-min-height'?

The other window is deleted, for several valid values of
window-min-height I tested.  A window-min-height of -1 seems the same as
1, which is OK.

> (5) Split some window horizontally, and repeatedly apply
>     `my-enlarge-window-horizontally'.  Is the other window deleted when
>     its width drops below `window-min-width'?  Does it for other
>     (possibly invalid) values of `window-min-width'?

Same as above.

> (6) Create a one-line window at the bottom of the frame and try to
>     resize the minibuffer.  Is the one-line window's modeline retained?

Yes.  Works fine.

> (7) After all these tests: Does customizing `window-min-height' and
>     `window-min-width' work as expected?

No problems here.

Thanks for working on this.




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

end of thread, other threads:[~2008-04-29 16:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-28 14:57 resizing frames and windows martin rudalics
2008-04-29 14:30 ` Chong Yidong
2008-04-29 14:56   ` martin rudalics
2008-04-29 15:52     ` Chong Yidong
2008-04-29 16:10       ` martin rudalics
2008-04-29 16:11 ` Chong Yidong

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.