diff --git a/src/clfswm-internal.lisp b/src/clfswm-internal.lisp index 1d650c582a58274f84951e698b44af89a5999397..61fd5dcd608e591973241d3978b14cfd60bbad12 100644 --- a/src/clfswm-internal.lisp +++ b/src/clfswm-internal.lisp @@ -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) diff --git a/src/clfswm.lisp b/src/clfswm.lisp index 62cdf76f922e319fc4e4b279b27382da24977ce1..730d5d84c7a07554ad75ce817df0409912c6f515 100644 --- a/src/clfswm.lisp +++ b/src/clfswm.lisp @@ -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. diff --git a/src/xlib-util.lisp b/src/xlib-util.lisp index 6210c6e5f8fa8936826b38b9c61938beca5be59b..3fef7cffa4bde15690fba91d57462266fc822753 100644 --- a/src/xlib-util.lisp +++ b/src/xlib-util.lisp @@ -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)