aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Blandy1992-10-19 18:46:29 +0000
committerJim Blandy1992-10-19 18:46:29 +0000
commit605be8af79110be3db1bcb76575f82651f99379d (patch)
tree7ae671cb54f719297867b2d1f4d5723084df1105
parent896adf849920c1066cbbddad809e44a07a2b8b46 (diff)
downloademacs-605be8af79110be3db1bcb76575f82651f99379d.tar.gz
emacs-605be8af79110be3db1bcb76575f82651f99379d.zip
* 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.
-rw-r--r--src/window.c105
1 files changed, 79 insertions, 26 deletions
diff --git a/src/window.c b/src/window.c
index 8d6e24de2c5..65c33093ebe 100644
--- a/src/window.c
+++ b/src/window.c
@@ -29,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29#include "disptab.h" 29#include "disptab.h"
30#include "keyboard.h" 30#include "keyboard.h"
31 31
32Lisp_Object Qwindowp; 32Lisp_Object Qwindowp, Qlive_window_p;
33 33
34Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window (); 34Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window ();
35Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter (); 35Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter ();
@@ -105,6 +105,16 @@ DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
105 return XTYPE (obj) == Lisp_Window ? Qt : Qnil; 105 return XTYPE (obj) == Lisp_Window ? Qt : Qnil;
106} 106}
107 107
108DEFUN ("live-window-p", Flive_window_p, Slive_window_p, 1, 1, 0,
109 "Returns t if OBJ is a window which is currently visible.")
110 (obj)
111 Lisp_Object obj;
112{
113 return ((XTYPE (obj) == Lisp_Window
114 && ! NILP (XWINDOW (obj)->buffer))
115 ? Qt : Qnil);
116}
117
108Lisp_Object 118Lisp_Object
109make_window () 119make_window ()
110{ 120{
@@ -158,7 +168,7 @@ used by that frame.")
158 return FRAME_MINIBUF_WINDOW (XFRAME (frame)); 168 return FRAME_MINIBUF_WINDOW (XFRAME (frame));
159} 169}
160 170
161DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 1, 1, 0, 171DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0,
162 "Returns non-nil if WINDOW is a minibuffer window.") 172 "Returns non-nil if WINDOW is a minibuffer window.")
163 (window) 173 (window)
164 Lisp_Object window; 174 Lisp_Object window;
@@ -190,11 +200,7 @@ POS defaults to point; WINDOW, to the selected window.")
190 posint = XINT (pos); 200 posint = XINT (pos);
191 } 201 }
192 202
193 if (NILP (window)) 203 w = decode_window (window);
194 window = selected_window;
195 else
196 CHECK_WINDOW (window, 1);
197 w = XWINDOW (window);
198 top = marker_position (w->start); 204 top = marker_position (w->start);
199 205
200 if (posint < top) 206 if (posint < top)
@@ -235,7 +241,7 @@ decode_window (window)
235 if (NILP (window)) 241 if (NILP (window))
236 return XWINDOW (selected_window); 242 return XWINDOW (selected_window);
237 243
238 CHECK_WINDOW (window, 0); 244 CHECK_LIVE_WINDOW (window, 0);
239 return XWINDOW (window); 245 return XWINDOW (window);
240} 246}
241 247
@@ -370,7 +376,7 @@ If they are on the border between WINDOW and its right sibling,\n\
370{ 376{
371 int x, y; 377 int x, y;
372 378
373 CHECK_WINDOW (window, 0); 379 CHECK_LIVE_WINDOW (window, 0);
374 CHECK_CONS (coordinates, 1); 380 CHECK_CONS (coordinates, 1);
375 x = XINT (Fcar (coordinates)); 381 x = XINT (Fcar (coordinates));
376 y = XINT (Fcdr (coordinates)); 382 y = XINT (Fcdr (coordinates));
@@ -682,12 +688,21 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
682 register struct window *p; 688 register struct window *p;
683 register struct window *par; 689 register struct window *par;
684 690
691 /* Because this function is called by other C code on non-leaf
692 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
693 so we can't decode_window here. */
685 if (NILP (window)) 694 if (NILP (window))
686 window = selected_window; 695 window = selected_window;
687 else 696 else
688 CHECK_WINDOW (window, 0); 697 CHECK_WINDOW (window, 0);
689
690 p = XWINDOW (window); 698 p = XWINDOW (window);
699
700 /* It's okay to delete an already-deleted window. */
701 if (NILP (p->buffer)
702 && NILP (p->hchild)
703 && NILP (p->vchild))
704 return Qnil;
705
691 parent = p->parent; 706 parent = p->parent;
692 if (NILP (parent)) 707 if (NILP (parent))
693 error ("Attempt to delete minibuffer or sole ordinary window"); 708 error ("Attempt to delete minibuffer or sole ordinary window");
@@ -695,8 +710,25 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
695 710
696 windows_or_buffers_changed++; 711 windows_or_buffers_changed++;
697 712
698 if (EQ (window, selected_window)) 713 /* Are we trying to delete any frame's selected window? */
699 Fselect_window (Fnext_window (window, Qnil, Qnil)); 714 {
715 Lisp_Object frame = WINDOW_FRAME (XWINDOW (window));
716
717 if (EQ (window, FRAME_SELECTED_WINDOW (XFRAME (frame))))
718 {
719 Lisp_Object alternative = Fnext_window (window, Qlambda, Qnil);
720
721 /* If we're about to delete the selected window on the
722 selected frame, then we should use Fselect_window to select
723 the new window. On the other hand, if we're about to
724 delete the selected window on any other frame, we shouldn't do
725 anything but set the frame's selected_window slot. */
726 if (EQ (window, selected_window))
727 Fselect_window (alternative);
728 else
729 FRAME_SELECTED_WINDOW (XFRAME (frame)) = alternative;
730 }
731 }
700 732
701 tem = p->buffer; 733 tem = p->buffer;
702 /* tem is null for dummy parent windows 734 /* tem is null for dummy parent windows
@@ -706,7 +738,6 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
706 unshow_buffer (p); 738 unshow_buffer (p);
707 unchain_marker (p->pointm); 739 unchain_marker (p->pointm);
708 unchain_marker (p->start); 740 unchain_marker (p->start);
709 p->buffer = Qnil;
710 } 741 }
711 742
712 tem = p->next; 743 tem = p->next;
@@ -747,12 +778,22 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
747 778
748 /* If parent now has only one child, 779 /* If parent now has only one child,
749 put the child into the parent's place. */ 780 put the child into the parent's place. */
750
751 tem = par->hchild; 781 tem = par->hchild;
752 if (NILP (tem)) 782 if (NILP (tem))
753 tem = par->vchild; 783 tem = par->vchild;
754 if (NILP (XWINDOW (tem)->next)) 784 if (NILP (XWINDOW (tem)->next))
755 replace_window (parent, tem); 785 replace_window (parent, tem);
786
787 /* Since we may be deleting combination windows, we must make sure that
788 not only p but all its children have been marked as deleted. */
789 if (! NILP (p->hchild))
790 delete_all_subwindows (XWINDOW (p->hchild));
791 else if (! NILP (p->vchild))
792 delete_all_subwindows (XWINDOW (p->vchild));
793
794 /* Mark this window as deleted. */
795 p->buffer = p->hchild = p->vchild = Qnil;
796
756 return Qnil; 797 return Qnil;
757} 798}
758 799
@@ -786,7 +827,7 @@ above. If neither nil nor t, restrict to WINDOW's frame.")
786 if (NILP (window)) 827 if (NILP (window))
787 window = selected_window; 828 window = selected_window;
788 else 829 else
789 CHECK_WINDOW (window, 0); 830 CHECK_LIVE_WINDOW (window, 0);
790 831
791 start_window = window; 832 start_window = window;
792 833
@@ -883,7 +924,7 @@ above. If neither nil nor t, restrict to WINDOW's frame.")
883 if (NILP (window)) 924 if (NILP (window))
884 window = selected_window; 925 window = selected_window;
885 else 926 else
886 CHECK_WINDOW (window, 0); 927 CHECK_LIVE_WINDOW (window, 0);
887 928
888 start_window = window; 929 start_window = window;
889 930
@@ -1170,7 +1211,7 @@ window_loop (type, obj, mini, frames)
1170 1211
1171 return best_window; 1212 return best_window;
1172} 1213}
1173 1214
1174DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, 1215DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0,
1175 "Return the window least recently selected or used for display.\n\ 1216 "Return the window least recently selected or used for display.\n\
1176If optional argument FRAMES is t, search all frames. If FRAME is a\n\ 1217If optional argument FRAMES is t, search all frames. If FRAME is a\n\
@@ -1227,7 +1268,7 @@ Only the frame WINDOW is on is affected.")
1227 if (NILP (window)) 1268 if (NILP (window))
1228 window = selected_window; 1269 window = selected_window;
1229 else 1270 else
1230 CHECK_WINDOW (window, 0); 1271 CHECK_LIVE_WINDOW (window, 0);
1231 1272
1232 w = XWINDOW (window); 1273 w = XWINDOW (window);
1233 top = XFASTINT (w->top); 1274 top = XFASTINT (w->top);
@@ -1296,10 +1337,10 @@ check_min_window_sizes ()
1296 1337
1297/* If *ROWS or *COLS are too small a size for FRAME, set them to the 1338/* If *ROWS or *COLS are too small a size for FRAME, set them to the
1298 minimum allowable size. */ 1339 minimum allowable size. */
1299extern void 1340void
1300check_frame_size (frame, rows, cols) 1341check_frame_size (frame, rows, cols)
1301FRAME_PTR frame; 1342 FRAME_PTR frame;
1302int *rows, *cols; 1343 int *rows, *cols;
1303{ 1344{
1304 /* For height, we have to see whether the frame has a minibuffer, and 1345 /* For height, we have to see whether the frame has a minibuffer, and
1305 whether it wants a mode line. */ 1346 whether it wants a mode line. */
@@ -1497,7 +1538,7 @@ before each command.")
1497 register struct window *w; 1538 register struct window *w;
1498 register struct window *ow = XWINDOW (selected_window); 1539 register struct window *ow = XWINDOW (selected_window);
1499 1540
1500 CHECK_WINDOW (window, 0); 1541 CHECK_LIVE_WINDOW (window, 0);
1501 1542
1502 w = XWINDOW (window); 1543 w = XWINDOW (window);
1503 1544
@@ -1706,7 +1747,7 @@ and put SIZE columns in the first of the pair.")
1706 if (NILP (window)) 1747 if (NILP (window))
1707 window = selected_window; 1748 window = selected_window;
1708 else 1749 else
1709 CHECK_WINDOW (window, 0); 1750 CHECK_LIVE_WINDOW (window, 0);
1710 1751
1711 o = XWINDOW (window); 1752 o = XWINDOW (window);
1712 1753
@@ -2143,7 +2184,7 @@ showing that buffer, popping the buffer up if necessary.")
2143 else 2184 else
2144 /* Nothing specified; pick a neighboring window. */ 2185 /* Nothing specified; pick a neighboring window. */
2145 window = Fnext_window (selected_window, Qnil, Qt); 2186 window = Fnext_window (selected_window, Qnil, Qt);
2146 CHECK_WINDOW (window, 0); 2187 CHECK_LIVE_WINDOW (window, 0);
2147 2188
2148 if (EQ (window, selected_window)) 2189 if (EQ (window, selected_window))
2149 error ("There is no other window"); 2190 error ("There is no other window");
@@ -2540,14 +2581,22 @@ static void
2540delete_all_subwindows (w) 2581delete_all_subwindows (w)
2541 register struct window *w; 2582 register struct window *w;
2542{ 2583{
2543 w->height = w->buffer; /* See Fset_window_configuration for excuse. */
2544 w->buffer = Qnil;
2545 if (!NILP (w->next)) 2584 if (!NILP (w->next))
2546 delete_all_subwindows (XWINDOW (w->next)); 2585 delete_all_subwindows (XWINDOW (w->next));
2547 if (!NILP (w->vchild)) 2586 if (!NILP (w->vchild))
2548 delete_all_subwindows (XWINDOW (w->vchild)); 2587 delete_all_subwindows (XWINDOW (w->vchild));
2549 if (!NILP (w->hchild)) 2588 if (!NILP (w->hchild))
2550 delete_all_subwindows (XWINDOW (w->hchild)); 2589 delete_all_subwindows (XWINDOW (w->hchild));
2590
2591 w->height = w->buffer; /* See Fset_window_configuration for excuse. */
2592
2593 /* We set all three of these fields to nil, to make sure that we can
2594 distinguish this dead window from any live window. Live leaf
2595 windows will have buffer set, and combination windows will have
2596 vchild or hchild set. */
2597 w->buffer = Qnil;
2598 w->vchild = Qnil;
2599 w->hchild = Qnil;
2551} 2600}
2552 2601
2553static int 2602static int
@@ -2754,6 +2803,9 @@ syms_of_window ()
2754 Qwindowp = intern ("windowp"); 2803 Qwindowp = intern ("windowp");
2755 staticpro (&Qwindowp); 2804 staticpro (&Qwindowp);
2756 2805
2806 Qlive_window_p = intern ("live-window-p");
2807 staticpro (&Qlive_window_p);
2808
2757#ifndef MULTI_FRAME 2809#ifndef MULTI_FRAME
2758 /* Make sure all windows get marked */ 2810 /* Make sure all windows get marked */
2759 staticpro (&minibuf_window); 2811 staticpro (&minibuf_window);
@@ -2838,6 +2890,7 @@ If there is only one window, it is split regardless of this value.");
2838 defsubr (&Sminibuffer_window); 2890 defsubr (&Sminibuffer_window);
2839 defsubr (&Swindow_minibuffer_p); 2891 defsubr (&Swindow_minibuffer_p);
2840 defsubr (&Swindowp); 2892 defsubr (&Swindowp);
2893 defsubr (&Slive_window_p);
2841 defsubr (&Spos_visible_in_window_p); 2894 defsubr (&Spos_visible_in_window_p);
2842 defsubr (&Swindow_buffer); 2895 defsubr (&Swindow_buffer);
2843 defsubr (&Swindow_height); 2896 defsubr (&Swindow_height);