# HG changeset patch # User Gerd Moellmann # Date 962893116 0 # Node ID 22f8fc642575399397230517089d672a99410510 # Parent 6d383cf4bb99ef0f4d227c5c2eccc394687eaf35 (Fwindow_list): Reverse list at the end. (candidate_window_p): Add parameter OWINDOW. ALL_FRAMES nil means allow windows on OWINDOW's frame, only. (window_loop): Simplified; use Fwindow_list. diff -r 6d383cf4bb99 -r 22f8fc642575 src/window.c --- a/src/window.c Thu Jul 06 13:58:49 2000 +0000 +++ b/src/window.c Thu Jul 06 14:18:36 2000 +0000 @@ -69,7 +69,8 @@ static void enlarge_window P_ ((Lisp_Object, int, int)); static Lisp_Object window_list P_ ((void)); static int add_window_to_list P_ ((struct window *, Lisp_Object *)); -static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); +static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object)); static Lisp_Object next_window P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int)); static void decode_next_window_args P_ ((Lisp_Object *, Lisp_Object *, @@ -1226,24 +1227,23 @@ } -/* Value is non-zero if WINODW satisfies the constraints given by - MINIBUF and ALL_FRAMES. - - MINIBUF t means WINDOW may be a minibuffer window. - MINIBUF `lambda' means it may not be a minibuffer window. - MINIBUF being a window means WINDOW must be equal to MINIBUF. - - ALL_FRAMES t means WINDOW may be on any frame. - ALL_FRAMES nil means WINDOW must not be on a minibuffer-only frame. - ALL_FRAMES `visible' means WINDOW must be on a visible frame. - ALL_FRAMES 0 means WINDOW must be on a visible or iconified frame. - ALL_FRAMES being a frame means WINDOW must be on that frame. - ALL_FRAMES being a window means WINDOW must be on a frame using - the same minibuffer as ALL_FRAMES. */ +/* Value is non-zero if WINDOW satisfies the constraints given by + OWINDOW, MINIBUF and ALL_FRAMES. + + MINIBUF t means WINDOW may be minibuffer windows. + `lambda' means WINDOW may not be a minibuffer window. + a window means a specific minibuffer window + + ALL_FRAMES t means search all frames, + nil means search just current frame, + `visible' means search just visible frames, + 0 means search visible and iconified frames, + a window means search the frame that window belongs to, + a frame means consider windows on that frame, only. */ static int -candidate_window_p (window, minibuf, all_frames) - Lisp_Object window, minibuf, all_frames; +candidate_window_p (window, owindow, minibuf, all_frames) + Lisp_Object window, owindow, minibuf, all_frames; { struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); @@ -1259,8 +1259,13 @@ If it is a window, consider only that one. */ candidate_p = 0; } + else if (EQ (all_frames, Qt)) + candidate_p = 1; else if (NILP (all_frames)) - candidate_p = !FRAME_MINIBUF_ONLY_P (f); + { + xassert (WINDOWP (owindow)); + candidate_p = EQ (w->frame, XWINDOW (owindow)->frame); + } else if (EQ (all_frames, Qvisible)) { FRAME_SAMPLE_VISIBILITY (f); @@ -1271,12 +1276,12 @@ FRAME_SAMPLE_VISIBILITY (f); candidate_p = FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f); } - else if (FRAMEP (all_frames)) - candidate_p = EQ (all_frames, w->frame); else if (WINDOWP (all_frames)) candidate_p = (EQ (FRAME_MINIBUF_WINDOW (f), all_frames) || EQ (XWINDOW (all_frames)->frame, w->frame) || EQ (XWINDOW (all_frames)->frame, FRAME_FOCUS_FRAME (f))); + else if (FRAMEP (all_frames)) + candidate_p = EQ (all_frames, w->frame); return candidate_p; } @@ -1356,7 +1361,7 @@ /* Scan forward from WINDOW to the end of the window list. */ if (CONSP (list)) for (list = XCDR (list); CONSP (list); list = XCDR (list)) - if (candidate_window_p (XCAR (list), minibuf, all_frames)) + if (candidate_window_p (XCAR (list), window, minibuf, all_frames)) break; /* Scan from the start of the window list up to WINDOW. */ @@ -1364,7 +1369,7 @@ for (list = Vwindow_list; CONSP (list) && !EQ (XCAR (list), window); list = XCDR (list)) - if (candidate_window_p (XCAR (list), minibuf, all_frames)) + if (candidate_window_p (XCAR (list), window, minibuf, all_frames)) break; if (CONSP (list)) @@ -1386,7 +1391,8 @@ if (WINDOWP (candidate)) break; } - else if (candidate_window_p (XCAR (list), minibuf, all_frames)) + else if (candidate_window_p (XCAR (list), window, minibuf, + all_frames)) candidate = XCAR (list); } @@ -1507,7 +1513,7 @@ DEFUN ("window-list", Fwindow_list, Swindow_list, 0, 3, 0, - "Return a list windows in canonical ordering.\n\ + "Return a list of windows in canonical ordering.\n\ Arguments are like for `next-window'.") (window, minibuf, all_frames) Lisp_Object minibuf, all_frames; @@ -1518,10 +1524,10 @@ list = Qnil; for (tail = window_list (); CONSP (tail); tail = XCDR (tail)) - if (candidate_window_p (XCAR (tail), minibuf, all_frames)) + if (candidate_window_p (XCAR (tail), window, minibuf, all_frames)) list = Fcons (XCAR (tail), list); - return list; + return Fnreverse (list); } @@ -1550,32 +1556,30 @@ static Lisp_Object window_loop (type, obj, mini, frames) enum window_loop type; - register Lisp_Object obj, frames; + Lisp_Object obj, frames; int mini; { - register Lisp_Object w; - register Lisp_Object best_window; - register Lisp_Object next_window; - register Lisp_Object last_window; - FRAME_PTR frame; - Lisp_Object frame_arg; - frame_arg = Qt; - + Lisp_Object window, windows, best_window, frame_arg; + struct frame *f; + /* If we're only looping through windows on a particular frame, frame points to that frame. If we're looping through windows on all frames, frame is 0. */ if (FRAMEP (frames)) - frame = XFRAME (frames); + f = XFRAME (frames); else if (NILP (frames)) - frame = SELECTED_FRAME (); + f = SELECTED_FRAME (); else - frame = 0; - if (frame) + f = NULL; + + if (f) frame_arg = Qlambda; else if (XFASTINT (frames) == 0) frame_arg = frames; else if (EQ (frames, Qvisible)) frame_arg = frames; + else + frame_arg = Qt; /* frame_arg is Qlambda to stick to one frame, Qvisible to consider all visible frames, @@ -1583,11 +1587,11 @@ /* Pick a window to start with. */ if (WINDOWP (obj)) - w = obj; - else if (frame) - w = FRAME_SELECTED_WINDOW (frame); + window = obj; + else if (f) + window = FRAME_SELECTED_WINDOW (f); else - w = FRAME_SELECTED_WINDOW (SELECTED_FRAME ()); + window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ()); /* Figure out the last window we're going to mess with. Since Fnext_window, given the same options, is guaranteed to go in a @@ -1596,178 +1600,162 @@ We can't just wait until we hit the first window again, because it might be deleted. */ - last_window = Fprevious_window (w, mini ? Qt : Qnil, frame_arg); - + windows = Fwindow_list (window, mini ? Qt : Qnil, frame_arg); + GCPRO1 (windows); best_window = Qnil; - for (;;) + + for (; CONSP (windows); windows = CDR (windows)) { - /* Pick the next window now, since some operations will delete - the current window. */ - next_window = Fnext_window (w, mini ? Qt : Qnil, frame_arg); - - /* Note that we do not pay attention here to whether - the frame is visible, since Fnext_window skips non-visible frames - if that is desired, under the control of frame_arg. */ - if (! MINI_WINDOW_P (XWINDOW (w)) + struct window *w; + + window = XCAR (windows); + w = XWINDOW (window); + + /* Note that we do not pay attention here to whether the frame + is visible, since Fwindow_list skips non-visible frames if + that is desired, under the control of frame_arg. */ + if (!MINI_WINDOW_P (w) /* For UNSHOW_BUFFER, we must always consider all windows. */ || type == UNSHOW_BUFFER || (mini && minibuf_level > 0)) switch (type) { case GET_BUFFER_WINDOW: - if (XBUFFER (XWINDOW (w)->buffer) == XBUFFER (obj) + if (EQ (w->buffer, obj) /* Don't find any minibuffer window except the one that is currently in use. */ - && (MINI_WINDOW_P (XWINDOW (w)) - ? EQ (w, minibuf_window) : 1)) - return w; + && (MINI_WINDOW_P (w) + ? EQ (window, minibuf_window) + : 1)) + { + UNGCPRO; + return window; + } break; case GET_LRU_WINDOW: /* t as arg means consider only full-width windows */ - if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (XWINDOW (w))) + if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (w)) break; /* Ignore dedicated windows and minibuffers. */ - if (MINI_WINDOW_P (XWINDOW (w)) - || !NILP (XWINDOW (w)->dedicated)) + if (MINI_WINDOW_P (w) || !NILP (w->dedicated)) break; if (NILP (best_window) || (XFASTINT (XWINDOW (best_window)->use_time) - > XFASTINT (XWINDOW (w)->use_time))) - best_window = w; + > XFASTINT (w->use_time))) + best_window = window; break; case DELETE_OTHER_WINDOWS: - if (XWINDOW (w) != XWINDOW (obj)) - Fdelete_window (w); + if (!EQ (window, obj)) + Fdelete_window (window); break; case DELETE_BUFFER_WINDOWS: - if (EQ (XWINDOW (w)->buffer, obj)) + if (EQ (w->buffer, obj)) { - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (w))); + struct frame *f = XFRAME (WINDOW_FRAME (w)); /* If this window is dedicated, and in a frame of its own, kill the frame. */ - if (EQ (w, FRAME_ROOT_WINDOW (f)) - && !NILP (XWINDOW (w)->dedicated) + if (EQ (window, FRAME_ROOT_WINDOW (f)) + && !NILP (w->dedicated) && other_visible_frames (f)) { /* Skip the other windows on this frame. There might be one, the minibuffer! */ - if (! EQ (w, last_window)) - while (f == XFRAME (WINDOW_FRAME (XWINDOW (next_window)))) - { - /* As we go, check for the end of the loop. - We mustn't start going around a second time. */ - if (EQ (next_window, last_window)) - { - last_window = w; - break; - } - next_window = Fnext_window (next_window, - mini ? Qt : Qnil, - frame_arg); - } + while (CONSP (XCDR (windows)) + && EQ (XWINDOW (XCAR (windows))->frame, + XWINDOW (XCAR (XCDR (windows)))->frame)) + windows = XCDR (windows); + /* Now we can safely delete the frame. */ - Fdelete_frame (WINDOW_FRAME (XWINDOW (w)), Qnil); + Fdelete_frame (w->frame, Qnil); + } + else if (NILP (w->parent)) + { + /* If we're deleting the buffer displayed in the + only window on the frame, find a new buffer to + display there. */ + Lisp_Object buffer; + buffer = Fother_buffer (obj, Qnil, w->frame); + if (NILP (buffer)) + buffer = Fget_buffer_create (build_string ("*scratch*")); + Fset_window_buffer (window, buffer); + if (EQ (window, selected_window)) + Fset_buffer (w->buffer); } else - /* If we're deleting the buffer displayed in the only window - on the frame, find a new buffer to display there. */ - if (NILP (XWINDOW (w)->parent)) - { - Lisp_Object new_buffer; - new_buffer = Fother_buffer (obj, Qnil, - XWINDOW (w)->frame); - if (NILP (new_buffer)) - new_buffer - = Fget_buffer_create (build_string ("*scratch*")); - Fset_window_buffer (w, new_buffer); - if (EQ (w, selected_window)) - Fset_buffer (XWINDOW (w)->buffer); - } - else - Fdelete_window (w); + Fdelete_window (window); } break; case GET_LARGEST_WINDOW: - /* Ignore dedicated windows and minibuffers. */ - if (MINI_WINDOW_P (XWINDOW (w)) - || !NILP (XWINDOW (w)->dedicated) - || NILP (best_window)) - break; { - struct window *best_window_ptr = XWINDOW (best_window); - struct window *w_ptr = XWINDOW (w); + struct window *b; + + /* Ignore dedicated windows and minibuffers. */ + if (MINI_WINDOW_P (w) + || !NILP (w->dedicated) + || NILP (best_window)) + break; + + b = XWINDOW (best_window); if (NILP (best_window) - || (XFASTINT (w_ptr->height) * XFASTINT (w_ptr->width) - > (XFASTINT (best_window_ptr->height) - * XFASTINT (best_window_ptr->width)))) - best_window = w; + || (XFASTINT (w->height) * XFASTINT (w->width) + > (XFASTINT (b->height) * XFASTINT (b->width)))) + best_window = window; } break; case UNSHOW_BUFFER: - if (EQ (XWINDOW (w)->buffer, obj)) + if (EQ (w->buffer, obj)) { + Lisp_Object buffer; + struct frame *f = XFRAME (w->frame); + /* Find another buffer to show in this window. */ - Lisp_Object another_buffer; - FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (w))); - another_buffer = Fother_buffer (obj, Qnil, XWINDOW (w)->frame); - if (NILP (another_buffer)) - another_buffer - = Fget_buffer_create (build_string ("*scratch*")); + buffer = Fother_buffer (obj, Qnil, w->frame); + if (NILP (buffer)) + buffer = Fget_buffer_create (build_string ("*scratch*")); + /* If this window is dedicated, and in a frame of its own, kill the frame. */ - if (EQ (w, FRAME_ROOT_WINDOW (f)) - && !NILP (XWINDOW (w)->dedicated) + if (EQ (window, FRAME_ROOT_WINDOW (f)) + && !NILP (w->dedicated) && other_visible_frames (f)) { /* Skip the other windows on this frame. There might be one, the minibuffer! */ - if (! EQ (w, last_window)) - while (f == XFRAME (WINDOW_FRAME (XWINDOW (next_window)))) - { - /* As we go, check for the end of the loop. - We mustn't start going around a second time. */ - if (EQ (next_window, last_window)) - { - last_window = w; - break; - } - next_window = Fnext_window (next_window, - mini ? Qt : Qnil, - frame_arg); - } + while (CONSP (XCDR (windows)) + && EQ (XWINDOW (XCAR (windows))->frame, + XWINDOW (XCAR (XCDR (windows)))->frame)) + windows = XCDR (windows); + /* Now we can safely delete the frame. */ - Fdelete_frame (WINDOW_FRAME (XWINDOW (w)), Qnil); + Fdelete_frame (w->frame, Qnil); } else { /* Otherwise show a different buffer in the window. */ - XWINDOW (w)->dedicated = Qnil; - Fset_window_buffer (w, another_buffer); - if (EQ (w, selected_window)) - Fset_buffer (XWINDOW (w)->buffer); + w->dedicated = Qnil; + Fset_window_buffer (window, buffer); + if (EQ (window, selected_window)) + Fset_buffer (w->buffer); } } break; /* Check for a window that has a killed buffer. */ case CHECK_ALL_WINDOWS: - if (! NILP (XWINDOW (w)->buffer) - && NILP (XBUFFER (XWINDOW (w)->buffer)->name)) + if (! NILP (w->buffer) + && NILP (XBUFFER (w->buffer)->name)) abort (); + break; } - - if (EQ (w, last_window)) - break; - - w = next_window; } + UNGCPRO; return best_window; }