about summary refs log tree commit diff
path: root/exwm-manage.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-manage.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-manage.el')
-rw-r--r--exwm-manage.el46
1 files changed, 34 insertions, 12 deletions
diff --git a/exwm-manage.el b/exwm-manage.el
index 924103e535..d4b3de48f9 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -68,8 +68,16 @@ corresponding buffer.")
                           (elt value 2))) ;MotifWmHints.decorations
               (setq exwm--mwm-hints-decorations nil))))))))
 
+(defun exwm-manage--set-client-list ()
+  "Set _NET_CLIENT_LIST."
+  (xcb:+request exwm--connection
+      (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
+                     :window exwm--root
+                     :data (vconcat (mapcar #'car exwm--id-buffer-alist)))))
+
 (defvar exwm-workspace--current)
 (defvar exwm-workspace--switch-history-outdated)
+(defvar exwm-workspace-current-index)
 
 (declare-function exwm--update-window-type "exwm.el" (id &optional force))
 (declare-function exwm--update-class "exwm.el" (id &optional force))
@@ -78,10 +86,10 @@ corresponding buffer.")
 (declare-function exwm--update-title "exwm.el" (id))
 (declare-function exwm--update-hints "exwm.el" (id &optional force))
 (declare-function exwm--update-protocols "exwm.el" (id &optional force))
-(declare-function exwm--update-state "exwm.el" (id &optional force))
 (declare-function exwm--update-strut "exwm.el" (id))
 (declare-function exwm-floating--set-floating "exwm-floating.el" (id))
 (declare-function exwm-floating--unset-floating "exwm-floating.el" (id))
+(declare-function exwm-workspace--set-desktop "exwm-workspace.el" (id))
 
 (defun exwm-manage--manage-window (id)
   "Manage window ID."
@@ -94,7 +102,9 @@ corresponding buffer.")
                              :event-mask exwm--client-event-mask))
       (throw 'return 'dead))
     (with-current-buffer (generate-new-buffer "*EXWM*")
-      (push `(,id . ,(current-buffer)) exwm--id-buffer-alist)
+      ;; Keep the oldest X window first.
+      (setq exwm--id-buffer-alist
+            (nconc exwm--id-buffer-alist `((,id . ,(current-buffer)))))
       (exwm-mode)
       (setq exwm--id id)
       (exwm--update-window-type id)
@@ -213,14 +223,10 @@ corresponding buffer.")
                            :keyboard-mode xcb:GrabMode:Async
                            :confine-to xcb:Window:None :cursor xcb:Cursor:None
                            :button button :modifiers xcb:ModMask:Any)))
-      (xcb:+request exwm--connection    ;update _NET_CLIENT_LIST
-          (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
-                         :window exwm--root
-                         :data (vconcat (mapcar #'car exwm--id-buffer-alist))))
+      (exwm-manage--set-client-list)
       (xcb:flush exwm--connection)
       (exwm--update-title id)
       (exwm--update-protocols id)
-      (exwm--update-state id)
       (if (or exwm-transient-for exwm--fixed-size
               (memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY exwm-window-type)
               (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG exwm-window-type))
@@ -228,6 +234,16 @@ corresponding buffer.")
         (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))
+            (exwm-workspace-move-window desktop id)
+          (exwm-workspace--set-desktop id)))
       (with-current-buffer (exwm--id->buffer id)
         (run-hooks 'exwm-manage-finish-hook)))))
 
@@ -297,10 +313,7 @@ corresponding buffer.")
           (when floating
             (select-window
              (frame-selected-window exwm-workspace--current)))))
-      (xcb:+request exwm--connection    ;update _NET_CLIENT_LIST
-          (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
-                         :window exwm--root
-                         :data (vconcat (mapcar #'car exwm--id-buffer-alist))))
+      (exwm-manage--set-client-list)
       (xcb:flush exwm--connection))))
 
 (defun exwm-manage--scan ()
@@ -523,13 +536,22 @@ border-width: %d; sibling: #x%x; stack-mode: %d"
                              :stack-mode stack-mode))))))
   (xcb:flush exwm--connection))
 
+(declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id))
+
 (defun exwm-manage--on-MapRequest (data _synthetic)
   "Handle MapRequest event."
   (let ((obj (make-instance 'xcb:MapRequest)))
     (xcb:unmarshal obj data)
     (with-slots (parent window) obj
       (if (assoc window exwm--id-buffer-alist)
-          (exwm--log "#x%x is already managed" window)
+          (with-current-buffer (exwm--id->buffer window)
+            (if (exwm-layout--iconic-state-p)
+                ;; State change: iconic => normal.
+                (when (eq exwm--frame exwm-workspace--current)
+                  (set-window-buffer (frame-selected-window exwm--frame)
+                                     (current-buffer))
+                  (select-window (frame-selected-window exwm--frame)))
+              (exwm--log "#x%x is already managed" window)))
         (if (/= exwm--root parent)
             (progn (xcb:+request exwm--connection
                        (make-instance 'xcb:MapWindow :window window))