From b8ce20b4f3eac1228aef58b83a72a87ccdb819d0 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Mon, 19 Feb 2018 22:34:03 +0800 Subject: [PATCH] Support displaying floating X windows on all workspaces ; Setting _NET_WM_DESKTOP to 0xffffffff makes an X windows appearing ; on all desktops (EWMH). It's tricky to do it for tiling X windows ; so it's not implemented. * exwm-core.el (exwm--desktop): New buffer-local variable recording the value of _NET_WM_DESKTOP. * exwm-layout.el (exwm-layout--hide): Do not hide X windows with this property set to 0xffffffff. * exwm.el (exwm--update-desktop): New function for fetching the value of _NET_WM_DESKTOP and setting `exwm--desktop'. * exwm-manage.el (exwm-manage--manage-window): Use it. * exwm-workspace.el (exwm-workspace--set-desktop): Also update `exwm--desktop'. --- exwm-core.el | 1 + exwm-layout.el | 4 +++- exwm-manage.el | 15 ++------------- exwm-workspace.el | 10 ++++++---- exwm.el | 26 ++++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/exwm-core.el b/exwm-core.el index 68ec53b..71498c9 100644 --- a/exwm-core.el +++ b/exwm-core.el @@ -139,6 +139,7 @@ least SECS seconds later." (defvar-local exwm--on-KeyPress ;KeyPress event handler #'exwm-input--on-KeyPress-line-mode) ;; Properties +(defvar-local exwm--desktop nil "_NET_WM_DESKTOP.") (defvar-local exwm-window-type nil "_NET_WM_WINDOW_TYPE.") (defvar-local exwm--geometry nil) (defvar-local exwm-class-name nil "Class name in WM_CLASS.") diff --git a/exwm-layout.el b/exwm-layout.el index a98e261..3f624ad 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -102,7 +102,9 @@ (defun exwm-layout--hide (id) "Hide window ID." (with-current-buffer (exwm--id->buffer id) - (unless (exwm-layout--iconic-state-p) ;already hidden + (unless (or (exwm-layout--iconic-state-p) + (and exwm--floating-frame + (eq #xffffffff exwm--desktop))) (exwm--log "Hide #x%x" id) (when exwm--floating-frame (let* ((container (frame-parameter exwm--floating-frame diff --git a/exwm-manage.el b/exwm-manage.el index b983ebf..790b6f1 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -73,6 +73,7 @@ You can still make the X windows floating afterwards." (declare-function exwm--update-struts "exwm.el" (id)) (declare-function exwm--update-title "exwm.el" (id)) (declare-function exwm--update-transient-for "exwm.el" (id &optional force)) +(declare-function exwm--update-desktop "exwm.el" (id &optional force)) (declare-function exwm--update-window-type "exwm.el" (id &optional force)) (declare-function exwm-floating--set-floating "exwm-floating.el" (id)) (declare-function exwm-floating--unset-floating "exwm-floating.el" (id)) @@ -252,19 +253,7 @@ You can still make the X windows floating afterwards." (exwm-floating--unset-floating id)) (exwm-input-grab-keyboard id) (setq exwm-workspace--switch-history-outdated t) - ;; Set _NET_WM_DESKTOP or move window. - (let ((reply (xcb:+request-unchecked+reply exwm--connection - (make-instance 'xcb:ewmh:get-_NET_WM_DESKTOP - :window id))) - desktop) - (when reply - (setq desktop (slot-value reply 'value))) - (if (and desktop - (/= desktop exwm-workspace-current-index) - ;; Check the range. - (< desktop (exwm-workspace--count))) - (exwm-workspace-move-window desktop id) - (exwm-workspace--set-desktop id))) + (exwm--update-desktop id) (exwm-manage--update-ewmh-state id) (with-current-buffer (exwm--id->buffer id) (when (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) diff --git a/exwm-workspace.el b/exwm-workspace.el index b9cda25..e2dfa23 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -685,10 +685,12 @@ INDEX must not exceed the current number of workspaces." (defun exwm-workspace--set-desktop (id) "Set _NET_WM_DESKTOP for X window ID." (with-current-buffer (exwm--id->buffer id) - (xcb:+request exwm--connection - (make-instance 'xcb:ewmh:set-_NET_WM_DESKTOP - :window id - :data (exwm-workspace--position exwm--frame))))) + (let ((desktop (exwm-workspace--position exwm--frame))) + (setq exwm--desktop desktop) + (xcb:+request exwm--connection + (make-instance 'xcb:ewmh:set-_NET_WM_DESKTOP + :window id + :data desktop))))) ;;;###autoload (defun exwm-workspace-move-window (frame-or-index &optional id) diff --git a/exwm.el b/exwm.el index 3e445b2..5cba378 100644 --- a/exwm.el +++ b/exwm.el @@ -145,6 +145,32 @@ (while (= ?R (shell-command-on-region (point) (point) args)))) (kill-emacs)))))) +(defun exwm--update-desktop (xwin) + "Update _NET_WM_DESKTOP." + (with-current-buffer (exwm--id->buffer xwin) + (let ((reply (xcb:+request-unchecked+reply exwm--connection + (make-instance 'xcb:ewmh:get-_NET_WM_DESKTOP + :window xwin))) + desktop) + (when reply + (setq desktop (slot-value reply 'value)) + (cond + ((eq desktop #xffffffff) + (unless (or (not exwm--floating-frame) + (eq exwm--frame exwm-workspace--current) + (and exwm--desktop + (= desktop exwm--desktop))) + (exwm-layout--show xwin (frame-root-window exwm--floating-frame))) + (setq exwm--desktop desktop)) + ((and desktop + (< desktop (exwm-workspace--count)) + (if exwm--desktop + (/= desktop exwm--desktop) + (/= desktop (exwm-workspace--position exwm--frame)))) + (exwm-workspace-move-window desktop xwin)) + (t + (exwm-workspace--set-desktop xwin))))))) + (defun exwm--update-window-type (id &optional force) "Update _NET_WM_WINDOW_TYPE." (with-current-buffer (exwm--id->buffer id)