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'.
This commit is contained in:
Chris Feng 2018-02-19 22:34:03 +08:00
parent d22e6740d7
commit b8ce20b4f3
5 changed files with 38 additions and 18 deletions

View file

@ -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.")

View file

@ -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

View file

@ -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)

View file

@ -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)
(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 (exwm-workspace--position exwm--frame)))))
:data desktop)))))
;;;###autoload
(defun exwm-workspace-move-window (frame-or-index &optional id)

26
exwm.el
View file

@ -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)