Add restart support

* exwm-input.el (exwm-input--exit): Cancel timers.

* exwm-manage.el (exwm-manage--manage-window): Add reparented X windows
to save-set.
* exwm-systemtray.el (exwm-systemtray--embed): Add embeded icons to
save-set.

* exwm-workspace.el (exwm-workspace--confirm-kill-emacs): No need to
unmanage; also hide Emacs frames; always call `exwm--exit'.

* exwm.el (exwm-restart): New command for restarting EXWM.
(exwm--exit-icccm-ewmh): New function for cleaning up ICCCM/EWMH
properties.
(exwm-exit-hook): Update doc string.
(exwm--exit): Call `exwm--exit-icccm-ewmh' and do not reset variables.
This commit is contained in:
Chris Feng 2016-07-30 19:01:33 +08:00
parent b87f4fbd71
commit 1e78045f95
5 changed files with 87 additions and 43 deletions

View file

@ -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 'post-command-hook #'exwm-input--on-post-command)
(remove-hook 'buffer-list-update-hook #'exwm-input--on-buffer-list-update) (remove-hook 'buffer-list-update-hook #'exwm-input--on-buffer-list-update)
(remove-hook 'exwm-workspace-list-change-hook (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)))

View file

@ -112,6 +112,11 @@ corresponding buffer.")
:window id :value-mask xcb:CW:EventMask :window id :value-mask xcb:CW:EventMask
:event-mask exwm--client-event-mask)) :event-mask exwm--client-event-mask))
(throw 'return 'dead)) (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*") (with-current-buffer (generate-new-buffer "*EXWM*")
;; Keep the oldest X window first. ;; Keep the oldest X window first.
(setq exwm--id-buffer-alist (setq exwm--id-buffer-alist

View file

@ -89,6 +89,11 @@ You shall use the default value if using auto-hide minibuffer.")
height* (round (* height (/ (float width*) width))))) height* (round (* height (/ (float width*) width)))))
(exwm--log "(System Tray) Resize from %dx%d to %dx%d" (exwm--log "(System Tray) Resize from %dx%d to %dx%d"
width height width* height*)) 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. ;; Reparent to the embedder.
(xcb:+request exwm-systemtray--connection (xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ReparentWindow (make-instance 'xcb:ReparentWindow

View file

@ -1045,47 +1045,46 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(0 (y-or-n-p prompt)) (0 (y-or-n-p prompt))
(x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s" (x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s"
x (if (= x 1) "" "s") prompt)))) x (if (= x 1) "" "s") prompt))))
;; Unmanage all X windows. ;; Hide & reparent out all frames (save-set can't be used here since
(dolist (i exwm--id-buffer-alist) ;; X windows will be re-mapped).
(exwm-manage--unmanage-window (car i) 'quit)
(xcb:+request exwm--connection
(make-instance 'xcb:MapWindow :window (car i))))
;; Reparent out the minibuffer frame.
(when (exwm-workspace--minibuffer-own-frame-p) (when (exwm-workspace--minibuffer-own-frame-p)
(xcb:+request exwm--connection (let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id)))
(make-instance 'xcb:ReparentWindow (xcb:+request exwm--connection
:window (frame-parameter exwm-workspace--minibuffer (make-instance 'xcb:UnmapWindow
'exwm-outer-id) :window id))
:parent exwm--root (xcb:+request exwm--connection
:x 0 (make-instance 'xcb:ReparentWindow
:y 0))) :window id
;; Reparent out all workspace frames. :parent exwm--root
:x 0
:y 0))))
(dolist (f exwm-workspace--list) (dolist (f exwm-workspace--list)
(xcb:+request exwm--connection (let ((id (frame-parameter f 'exwm-outer-id)))
(make-instance 'xcb:ReparentWindow (xcb:+request exwm--connection
:window (frame-parameter f 'exwm-outer-id) (make-instance 'xcb:UnmapWindow
:parent exwm--root :window id))
:x 0 (xcb:+request exwm--connection
:y 0))) (make-instance 'xcb:ReparentWindow
(xcb:flush exwm--connection) :window id
(if (not exwm-workspace--client) :parent exwm--root
(progn :x 0
;; Destroy all resources created by this connection. :y 0))))
(xcb:disconnect exwm--connection) ;; Exit each module.
t) (exwm--exit)
;; Extra cleanups for emacsclient. ;; 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) (dolist (f exwm-workspace--list)
(set-frame-parameter f 'client exwm-workspace--client)) (set-frame-parameter f 'client exwm-workspace--client))
(when (exwm-workspace--minibuffer-own-frame-p) (when (exwm-workspace--minibuffer-own-frame-p)
(set-frame-parameter exwm-workspace--minibuffer 'client (set-frame-parameter exwm-workspace--minibuffer 'client
exwm-workspace--client)) exwm-workspace--client))
(let ((connection exwm--connection))
(exwm--exit)
;; Destroy all resources created by this connection.
(xcb:disconnect connection))
;; Kill the client. ;; Kill the client.
(server-save-buffers-kill-terminal nil) (server-save-buffers-kill-terminal nil))
nil))) ;; Set the return value.
(not exwm-workspace--client)))
(defun exwm-workspace--set-desktop-geometry () (defun exwm-workspace--set-desktop-geometry ()
"Set _NET_DESKTOP_GEOMETRY." "Set _NET_DESKTOP_GEOMETRY."

49
exwm.el
View file

@ -83,6 +83,20 @@
(exwm-layout--refresh) (exwm-layout--refresh)
(call-interactively #'exwm-input-grab-keyboard)))) (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) (defun exwm--update-window-type (id &optional force)
"Update _NET_WM_WINDOW_TYPE." "Update _NET_WM_WINDOW_TYPE."
(with-current-buffer (exwm--id->buffer id) (with-current-buffer (exwm--id->buffer id)
@ -597,6 +611,30 @@
:window i :data "EXWM")))) :window i :data "EXWM"))))
(xcb:flush exwm--connection)) (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 (defvar exwm-init-hook nil
"Normal hook run when EXWM has just finished initialization.") "Normal hook run when EXWM has just finished initialization.")
@ -643,10 +681,7 @@
(exwm-manage--scan) (exwm-manage--scan)
(run-hooks 'exwm-init-hook))))) (run-hooks 'exwm-init-hook)))))
(defvar exwm-exit-hook nil (defvar exwm-exit-hook nil "Normal hook run just before EXWM exits.")
"Normal hook run just before EXWM is about to exit.
This hook is only run when EXWM is started with emacsclient.")
(defun exwm--exit () (defun exwm--exit ()
"Exit EXWM." "Exit EXWM."
@ -657,11 +692,7 @@ This hook is only run when EXWM is started with emacsclient.")
(exwm-manage--exit) (exwm-manage--exit)
(exwm-floating--exit) (exwm-floating--exit)
(exwm-layout--exit) (exwm-layout--exit)
;; Reset several import variables. (exwm--exit-icccm-ewmh))
(setq exwm--connection nil
exwm--root nil
exwm--id-buffer-alist nil)
(exwm-enable))
(defvar exwm-blocking-subrs '(x-file-dialog x-popup-dialog x-select-font) (defvar exwm-blocking-subrs '(x-file-dialog x-popup-dialog x-select-font)
"Subrs (primitives) that would normally block EXWM.") "Subrs (primitives) that would normally block EXWM.")