*** empty log message ***
[bpt/emacs.git] / src / window.c
index 3569408..2340ec6 100644 (file)
@@ -1214,34 +1214,49 @@ delete_window (window)
 
   /* Are we trying to delete any frame's selected window?  */
   {
-    Lisp_Object pwindow;
+    Lisp_Object swindow, pwindow;
 
     /* See if the frame's selected window is either WINDOW
        or any subwindow of it, by finding all that window's parents
        and comparing each one with WINDOW.  */
-    pwindow = FRAME_SELECTED_WINDOW (f);
+    swindow = FRAME_SELECTED_WINDOW (f);
 
-    while (!NILP (pwindow))
+    while (1)
       {
-       if (EQ (window, pwindow))
+       pwindow = swindow;
+       while (!NILP (pwindow))
+         {
+           if (EQ (window, pwindow))
+             break;
+           pwindow = XWINDOW (pwindow)->parent;
+         }
+
+       /* If the window being deleted is not a parent of SWINDOW,
+          then SWINDOW is ok as the new selected window.  */
+       if (!EQ (window, pwindow))
          break;
-       pwindow = XWINDOW (pwindow)->parent;
+       /* Otherwise, try another window for SWINDOW.  */
+       swindow = Fnext_window (swindow, Qlambda, Qnil);;
+
+       /* If we get back to the frame's selected window,
+          it means there was no acceptable alternative,
+          so we cannot delete.  */
+       if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
+         error ("Cannot delete window");
       }
 
-    if (EQ (window, pwindow))
+    /* If we need to change SWINDOW, do it.  */
+    if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
       {
-       Lisp_Object alternative;
-       alternative = Fnext_window (window, Qlambda, Qnil);
-
        /* If we're about to delete the selected window on the
           selected frame, then we should use Fselect_window to select
           the new window.  On the other hand, if we're about to
           delete the selected window on any other frame, we shouldn't do
           anything but set the frame's selected_window slot.  */
-       if (EQ (window, selected_window))
-         Fselect_window (alternative);
+       if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
+         Fselect_window (swindow);
        else
-         FRAME_SELECTED_WINDOW (f) = alternative;
+         FRAME_SELECTED_WINDOW (f) = swindow;
       }
   }
 
@@ -2103,7 +2118,7 @@ replace_buffer_in_all_windows (buffer)
    might crash Emacs.  */
 
 #define MIN_SAFE_WINDOW_WIDTH  (2)
-#define MIN_SAFE_WINDOW_HEIGHT (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.  */
@@ -2127,13 +2142,12 @@ check_frame_size (frame, rows, cols)
      int *rows, *cols;
 {
   /* For height, we have to see:
-     whether the frame has a minibuffer,
-     whether it wants a mode line, and
-     whether it has a menu bar.  */
-  int min_height =
-    (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
-     : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
-     : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
+     how many windows the frame has at minimum (one or two),
+     and whether it has a menu bar or other special stuff at the top.  */
+  int min_height
+    = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
+       ? MIN_SAFE_WINDOW_HEIGHT
+       : 2 * MIN_SAFE_WINDOW_HEIGHT);
   
   if (FRAME_TOP_MARGIN (frame) > 0)
     min_height += FRAME_TOP_MARGIN (frame);
@@ -2372,7 +2386,10 @@ window_min_size (w, width_p, ignore_fixed_p, fixed)
    WINDOW's width.  Resize WINDOW's children, if any, so that they
    keep their proportionate size relative to WINDOW.  Propagate
    WINDOW's top or left edge position to children.  Delete windows
-   that become too small unless NODELETE_P is non-zero.  */
+   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)
@@ -2384,6 +2401,9 @@ size_window (window, size, width_p, nodelete_p)
   Lisp_Object child, *forward, *sideward;
   int old_size, min_size;
 
+  if (nodelete_p == 2)
+    nodelete_p = 0;
+
   check_min_window_sizes ();
   size = max (0, size);
   
@@ -2400,12 +2420,12 @@ size_window (window, size, width_p, nodelete_p)
       old_size = XINT (w->height);
       min_size = window_min_height;
     }
-  
-  if (old_size < min_size)
+
+  if (old_size < min_size && nodelete_p != 2)
     w->too_small_ok = Qt;
 
   /* Maybe delete WINDOW if it's too small.  */
-  if (!nodelete_p && !NILP (w->parent))
+  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;
@@ -2531,7 +2551,7 @@ size_window (window, size, width_p, nodelete_p)
            int child_size;
            c = XWINDOW (child);
            child_size = width_p ? XINT (c->width) : XINT (c->height);
-           size_window (child, child_size, width_p, 0);
+           size_window (child, child_size, width_p, 2);
          }
     }
 }
@@ -3394,7 +3414,7 @@ enlarge_window (window, delta, widthflag, preserve_before)
          {
            maxdelta = (*sizefun) (parent) - XINT (*sizep);
            /* Subtract size of siblings before, since we can't take that.  */
-           maxdelta -= CURBEG (window) - CURBEG (parent);
+           maxdelta -= XINT (CURBEG (window)) - XINT (CURBEG (parent));
          }
        else
          maxdelta = (!NILP (p->next) ? ((*sizefun) (p->next)
@@ -3522,11 +3542,36 @@ enlarge_window (window, delta, widthflag, preserve_before)
       register int delta1;
       register int opht = (*sizefun) (parent);
 
-      /* If trying to grow this window to or beyond size of the parent,
-        make delta1 so big that, on shrinking back down,
-        all the siblings end up with less than one line and are deleted.  */
       if (opht <= XINT (*sizep) + delta)
-       delta1 = opht * opht * 2;
+       {
+         /* If trying to grow this window to or beyond size of the parent,
+            just delete all the sibling windows.  */
+         Lisp_Object start, tem, next;
+
+         start = XWINDOW (parent)->vchild;
+         if (NILP (start))
+           start = XWINDOW (parent)->hchild;
+
+         /* Delete any siblings that come after WINDOW.  */
+         tem = XWINDOW (window)->next;
+         while (! NILP (tem))
+           {
+             next = XWINDOW (tem)->next;
+             delete_window (tem);
+             tem = next;
+           }
+
+         /* 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))
+           {
+             next = XWINDOW (tem)->next;
+             delete_window (tem);
+             tem = next;
+           }
+       }
       else
        {
          /* Otherwise, make delta1 just right so that if we add
@@ -3569,19 +3614,20 @@ enlarge_window (window, delta, widthflag, preserve_before)
              ++n;
 
          delta1 = n * delta;
-       }
 
-      /* Add delta1 lines or columns to this window, and to the parent,
-        keeping things consistent while not affecting siblings.  */
-      XSETINT (CURSIZE (parent), opht + delta1);
-      (*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);
+         /* Add delta1 lines or columns to this window, and to the parent,
+            keeping things consistent while not affecting siblings.  */
+         XSETINT (CURSIZE (parent), opht + delta1);
+         (*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);
+
+       }
     }
 
   XSETFASTINT (p->last_modified, 0);