Only windows with no transient windows participate in hidden children optimization
authorPhilippe Brochard <pbrochard@common-lisp.net>
Fri, 18 Jan 2013 22:36:32 +0000 (23:36 +0100)
committerPhilippe Brochard <pbrochard@common-lisp.net>
Fri, 18 Jan 2013 22:36:32 +0000 (23:36 +0100)
src/clfswm-internal.lisp
src/clfswm.lisp
src/xlib-util.lisp

index 1d650c5..61fd5dc 100644 (file)
@@ -1204,8 +1204,22 @@ XINERAMA version 1.1 opcode: 150
     "Show all children and hide those not in a root frame"
     (declare (ignore from-root-frame))
     (let ((geometry-change nil)
-          (hidden-child nil))
-      (labels ((in-displayed-list (child)
+          (hidden-child nil)
+          (has-no-leader-list nil))
+      (labels ((set-has-no-leader-list ()
+                 (let ((window-list nil)
+                       (leader-list nil))
+                   (with-all-windows (*root-frame* win)
+                     (let ((leader (window-leader win)))
+                       (when leader
+                         (when (member leader window-list :test (lambda (x y) (eql x (first y))))
+                           (pushnew leader leader-list))
+                         (push (list leader win) window-list))))
+                   (dolist (leader-win window-list)
+                     (unless (member leader-win leader-list :test (lambda (x y) (eql (first x) y)))
+                       (push (second leader-win) has-no-leader-list)))))
+
+               (in-displayed-list (child)
                  (member child displayed-child :test (lambda (c rect)
                                                        (child-equal-p c (child-rect-child rect)))))
 
@@ -1240,7 +1254,8 @@ XINERAMA version 1.1 opcode: 150
                    (let ((rect (make-child-rect :child child :parent parent
                                                 :selected-p selected-p
                                                 :x nx :y ny :w nw :h nh)))
-                     (if (and *show-hide-policy* (hidden-child-p rect))
+                     (if (and *show-hide-policy* (hidden-child-p rect)
+                              (member child has-no-leader-list :test #'child-equal-p))
                          (add-in-hidden-list child)
                          (push rect displayed-child)))))
 
@@ -1267,6 +1282,7 @@ XINERAMA version 1.1 opcode: 150
                      (select-and-display child parent selected-p)))))
 
         (setf displayed-child nil)
+        (set-has-no-leader-list)
         (rec *root-frame* nil t (child-root-p *root-frame*))
         (display-displayed-child)
         (dolist (child hidden-child)
index 62cdf76..730d5d8 100644 (file)
@@ -79,9 +79,9 @@
                (when (or (child-equal-p window (current-child))
                          (is-in-current-child-p window))
                  (setf change (or change :moved))
+                 (show-all-children)
                  (focus-window window)
-                 (focus-all-children window (find-parent-frame window (find-current-root)))
-                 (show-all-children))))))
+                 (focus-all-children window (find-parent-frame window (find-current-root))))))))
         (unless (eq change :resized)
           ;; To be ICCCM compliant, send a fake configuration notify event only when
           ;; the window has moved and not when it has been resized or the border width has changed.
index 6210c6e..3fef7cf 100644 (file)
@@ -374,6 +374,16 @@ they should be windows. So use this function to make a window out of them."
   (eql (window-state window) +iconic-state+))
 
 
+(defun window-transient-for (window)
+  (first (xlib:get-property window :WM_TRANSIENT_FOR)))
+
+(defun window-leader (window)
+  (when window
+    (or (first (xlib:get-property window :WM_CLIENT_LEADER))
+        (let ((id (window-transient-for window)))
+          (when id
+            (window-leader id))))))
+
 
 
 (defun unhide-window (window)