=== modified file 'lisp/window.el' --- lisp/window.el 2008-06-17 22:33:06 +0000 +++ lisp/window.el 2008-06-22 12:25:44 +0000 @@ -1625,5 +1625,77 @@ (define-key ctl-x-map "+" 'balance-windows) (define-key ctl-x-4-map "0" 'kill-buffer-and-window) + +;; Below are functions for managing window-groups. Window +;; groups allow windows in a frame a degree of separation from other +;; windows in the same frame, similar to the way windows in different +;; frames are separated from each other. + +;; Here's some examples. + +;; Make a new frame and split it vertically: +;; (split-window-horizontally) +;; Call the left side the "Context Area" and the left one the "Edit Area". +;; Now make the "Context Area" into a group: +;; (window-group-create (selected-window)) +;; Theres actually two groups now, the "Context Area" and the default "Edit Area". +;; Now try "c-x o". Notice that you dont go to the "Edit Area". +;; Now try splitting the "Context Area" with "c-x 2", and switch buffers a bit +;; Now try removing windows with "c-x 0". Notice that only windows in the +;; current group are affected. +;; To return the state as it was: +;; (window-group-dissolve (window-group (selected-window))) + + +(defun window-group (window) + "Return the window group object that WINDOW belongs to. +Return nil if WINDOW is not in a window group." + (window-parameter window 'group)) + +(defun window-group-member-p (window group) + "Non nil if WINDOW is a member of GROUP." + (eq group (window-group window))) + +(defun window-group-members (group) + "Return all windows in GROUP. +Must be in selected frame." + (let ((group-windows ())) + (walk-windows + (lambda (w) + (when (window-group-member-p w group ) + (push w group-windows)))) + group-windows)) + +(defvar window-group--counter 0 + "An internal variable to keep track of window groups.") + +(defun window-group-create (window) + "Return a window group object with WINDOW as its only member. +An error is signalled if WINDOW is not visible or already part of +a group." + (if (window-group window) + (error "Window %s is already part of group %s" + ;;TODO check that the resulting error is not nonsensical + window (window-group window))) + ;;TODO we should now test for window visibility + (setq window-group--counter (1+ window-group--counter)) + (let* ((name (concat "group-" (number-to-string window-group--counter))) + (group (make-symbol name))) + (set-window-parameter window 'group group) + group)) + +(defun window-group-dissolve (group) + "Dissolve the window group object GROUP. +The windows in the group are not deleted." + (let ((group-windows (window-group-members group))) + (if (null group-windows) + (error "No group %s on current frame" group) + ;;TODO I think the group id is not suitable for printing! + (dolist (win group-windows) + (set-window-parameter win 'group nil))))) + +(provide 'window-group) + + ;; arch-tag: b508dfcc-c353-4c37-89fa-e773fe10cea9 ;;; window.el ends here === modified file 'src/window.c' --- src/window.c 2008-06-10 22:08:42 +0000 +++ src/window.c 2008-06-19 13:25:41 +0000 @@ -54,6 +54,7 @@ Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; Lisp_Object Qdisplay_buffer; Lisp_Object Qscroll_up, Qscroll_down; +Lisp_Object Qgroup; Lisp_Object Qwindow_size_fixed; extern Lisp_Object Qleft_margin, Qright_margin; @@ -82,7 +83,8 @@ Lisp_Object *)); static int foreach_window_1 P_ ((struct window *, int (* fn) (struct window *, void *), - void *)); + void *, + int)); static Lisp_Object window_list_1 P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); /* This is the window in which the terminal's cursor should @@ -1041,7 +1043,7 @@ window = Qnil; cw.window = &window, cw.x = &x, cw.y = &y; cw.part = part; - foreach_window (f, check_window_containing, &cw); + foreach_window (f, check_window_containing, &cw, 1); /* If not found above, see if it's in the tool bar window, if a tool bar exists. */ @@ -1733,7 +1735,8 @@ static Lisp_Object window_list () { - if (!CONSP (Vwindow_list)) + //if(!CONSP (Vwindow_list)) + if (1) //never cache the window list for now FIXME { Lisp_Object tail; @@ -1746,7 +1749,7 @@ new windows at the front of args[1], which means we have to reverse this list at the end. */ args[1] = Qnil; - foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]); + foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1], 0); args[0] = Vwindow_list; args[1] = Fnreverse (args[1]); Vwindow_list = Fnconc (2, args); @@ -2213,7 +2216,7 @@ break; case DELETE_OTHER_WINDOWS: - if (!EQ (window, obj)) + if (!EQ (window, obj) ) Fdelete_window (window); break; @@ -3882,6 +3885,12 @@ adjust_glyphs (fo); Fset_window_buffer (new, o->buffer, Qt); + /* make the new window inherit group properties. We + inherit only those atm, because its not obvious that all + properties should be inherited + */ + if(!NILP(Fwindow_parameter(window, Qgroup))) + Fset_window_parameter(new, Qgroup, Fwindow_parameter(window, Qgroup)); return new; } @@ -6826,17 +6835,20 @@ /* Call FN for all leaf windows on frame F. FN is called with the first argument being a pointer to the leaf window, and with - additional argument USER_DATA. Stops when FN returns 0. */ + additional argument USER_DATA. Stops when FN returns 0. + ALLWINDOWS 1 means iterate every window, else only the group of the selected window +*/ void -foreach_window (f, fn, user_data) +foreach_window (f, fn, user_data, allwindows) struct frame *f; int (* fn) P_ ((struct window *, void *)); void *user_data; + int allwindows; { /* Fdelete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */ if (WINDOWP (FRAME_ROOT_WINDOW (f))) - foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data); + foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data,allwindows); } @@ -6846,22 +6858,31 @@ Stop when FN returns 0. Value is 0 if stopped by FN. */ static int -foreach_window_1 (w, fn, user_data) +foreach_window_1 (w, fn, user_data, allwindows) struct window *w; int (* fn) P_ ((struct window *, void *)); void *user_data; + int allwindows; { int cont; - + struct window *current_window=XWINDOW(selected_window); + register Lisp_Object group = Fcdr(Fassq(Qgroup, current_window->window_parameters)); + Lisp_Object group2; for (cont = 1; w && cont;) { if (!NILP (w->hchild)) - cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data); + cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data,allwindows); else if (!NILP (w->vchild)) - cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data); - else - cont = fn (w, user_data); - + cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data,allwindows); + else{ + //only call fn if the group of the frames selected window + //is the same as the group of the current window in the loop. + group2=Fcdr(Fassq(Qgroup,w->window_parameters)); + debug_print(group); + debug_print(group2); + if (allwindows || EQ(group , group2 )) + cont = fn (w, user_data); + } w = NILP (w->next) ? 0 : XWINDOW (w->next); } @@ -6900,7 +6921,7 @@ struct frame *f; int freeze_p; { - foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); + foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0),1); } @@ -7061,6 +7082,10 @@ void syms_of_window () { + + Qgroup = intern ("group"); + staticpro (&Qgroup); + Qscroll_up = intern ("scroll-up"); staticpro (&Qscroll_up); === modified file 'src/window.h' --- src/window.h 2008-06-06 00:00:29 +0000 +++ src/window.h 2008-06-07 22:28:47 +0000 @@ -784,7 +784,8 @@ extern void freeze_window_starts P_ ((struct frame *, int)); extern void foreach_window P_ ((struct frame *, int (* fn) (struct window *, void *), - void *)); + void *, + int allwindows)); extern void grow_mini_window P_ ((struct window *, int)); extern void shrink_mini_window P_ ((struct window *));