about summary refs log tree commit diff
path: root/exwm-layout.el
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2016-07-13T10·51+0800
committerChris Feng <chris.w.feng@gmail.com>2016-07-13T11·36+0800
commit6c8255bf3978a4df3d76ffd6f7d6bbdbba8bba19 (patch)
treed48859b6a960edfb29ab9e6f623b1401ad337500 /exwm-layout.el
parenteee5c6fa4dd776c1604e5ec7db34bc5401d8dea6 (diff)
Add/improve some ICCCM/EWMH features
* exwm-floating.el (exwm-floating--set-allowed-actions)
(exwm-floating--set-floating, exwm-floating--unset-floating):
Add _NET_WM_ALLOWED_ACTIONS support.

* exwm-floating.el (exwm-floating--set-floating)
(exwm-floating--unset-floating): Support initial state hint.
* exwm.el (exwm--update-hints): Fetch initial state.
(exwm--update-state, exwm--on-PropertyNotify):
WM_STATE is not intended to be read.
* exwm-core.el (exwm-state):
* exwm-floating.el (exwm-floating-hide):
* exwm-input.el (exwm-input--update-focus):
* exwm-layout.el (exwm-layout--set-state)
(exwm-layout--iconic-state-p, exwm-layout--show, exwm-layout--hide):
* exwm-manage.el (exwm-manage--on-MapRequest):
Improve WM_STATE support.

* exwm-input.el (exwm-input--set-focus):
* exwm-input.el (exwm-input--update-focus)
(exwm-input--set-active-window):
* exwm.el (exwm--on-ClientMessage): Add _NET_ACTIVE_WINDOW support.

* exwm-layout.el (exwm-layout--set-client-list-stacking):
Improve _NET_CLIENT_LIST_STACKING support.

* exwm-manage.el (exwm-manage--set-client-list)
(exwm-manage--manage-window, exwm-manage--unmanage-window):
Improve _NET_CLIENT_LIST support.

* exwm-manage.el (exwm-manage--manage-window):
* exwm-workspace.el (exwm-workspace--set-desktop)
(exwm-workspace-move-window):
* exwm.el (exwm--on-ClientMessage): Add _NET_WM_DESKTOP support.

* exwm-randr.el (exwm-randr--refresh):
* exwm-workspace.el (exwm-workspace--set-desktop-geometry)
(exwm-workspace--init): Add _NET_DESKTOP_GEOMETRY support.

* exwm-workspace.el (exwm-workspace--set-desktop-geometry):
Renamed from `exwm-workspace--update-desktop-geometry'.
* exwm-randr.el (exwm-randr--refresh): Improve _NET_WORKAREA support.

* exwm-workspace.el (exwm-workspace--set-fullscreen):
Correct variables names.

* exwm-workspace.el (exwm-workspace--init):
* exwm.el (exwm--init-icccm-ewmh):
Set _NET_NUMBER_OF_DESKTOPS in workspace module.

* exwm-workspace.el (exwm-workspace--init):
* exwm.el (exwm--init-icccm-ewmh):
Set _NET_DESKTOP_VIEWPORT in workspace module.

* exwm.el (exwm--on-ClientMessage): Improve _NET_CURRENT_DESKTOP
support.

* exwm.el (exwm--on-ClientMessage): Add _NET_CLOSE_WINDOW support.

* exwm.el (exwm--on-ClientMessage): Add WM_CHANGE_STATE support.

* exwm.el (exwm--init-icccm-ewmh): Update supported atoms.
Diffstat (limited to 'exwm-layout.el')
-rw-r--r--exwm-layout.el68
1 files changed, 43 insertions, 25 deletions
diff --git a/exwm-layout.el b/exwm-layout.el
index 2d85580085..259788f66c 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -50,6 +50,20 @@
                                              xcb:ConfigWindow:Height))
                        :width width :height height))))
 
+(defun exwm-layout--set-state (id state)
+  "Set WM_STATE."
+  (xcb:+request exwm--connection
+      (make-instance 'xcb:icccm:set-WM_STATE
+                     :window id :state state :icon xcb:Window:None))
+  (with-current-buffer (exwm--id->buffer id)
+    (setq exwm-state state)))
+
+(defun exwm-layout--iconic-state-p (&optional id)
+  (= xcb:icccm:WM_STATE:IconicState
+     (if id
+         (buffer-local-value 'exwm-state (exwm--id->buffer id))
+       exwm-state)))
+
 (defun exwm-layout--show (id &optional window)
   "Show window ID exactly fit in the Emacs window WINDOW."
   (exwm--log "Show #x%x in %s" id window)
@@ -101,11 +115,7 @@
       (xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id))
       (xcb:+request exwm--connection
           (make-instance 'xcb:MapWindow :window exwm--container))
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:icccm:set-WM_STATE
-                         :window id :state xcb:icccm:WM_STATE:NormalState
-                         :icon xcb:Window:None))
-      (setq exwm-state xcb:icccm:WM_STATE:NormalState))
+      (exwm-layout--set-state id xcb:icccm:WM_STATE:NormalState))
     (xcb:+request exwm--connection
         (make-instance 'xcb:SendEvent
                        :propagate 0 :destination id
@@ -125,25 +135,21 @@
 (defun exwm-layout--hide (id)
   "Hide window ID."
   (with-current-buffer (exwm--id->buffer id)
-    (unless (eq xcb:icccm:WM_STATE:IconicState exwm-state) ;already hidden
+    (unless (exwm-layout--iconic-state-p) ;already hidden
       (exwm--log "Hide #x%x" id)
       (xcb:+request exwm--connection
           (make-instance 'xcb:ChangeWindowAttributes
                          :window id :value-mask xcb:CW:EventMask
                          :event-mask xcb:EventMask:NoEvent))
-      (xcb:+request exwm--connection (make-instance 'xcb:UnmapWindow :window id))
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:UnmapWindow :window id))
       (xcb:+request exwm--connection
           (make-instance 'xcb:ChangeWindowAttributes
                          :window id :value-mask xcb:CW:EventMask
                          :event-mask exwm--client-event-mask))
       (xcb:+request exwm--connection
           (make-instance 'xcb:UnmapWindow :window exwm--container))
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:icccm:set-WM_STATE
-                         :window id
-                         :state xcb:icccm:WM_STATE:IconicState
-                         :icon xcb:Window:None))
-      (setq exwm-state xcb:icccm:WM_STATE:IconicState)
+      (exwm-layout--set-state id xcb:icccm:WM_STATE:IconicState)
       (xcb:flush exwm--connection))))
 
 (defvar exwm-workspace--current)
@@ -243,6 +249,29 @@ selected by `other-buffer'."
 (defvar exwm-layout-show-all-buffers nil
   "Non-nil to allow switching to buffers on other workspaces.")
 
+(defun exwm-layout--set-client-list-stacking ()
+  "Set _NET_CLIENT_LIST_STACKING."
+  (let (id clients-floating clients clients-iconic clients-other)
+    (dolist (pair exwm--id-buffer-alist)
+      (setq id (car pair))
+      (with-current-buffer (cdr pair)
+        (if (eq exwm--frame exwm-workspace--current)
+            (if exwm--floating-frame
+                ;; A floating X window on the current workspace.
+                (setq clients-floating (cons id clients-floating))
+              (if (get-buffer-window (cdr pair) exwm-workspace--current)
+                  ;; A normal tilling X window on the current workspace.
+                  (setq clients (cons id clients))
+                ;; An iconic tilling X window on the current workspace.
+                (setq clients-iconic (cons id clients-iconic))))
+          ;; X window on other workspaces.
+          (setq clients-other (cons id clients-other)))))
+    (xcb:+request exwm--connection
+        (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST_STACKING
+                       :window exwm--root
+                       :data (vconcat (append clients-other clients-iconic
+                                             clients clients-floating))))))
+
 (defun exwm-layout--refresh ()
   "Refresh layout."
   (let ((frame (selected-frame))
@@ -310,18 +339,7 @@ selected by `other-buffer'."
             (when (and (eq major-mode 'exwm-mode)
                        (or exwm--floating-frame (not (eq frame exwm--frame))))
               (switch-to-prev-buffer window)))))
-      ;; Update _NET_CLIENT_LIST_STACKING
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST_STACKING
-                         :window exwm--root
-                         :data (vconcat
-                                (delq nil
-                                      (mapcar
-                                       (lambda (buffer)
-                                         (with-current-buffer buffer
-                                           (when (eq major-mode 'exwm-mode)
-                                             exwm--id)))
-                                       (buffer-list))))))
+      (exwm-layout--set-client-list-stacking)
       (xcb:flush exwm--connection))))
 
 (defun exwm-layout--on-minibuffer-setup ()