about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--exwm-input.el6
-rw-r--r--exwm-manage.el5
-rw-r--r--exwm-systemtray.el5
-rw-r--r--exwm-workspace.el65
-rw-r--r--exwm.el49
5 files changed, 87 insertions, 43 deletions
diff --git a/exwm-input.el b/exwm-input.el
index f7a67040d60a..555cc87f9fa5 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -659,7 +659,11 @@ Its usage is the same with `exwm-input-set-simulation-keys'."
   (remove-hook 'post-command-hook #'exwm-input--on-post-command)
   (remove-hook 'buffer-list-update-hook #'exwm-input--on-buffer-list-update)
   (remove-hook 'exwm-workspace-list-change-hook
-               #'exwm-input--update-global-prefix-keys))
+               #'exwm-input--update-global-prefix-keys)
+  (when exwm-input--update-focus-defer-timer
+    (cancel-timer exwm-input--update-focus-defer-timer))
+  (when exwm-input--update-focus-timer
+    (cancel-timer exwm-input--update-focus-timer)))
 
 
 
diff --git a/exwm-manage.el b/exwm-manage.el
index 16abe9845bc3..0b7b475590b3 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -112,6 +112,11 @@ corresponding buffer.")
                              :window id :value-mask xcb:CW:EventMask
                              :event-mask exwm--client-event-mask))
       (throw 'return 'dead))
+    ;; Add this X window to save-set.
+    (xcb:+request exwm--connection
+        (make-instance 'xcb:ChangeSaveSet
+                       :mode xcb:SetMode:Insert
+                       :window id))
     (with-current-buffer (generate-new-buffer "*EXWM*")
       ;; Keep the oldest X window first.
       (setq exwm--id-buffer-alist
diff --git a/exwm-systemtray.el b/exwm-systemtray.el
index 56e5fb8eb728..25f5fa584c4a 100644
--- a/exwm-systemtray.el
+++ b/exwm-systemtray.el
@@ -89,6 +89,11 @@ You shall use the default value if using auto-hide minibuffer.")
                 height* (round (* height (/ (float width*) width)))))
         (exwm--log "(System Tray) Resize from %dx%d to %dx%d"
                    width height width* height*))
+      ;; Add this icon to save-set.
+      (xcb:+request exwm-systemtray--connection
+          (make-instance 'xcb:ChangeSaveSet
+                         :mode xcb:SetMode:Insert
+                         :window icon))
       ;; Reparent to the embedder.
       (xcb:+request exwm-systemtray--connection
           (make-instance 'xcb:ReparentWindow
diff --git a/exwm-workspace.el b/exwm-workspace.el
index ce2ed6f6454a..b73059ab4d19 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -1045,47 +1045,46 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
           (0 (y-or-n-p prompt))
           (x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s"
                                   x (if (= x 1) "" "s") prompt))))
-    ;; Unmanage all X windows.
-    (dolist (i exwm--id-buffer-alist)
-      (exwm-manage--unmanage-window (car i) 'quit)
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:MapWindow :window (car i))))
-    ;; Reparent out the minibuffer frame.
+    ;; Hide & reparent out all frames (save-set can't be used here since
+    ;; X windows will be re-mapped).
     (when (exwm-workspace--minibuffer-own-frame-p)
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:ReparentWindow
-                         :window (frame-parameter exwm-workspace--minibuffer
-                                                  'exwm-outer-id)
-                         :parent exwm--root
-                         :x 0
-                         :y 0)))
-    ;; Reparent out all workspace frames.
+      (let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id)))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:UnmapWindow
+                           :window id))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ReparentWindow
+                           :window id
+                           :parent exwm--root
+                           :x 0
+                           :y 0))))
     (dolist (f exwm-workspace--list)
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:ReparentWindow
-                         :window (frame-parameter f 'exwm-outer-id)
-                         :parent exwm--root
-                         :x 0
-                         :y 0)))
-    (xcb:flush exwm--connection)
-    (if (not exwm-workspace--client)
-        (progn
-          ;; Destroy all resources created by this connection.
-          (xcb:disconnect exwm--connection)
-          t)
-      ;; Extra cleanups for emacsclient.
+      (let ((id (frame-parameter f 'exwm-outer-id)))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:UnmapWindow
+                           :window id))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ReparentWindow
+                           :window id
+                           :parent exwm--root
+                           :x 0
+                           :y 0))))
+    ;; Exit each module.
+    (exwm--exit)
+    ;; Destroy all resources created by this connection.
+    (xcb:disconnect exwm--connection)
+    (setq exwm--connection nil)
+    ;; Extra cleanups for emacsclient.
+    (when exwm-workspace--client
       (dolist (f exwm-workspace--list)
         (set-frame-parameter f 'client exwm-workspace--client))
       (when (exwm-workspace--minibuffer-own-frame-p)
         (set-frame-parameter exwm-workspace--minibuffer 'client
                              exwm-workspace--client))
-      (let ((connection exwm--connection))
-        (exwm--exit)
-        ;; Destroy all resources created by this connection.
-        (xcb:disconnect connection))
       ;; Kill the client.
-      (server-save-buffers-kill-terminal nil)
-      nil)))
+      (server-save-buffers-kill-terminal nil))
+    ;; Set the return value.
+    (not exwm-workspace--client)))
 
 (defun exwm-workspace--set-desktop-geometry ()
   "Set _NET_DESKTOP_GEOMETRY."
diff --git a/exwm.el b/exwm.el
index 692c863559d2..b04990b32946 100644
--- a/exwm.el
+++ b/exwm.el
@@ -83,6 +83,20 @@
       (exwm-layout--refresh)
       (call-interactively #'exwm-input-grab-keyboard))))
 
+;;;###autoload
+(defun exwm-restart ()
+  "Restart EXWM."
+  (interactive)
+  (when (exwm-workspace--confirm-kill-emacs "[EXWM] Restart? ")
+    (server-force-delete)
+    (run-hooks 'kill-emacs-hook)
+    ;; FIXME: more?
+    (apply #'call-process (car command-line-args) nil nil nil
+           (cdr command-line-args))
+    ;; Kill this instance at last.
+    (let ((kill-emacs-hook nil))
+      (kill-emacs))))
+
 (defun exwm--update-window-type (id &optional force)
   "Update _NET_WM_WINDOW_TYPE."
   (with-current-buffer (exwm--id->buffer id)
@@ -597,6 +611,30 @@
                          :window i :data "EXWM"))))
   (xcb:flush exwm--connection))
 
+(defun exwm--exit-icccm-ewmh ()
+  "Remove ICCCM/EWMH properties."
+  (dolist (p (list
+              xcb:Atom:_NET_WM_NAME
+              xcb:Atom:_NET_SUPPORTED
+              xcb:Atom:_NET_CLIENT_LIST
+              xcb:Atom:_NET_CLIENT_LIST_STACKING
+              xcb:Atom:_NET_NUMBER_OF_DESKTOPS
+              xcb:Atom:_NET_DESKTOP_GEOMETRY
+              xcb:Atom:_NET_DESKTOP_VIEWPORT
+              xcb:Atom:_NET_CURRENT_DESKTOP
+              xcb:Atom:_NET_ACTIVE_WINDOW
+              xcb:Atom:_NET_WORKAREA
+              xcb:Atom:_NET_SUPPORTING_WM_CHECK
+              xcb:Atom:_NET_VIRTUAL_ROOTS
+              ;; TODO: Keep this list synchronized with that in
+              ;;       `exwm--init-icccm-ewmh'.
+              ))
+    (xcb:+request exwm--connection
+        (make-instance 'xcb:DeleteProperty
+                       :window exwm--root
+                       :property p))
+    (xcb:flush exwm--connection)))
+
 (defvar exwm-init-hook nil
   "Normal hook run when EXWM has just finished initialization.")
 
@@ -643,10 +681,7 @@
         (exwm-manage--scan)
         (run-hooks 'exwm-init-hook)))))
 
-(defvar exwm-exit-hook nil
-  "Normal hook run just before EXWM is about to exit.
-
-This hook is only run when EXWM is started with emacsclient.")
+(defvar exwm-exit-hook nil "Normal hook run just before EXWM exits.")
 
 (defun exwm--exit ()
   "Exit EXWM."
@@ -657,11 +692,7 @@ This hook is only run when EXWM is started with emacsclient.")
   (exwm-manage--exit)
   (exwm-floating--exit)
   (exwm-layout--exit)
-  ;; Reset several import variables.
-  (setq exwm--connection nil
-        exwm--root nil
-        exwm--id-buffer-alist nil)
-  (exwm-enable))
+  (exwm--exit-icccm-ewmh))
 
 (defvar exwm-blocking-subrs '(x-file-dialog x-popup-dialog x-select-font)
   "Subrs (primitives) that would normally block EXWM.")