diff --git a/exwm-core.el b/exwm-core.el index 226e7fc..0c92d90 100644 --- a/exwm-core.el +++ b/exwm-core.el @@ -87,7 +87,6 @@ (defvar-local exwm--frame nil) ;workspace frame (defvar-local exwm--floating-frame nil) ;floating frame (defvar-local exwm--mode-line-format nil) ;save mode-line-format -(defvar-local exwm--fullscreen nil) ;used in fullscreen (defvar-local exwm--floating-frame-position nil) ;used in fullscreen (defvar-local exwm--fixed-size nil) ;fixed size (defvar-local exwm--keyboard-grabbed nil) ;Keyboard grabbed. @@ -103,6 +102,7 @@ (defvar-local exwm-transient-for nil "WM_TRANSIENT_FOR.") (defvar-local exwm--protocols nil) (defvar-local exwm-state xcb:icccm:WM_STATE:NormalState "WM_STATE.") +(defvar-local exwm--ewmh-state nil "_NET_WM_STATE.") ;; _NET_WM_NORMAL_HINTS (defvar-local exwm--normal-hints-x nil) (defvar-local exwm--normal-hints-y nil) @@ -150,8 +150,10 @@ "*General*" "---" ["Toggle floating" exwm-floating-toggle-floating] - ["Enter fullscreen" exwm-layout-set-fullscreen (not exwm--fullscreen)] - ["Leave fullscreen" exwm-reset exwm--fullscreen] + ["Enter fullscreen" exwm-layout-set-fullscreen + (null (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state))] + ["Leave fullscreen" exwm-reset + (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)] ["Hide window" exwm-floating-hide exwm--floating-frame] "---" diff --git a/exwm-layout.el b/exwm-layout.el index f5e0e14..e8fd8e5 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -177,7 +177,7 @@ "Make window ID fullscreen." (interactive) (with-current-buffer (if id (exwm--id->buffer id) (window-buffer)) - (when exwm--fullscreen + (when (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) (user-error "Already in full-screen mode.")) ;; Save the position of floating frame. (when exwm--floating-frame @@ -221,7 +221,7 @@ :window exwm--id :data (vector xcb:Atom:_NET_WM_STATE_FULLSCREEN))) (xcb:flush exwm--connection) - (setq exwm--fullscreen t) + (cl-pushnew xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) (call-interactively #'exwm-input-release-keyboard))) ;;;###autoload @@ -229,7 +229,7 @@ "Restore window from fullscreen state." (interactive) (with-current-buffer (if id (exwm--id->buffer id) (window-buffer)) - (unless exwm--fullscreen + (unless (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) (user-error "Not in full-screen mode.")) ;; Restore the size of this workspace. (exwm-workspace--set-fullscreen exwm--frame) @@ -256,7 +256,8 @@ (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_WM_STATE :window exwm--id :data [])) (xcb:flush exwm--connection) - (setq exwm--fullscreen nil) + (setq exwm--ewmh-state + (delq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) (call-interactively #'exwm-input-grab-keyboard))) (defvar exwm-layout--other-buffer-exclude-exwm-mode-buffers nil diff --git a/exwm-manage.el b/exwm-manage.el index 60ff2e2..0f1a80b 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -48,6 +48,16 @@ corresponding buffer.") (when reply ;nil when destroyed (setq exwm--geometry reply)))))) +(defun exwm-manage--update-ewmh-state (id) + "Update _NET_WM_STATE." + (with-current-buffer (exwm--id->buffer id) + (unless exwm--ewmh-state + (let ((reply (xcb:+request-unchecked+reply exwm--connection + (make-instance 'xcb:ewmh:get-_NET_WM_STATE + :window id)))) + (when reply + (setq exwm--ewmh-state (append (slot-value reply 'value) nil))))))) + ;; The _MOTIF_WM_HINTS atom (see for more details) ;; It's currently only used in 'exwm-manage' module (defvar exwm-manage--_MOTIF_WM_HINTS nil "_MOTIF_WM_HINTS atom.") @@ -286,7 +296,12 @@ corresponding buffer.") (< desktop (exwm-workspace--count))) (exwm-workspace-move-window desktop id) (exwm-workspace--set-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) + (setq exwm--ewmh-state + (delq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) + (exwm-layout-set-fullscreen id)) (run-hooks 'exwm-manage-finish-hook))))) (defvar exwm-workspace--id-struts-alist) @@ -373,7 +388,7 @@ manager is shutting down." (make-instance 'xcb:ReparentWindow :window window :parent exwm--root :x 0 :y 0)))) ;; Restore the workspace if this X window is currently fullscreen. - (when exwm--fullscreen + (when (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) (exwm-workspace--set-fullscreen exwm--frame)) ;; Destroy the X window container (and the frame container if any). (xcb:+request exwm--connection @@ -552,7 +567,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d" border-width sibling stack-mode) (if (and (setq buffer (exwm--id->buffer window)) (with-current-buffer buffer - (or exwm--fullscreen + (or (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) ;; Make sure it's a floating X window wanting to resize ;; itself. (or (not exwm--floating-frame) @@ -578,7 +593,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d" ;; Send client message for managed windows (with-current-buffer buffer (setq edges - (if exwm--fullscreen + (if (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) (list 0 0 (exwm-workspace--current-width) (exwm-workspace--current-height)) diff --git a/exwm-workspace.el b/exwm-workspace.el index fec83d9..befa8e0 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -445,7 +445,9 @@ PREFIX-DIGITS is a list of the digits introduced so far." The optional FORCE option is for internal use only." (interactive (list - (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible + (unless (and (eq major-mode 'exwm-mode) + ;; The prompt is invisible in fullscreen mode. + (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) (let ((exwm-workspace--prompt-add-allowed t) (exwm-workspace--prompt-delete-allowed t)) (exwm-workspace--prompt-for-workspace "Switch to [+/-]: "))))) @@ -463,7 +465,8 @@ The optional FORCE option is for internal use only." :value-mask xcb:ConfigWindow:StackMode :stack-mode xcb:StackMode:Above)) ;; Raise X windows with struts set if there's no fullscreen X window. - (unless (buffer-local-value 'exwm--fullscreen (window-buffer window)) + (unless (with-current-buffer (window-buffer window) + (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) (dolist (pair exwm-workspace--id-struts-alist) (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow @@ -537,7 +540,9 @@ deleted, moved, etc).") (defun exwm-workspace-swap (workspace1 workspace2) "Interchange position of WORKSPACE1 with that of WORKSPACE2." (interactive - (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible + (unless (and (eq major-mode 'exwm-mode) + ;; The prompt is invisible in fullscreen mode. + (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) (let (w1 w2) (let ((exwm-workspace--prompt-add-allowed t) (exwm-workspace--prompt-delete-allowed t)) @@ -572,7 +577,9 @@ deleted, moved, etc).") When called interactively, prompt for a workspace and move current one just before it." (interactive - (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible + (unless (and (eq major-mode 'exwm-mode) + ;; The prompt is invisible in fullscreen mode. + (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state)) (list exwm-workspace--current (exwm-workspace--position (exwm-workspace--prompt-for-workspace "Move workspace to: "))))) diff --git a/exwm.el b/exwm.el index 0bc9701..0544308 100644 --- a/exwm.el +++ b/exwm.el @@ -78,7 +78,8 @@ (interactive) (with-current-buffer (window-buffer) (when (eq major-mode 'exwm-mode) - (when exwm--fullscreen (exwm-layout-unset-fullscreen)) + (when (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state) + (exwm-layout-unset-fullscreen)) ;; Force refresh (exwm-layout--refresh) (call-interactively #'exwm-input-grab-keyboard)))) @@ -464,12 +465,17 @@ (when (or (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN props) (memq xcb:Atom:_NET_WM_STATE_ABOVE props)) (cond ((= action xcb:ewmh:_NET_WM_STATE_ADD) - (unless exwm--fullscreen (exwm-layout-set-fullscreen id)) + (unless (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN + exwm--ewmh-state) + (exwm-layout-set-fullscreen id)) (push xcb:Atom:_NET_WM_STATE_FULLSCREEN props-new)) ((= action xcb:ewmh:_NET_WM_STATE_REMOVE) - (when exwm--fullscreen (exwm-layout-unset-fullscreen id))) + (when (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN + exwm--ewmh-state) + (exwm-layout-unset-fullscreen id))) ((= action xcb:ewmh:_NET_WM_STATE_TOGGLE) - (if exwm--fullscreen + (if (memq xcb:Atom:_NET_WM_STATE_FULLSCREEN + exwm--ewmh-state) (exwm-layout-unset-fullscreen id) (exwm-layout-set-fullscreen id) (push xcb:Atom:_NET_WM_STATE_FULLSCREEN props-new)))))