changeset 1444:559d2f2119aa

* window.c: Try to deal coherently with deleted windows: * (Flive_window_p): New function. (Qlive_window_p): New variable, to name it in type errors. (syms_of_window): Defsubr Slive_window_p, init and staticpro Qlive_window_p. (decode_window): Use CHECK_LIVE_WINDOW instead of CHECK_WINDOW; the only thing a user should be able to do to a dead window is check its type. (Fcoordinates_in_window_p, Fnext_window, Fprevious_window, Fdelete_other_windows, Fselect_window, Fsplit_window, Fscroll_other_window): Use CHECK_LIVE_WINDOW instead of CHECK_WINDOW. (Fdelete_window): If WINDOW is a deleted window, do nothing; there's no harm in allowing people to delete deleted windows. Delete all of WINDOW's subwindows, too. (delete_all_subwindows): Set the buffer, vchild, and hchild of the windows we delete all to nil. * window.c (Fwindow_minibuffer_p): Make the WINDOW argument optional, like all the other window-querying functions. * window.c (Fpos_visible_in_window_p): Use decode_window to handle the WINDOW argument, instead of writing out that function's code. * window.c (check_frame_size): Don't define this extern; that doesn't mean anything. * window.c (Fdelete_window): Choose an alternative when we delete any frame's selected window, not just when we delete the selected frame's selected window.
author Jim Blandy <jimb@redhat.com>
date Mon, 19 Oct 1992 18:46:29 +0000
parents b359c67a9194
children 3b0906e2b82c
files src/window.c
diffstat 1 files changed, 79 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/window.c	Mon Oct 19 18:44:46 1992 +0000
+++ b/src/window.c	Mon Oct 19 18:46:29 1992 +0000
@@ -29,7 +29,7 @@
 #include "disptab.h"
 #include "keyboard.h"
 
-Lisp_Object Qwindowp;
+Lisp_Object Qwindowp, Qlive_window_p;
 
 Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window ();
 Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter ();
@@ -105,6 +105,16 @@
   return XTYPE (obj) == Lisp_Window ? Qt : Qnil;
 }
 
+DEFUN ("live-window-p", Flive_window_p, Slive_window_p, 1, 1, 0,
+  "Returns t if OBJ is a window which is currently visible.")
+     (obj)
+     Lisp_Object obj;
+{
+  return ((XTYPE (obj) == Lisp_Window
+	   && ! NILP (XWINDOW (obj)->buffer))
+	  ? Qt : Qnil);
+}
+
 Lisp_Object
 make_window ()
 {
@@ -158,7 +168,7 @@
   return FRAME_MINIBUF_WINDOW (XFRAME (frame));
 }
 
-DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 1, 1, 0,
+DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0,
   "Returns non-nil if WINDOW is a minibuffer window.")
   (window)
      Lisp_Object window;
@@ -190,11 +200,7 @@
       posint = XINT (pos);
     }
 
-  if (NILP (window))
-    window = selected_window;
-  else
-    CHECK_WINDOW (window, 1);
-  w = XWINDOW (window);
+  w = decode_window (window);
   top = marker_position (w->start);
 
   if (posint < top)
@@ -235,7 +241,7 @@
   if (NILP (window))
     return XWINDOW (selected_window);
 
-  CHECK_WINDOW (window, 0);
+  CHECK_LIVE_WINDOW (window, 0);
   return XWINDOW (window);
 }
 
@@ -370,7 +376,7 @@
 {
   int x, y;
 
-  CHECK_WINDOW (window, 0);
+  CHECK_LIVE_WINDOW (window, 0);
   CHECK_CONS (coordinates, 1);
   x = XINT (Fcar (coordinates));
   y = XINT (Fcdr (coordinates));
@@ -682,12 +688,21 @@
   register struct window *p;
   register struct window *par;
 
+  /* Because this function is called by other C code on non-leaf
+     windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
+     so we can't decode_window here.  */
   if (NILP (window))
     window = selected_window;
   else
     CHECK_WINDOW (window, 0);
-
   p = XWINDOW (window);
+
+  /* It's okay to delete an already-deleted window.  */
+  if (NILP (p->buffer)
+      && NILP (p->hchild)
+      && NILP (p->vchild))
+    return Qnil;
+
   parent = p->parent;
   if (NILP (parent))
     error ("Attempt to delete minibuffer or sole ordinary window");
@@ -695,8 +710,25 @@
 
   windows_or_buffers_changed++;
 
-  if (EQ (window, selected_window))
-    Fselect_window (Fnext_window (window, Qnil, Qnil));
+  /* Are we trying to delete any frame's selected window?  */
+  {
+    Lisp_Object frame = WINDOW_FRAME (XWINDOW (window));
+
+    if (EQ (window, FRAME_SELECTED_WINDOW (XFRAME (frame))))
+      {
+	Lisp_Object 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);
+	else
+	  FRAME_SELECTED_WINDOW (XFRAME (frame)) = alternative;
+      }
+  }
 
   tem = p->buffer;
   /* tem is null for dummy parent windows
@@ -706,7 +738,6 @@
       unshow_buffer (p);
       unchain_marker (p->pointm);
       unchain_marker (p->start);
-      p->buffer = Qnil;
     }
 
   tem = p->next;
@@ -747,12 +778,22 @@
 
   /* If parent now has only one child,
      put the child into the parent's place.  */
-
   tem = par->hchild;
   if (NILP (tem))
     tem = par->vchild;
   if (NILP (XWINDOW (tem)->next))
     replace_window (parent, tem);
+
+  /* Since we may be deleting combination windows, we must make sure that
+     not only p but all its children have been marked as deleted.  */
+  if (! NILP (p->hchild))
+    delete_all_subwindows (XWINDOW (p->hchild));
+  else if (! NILP (p->vchild))
+    delete_all_subwindows (XWINDOW (p->vchild));
+
+  /* Mark this window as deleted.  */
+  p->buffer = p->hchild = p->vchild = Qnil;
+
   return Qnil;
 }
 
@@ -786,7 +827,7 @@
   if (NILP (window))
     window = selected_window;
   else
-    CHECK_WINDOW (window, 0);
+    CHECK_LIVE_WINDOW (window, 0);
 
   start_window = window;
 
@@ -883,7 +924,7 @@
   if (NILP (window))
     window = selected_window;
   else
-    CHECK_WINDOW (window, 0);
+    CHECK_LIVE_WINDOW (window, 0);
 
   start_window = window;
 
@@ -1170,7 +1211,7 @@
 
   return best_window;
 }     
-
+
 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0,
   "Return the window least recently selected or used for display.\n\
 If optional argument FRAMES is t, search all frames.  If FRAME is a\n\
@@ -1227,7 +1268,7 @@
   if (NILP (window))
     window = selected_window;
   else
-    CHECK_WINDOW (window, 0);
+    CHECK_LIVE_WINDOW (window, 0);
 
   w = XWINDOW (window);
   top = XFASTINT (w->top);
@@ -1296,10 +1337,10 @@
 
 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
    minimum allowable size.  */
-extern void
+void
 check_frame_size (frame, rows, cols)
-FRAME_PTR frame;
-int *rows, *cols;
+     FRAME_PTR frame;
+     int *rows, *cols;
 {
   /* For height, we have to see whether the frame has a minibuffer, and
      whether it wants a mode line.  */
@@ -1497,7 +1538,7 @@
   register struct window *w;
   register struct window *ow = XWINDOW (selected_window);
 
-  CHECK_WINDOW (window, 0);
+  CHECK_LIVE_WINDOW (window, 0);
 
   w = XWINDOW (window);
 
@@ -1706,7 +1747,7 @@
   if (NILP (window))
     window = selected_window;
   else
-    CHECK_WINDOW (window, 0);
+    CHECK_LIVE_WINDOW (window, 0);
 
   o = XWINDOW (window);
 
@@ -2143,7 +2184,7 @@
   else
     /* Nothing specified; pick a neighboring window.  */
     window = Fnext_window (selected_window, Qnil, Qt);
-  CHECK_WINDOW (window, 0);
+  CHECK_LIVE_WINDOW (window, 0);
 
   if (EQ (window, selected_window))
     error ("There is no other window");
@@ -2540,14 +2581,22 @@
 delete_all_subwindows (w)
      register struct window *w;
 {
-  w->height = w->buffer;       /* See Fset_window_configuration for excuse.  */
-  w->buffer = Qnil;
   if (!NILP (w->next))
     delete_all_subwindows (XWINDOW (w->next));
   if (!NILP (w->vchild))
     delete_all_subwindows (XWINDOW (w->vchild));
   if (!NILP (w->hchild))
     delete_all_subwindows (XWINDOW (w->hchild));
+
+  w->height = w->buffer;       /* See Fset_window_configuration for excuse.  */
+
+  /* We set all three of these fields to nil, to make sure that we can
+     distinguish this dead window from any live window.  Live leaf
+     windows will have buffer set, and combination windows will have
+     vchild or hchild set.  */
+  w->buffer = Qnil;
+  w->vchild = Qnil;
+  w->hchild = Qnil;
 }
 
 static int
@@ -2754,6 +2803,9 @@
   Qwindowp = intern ("windowp");
   staticpro (&Qwindowp);
 
+  Qlive_window_p = intern ("live-window-p");
+  staticpro (&Qlive_window_p);
+
 #ifndef MULTI_FRAME
   /* Make sure all windows get marked */
   staticpro (&minibuf_window);
@@ -2838,6 +2890,7 @@
   defsubr (&Sminibuffer_window);
   defsubr (&Swindow_minibuffer_p);
   defsubr (&Swindowp);
+  defsubr (&Slive_window_p);
   defsubr (&Spos_visible_in_window_p);
   defsubr (&Swindow_buffer);
   defsubr (&Swindow_height);