Mercurial > emacs
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);