From 1b6272e4585c5176705944f397932d9a9de212e6 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Thu, 22 Feb 2018 22:21:54 +0800 Subject: [PATCH] Hide blocked frames (they are visible with a compositor) * exwm-workspace.el (exwm-workspace--set-active): New function for setting the 'exwm-active' frame parameter and show/hide frames BTW. (exwm-workspace--active-p): New function checking whether a frame is active. (exwm-workspace--set-fullscreen, exwm-workspace-switch) (exwm-workspace-move-window): * exwm-randr.el (exwm-randr--refresh): Use them. * exwm-workspace.el (exwm-workspace-attach-minibuffer) (exwm-workspace--show-minibuffer, exwm-workspace--hide-minibuffer): Show/Hide the minibuffer frame. --- exwm-randr.el | 11 +++++-- exwm-workspace.el | 76 +++++++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/exwm-randr.el b/exwm-randr.el index c78a4ec81..a3593ec05 100644 --- a/exwm-randr.el +++ b/exwm-randr.el @@ -81,7 +81,10 @@ the first one in result being the primary output." (defvar exwm-workspace--fullscreen-frame-count) (defvar exwm-workspace--list) +(declare-function exwm-workspace--active-p "exwm-workspace.el" (frame)) (declare-function exwm-workspace--count "exwm-workspace.el") +(declare-function exwm-workspace--set-active "exwm-workspace.el" + (frame active)) (declare-function exwm-workspace--set-desktop-geometry "exwm-workspace.el" ()) (declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame)) (declare-function exwm-workspace--show-minibuffer "exwm-workspace.el" ()) @@ -138,7 +141,9 @@ the first one in result being the primary output." container-frame-alist)) (set-frame-parameter frame 'exwm-randr-output output) (set-frame-parameter frame 'exwm-geometry geometry))) - ;; Update the 'exwm-active' frame parameter. + ;; Update active/inactive workspaces. + (dolist (w exwm-workspace--list) + (exwm-workspace--set-active w nil)) (dolist (xwin (reverse (slot-value (xcb:+request-unchecked+reply exwm--connection @@ -149,8 +154,8 @@ the first one in result being the primary output." (when output (setq container-output-alist (rassq-delete-all output container-output-alist)) - (set-frame-parameter (cdr (assq xwin container-frame-alist)) - 'exwm-active t)))) + (exwm-workspace--set-active (cdr (assq xwin container-frame-alist)) + t)))) ;; Update workareas. (exwm-workspace--update-workareas) ;; Resize workspace. diff --git a/exwm-workspace.el b/exwm-workspace.el index 6025ace41..a0a8d0db5 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -369,6 +369,18 @@ NIL if FRAME is not a workspace" (xcb:flush exwm--connection)) (run-hooks 'exwm-workspace--update-workareas-hook)) +(defun exwm-workspace--set-active (frame active) + "Make frame FRAME active on its output." + (set-frame-parameter frame 'exwm-active active) + (if active + (exwm-workspace--set-fullscreen frame) + (exwm--set-geometry (frame-parameter frame 'exwm-container) nil nil 1 1) + (xcb:flush exwm--connection))) + +(defun exwm-workspace--active-p (frame) + "Return non-nil if FRAME is active" + (frame-parameter frame 'exwm-active)) + (defun exwm-workspace--set-fullscreen (frame) "Make frame FRAME fullscreen according to `exwm-workspace--workareas'." (let ((workarea (elt exwm-workspace--workareas @@ -383,7 +395,9 @@ NIL if FRAME is not a workspace" (when (and (eq frame exwm-workspace--current) (exwm-workspace--minibuffer-own-frame-p)) (exwm-workspace--resize-minibuffer-frame)) - (exwm--set-geometry container x y width height) + (if (exwm-workspace--active-p frame) + (exwm--set-geometry container x y width height) + (exwm--set-geometry container x y 1 1)) (exwm--set-geometry id nil nil width height) (xcb:flush exwm--connection)) ;; This is only used for workspace initialization. @@ -516,25 +530,25 @@ for internal use only." ;; Show/Hide X windows. (let ((output-old (frame-parameter old-frame 'exwm-randr-output)) (output-new (frame-parameter frame 'exwm-randr-output)) - (active-old (frame-parameter old-frame 'exwm-active)) - (active-new (frame-parameter frame 'exwm-active)) + (active-old (exwm-workspace--active-p old-frame)) + (active-new (exwm-workspace--active-p frame)) workspaces-to-hide) (cond ((not active-old) - (set-frame-parameter frame 'exwm-active t)) + (exwm-workspace--set-active frame t)) ((eq output-old output-new) - (set-frame-parameter old-frame 'exwm-active nil) - (set-frame-parameter frame 'exwm-active t) + (exwm-workspace--set-active old-frame nil) + (exwm-workspace--set-active frame t) (setq workspaces-to-hide (list old-frame))) (active-new) (t (dolist (w exwm-workspace--list) - (when (and (frame-parameter w 'exwm-active) + (when (and (exwm-workspace--active-p w) (eq output-new (frame-parameter w 'exwm-randr-output))) - (set-frame-parameter w 'exwm-active nil) + (exwm-workspace--set-active w nil) (setq workspaces-to-hide (append workspaces-to-hide (list w))))) - (set-frame-parameter frame 'exwm-active t))) + (exwm-workspace--set-active frame t))) (dolist (i exwm--id-buffer-alist) (with-current-buffer (cdr i) (if (memq exwm--frame workspaces-to-hide) @@ -737,7 +751,7 @@ INDEX must not exceed the current number of workspaces." (exwm--id->buffer id)) (if (eq frame exwm-workspace--current) (select-window (frame-selected-window frame)) - (unless (frame-parameter frame 'exwm-active) + (unless (exwm-workspace--active-p frame) (exwm-layout--hide id)))) ;; Floating. (setq container (frame-parameter exwm--floating-frame @@ -762,7 +776,7 @@ INDEX must not exceed the current number of workspaces." (if (eq frame exwm-workspace--current) (select-window (frame-root-window exwm--floating-frame)) (select-window (frame-selected-window exwm-workspace--current)) - (unless (frame-parameter frame 'exwm-active) + (unless (exwm-workspace--active-p frame) (exwm-layout--hide id))) ;; The frame needs to be recreated since it won't use the ;; minibuffer on the new workspace. @@ -823,7 +837,7 @@ INDEX must not exceed the current number of workspaces." (if (eq frame exwm-workspace--current) (with-current-buffer (exwm--id->buffer id) (select-window (frame-root-window exwm--floating-frame))) - (unless (frame-parameter frame 'exwm-active) + (unless (exwm-workspace--active-p frame) (exwm-layout--hide id))))) ;; Update the 'exwm-selected-window' frame parameter. (when (not (eq frame exwm-workspace--current)) @@ -935,6 +949,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." (redisplay) ;FIXME. (setq exwm-workspace--attached-minibuffer-height (frame-pixel-height exwm-workspace--minibuffer)) + (exwm-workspace--show-minibuffer) (let ((container (frame-parameter exwm-workspace--minibuffer 'exwm-container))) (push (cons container @@ -945,8 +960,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." (exwm-workspace--update-struts) (exwm-workspace--update-workareas) (dolist (f exwm-workspace--list) - (exwm-workspace--set-fullscreen f)) - (exwm-workspace--show-minibuffer)))) + (exwm-workspace--set-fullscreen f))))) ;;;###autoload (defun exwm-workspace-detach-minibuffer () @@ -1050,6 +1064,12 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." (cancel-timer exwm-workspace--display-echo-area-timer) (setq exwm-workspace--display-echo-area-timer nil)) ;; Show the minibuffer frame. + (unless (exwm-workspace--minibuffer-attached-p) + (exwm--set-geometry (frame-parameter exwm-workspace--minibuffer + 'exwm-container) + nil nil + (frame-pixel-width exwm-workspace--minibuffer) + (frame-pixel-height exwm-workspace--minibuffer))) (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow :window (frame-parameter exwm-workspace--minibuffer @@ -1061,18 +1081,22 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first." (defun exwm-workspace--hide-minibuffer () "Hide the minibuffer frame." ;; Hide the minibuffer frame. - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window (frame-parameter exwm-workspace--minibuffer - 'exwm-container) - :value-mask (logior (if exwm-manage--desktop - xcb:ConfigWindow:Sibling - 0) - xcb:ConfigWindow:StackMode) - :sibling exwm-manage--desktop - :stack-mode (if exwm-manage--desktop - xcb:StackMode:Above - xcb:StackMode:Below))) + (if (exwm-workspace--minibuffer-attached-p) + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window (frame-parameter exwm-workspace--minibuffer + 'exwm-container) + :value-mask (logior (if exwm-manage--desktop + xcb:ConfigWindow:Sibling + 0) + xcb:ConfigWindow:StackMode) + :sibling exwm-manage--desktop + :stack-mode (if exwm-manage--desktop + xcb:StackMode:Above + xcb:StackMode:Below))) + (exwm--set-geometry (frame-parameter exwm-workspace--minibuffer + 'exwm-container) + nil nil 1 1)) (xcb:flush exwm--connection)) (defun exwm-workspace--on-minibuffer-setup ()