Cleanup exwm-workspace on exit

* exwm-workspace.el (exwm-workspace--confirm-kill-emacs): Move
deinitialization to `exwm-workspace--exit'.
(exwm-workspace--exit): Reparent minibuffer frame to the root
window, turn workspace frames into regular frames, restore frame
parameters.
(exwm-workspace--init): Reset the fullscreen counter.
(exwm-workspace--remove-frame-as-workspace): Reset fullscreen
state.
(exwm-workspace--init-minibuffer-frame)
(exwm-workspace--exit-minibuffer-frame): New functions configuring
the minibuffer frame.
(exwm-workspace--init, exwm-workspace--exit): Use the above
functions to configure the minibuffer frame.
This commit is contained in:
Adrián Medraño Calvo 2018-03-06 00:00:00 +00:00
parent 33a1a28476
commit a51be88c1e

View file

@ -1207,37 +1207,6 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(setq kill-emacs-hook (list #'server-force-stop))) (setq kill-emacs-hook (list #'server-force-stop)))
(run-hooks 'kill-emacs-hook) (run-hooks 'kill-emacs-hook)
(setq kill-emacs-hook nil)) (setq kill-emacs-hook nil))
;; 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)
(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)
(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))))
;; Restore the 'client' frame parameter (before `exwm--exit').
(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)))
;; Exit each module. ;; Exit each module.
(exwm--exit) (exwm--exit)
;; Destroy all resources created by this connection. ;; Destroy all resources created by this connection.
@ -1361,6 +1330,11 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
:window outer-id :window outer-id
:value-mask xcb:CW:OverrideRedirect :value-mask xcb:CW:OverrideRedirect
:override-redirect 0)) :override-redirect 0))
;; Remove fullscreen state.
(xcb:+request exwm--connection
(make-instance 'xcb:ewmh:set-_NET_WM_STATE
:window outer-id
:data nil))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:MapWindow (make-instance 'xcb:MapWindow
:window outer-id))) :window outer-id)))
@ -1451,42 +1425,13 @@ applied to all subsequently created X frames."
"Replacement for `handle-focus-out'." "Replacement for `handle-focus-out'."
(interactive "e")) (interactive "e"))
(defun exwm-workspace--init () (defun exwm-workspace--init-minibuffer-frame ()
"Initialize workspace module."
;; Prevent unexpected exit
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
(exwm-workspace--modify-all-x-frames-parameters
'((internal-border-width . 0)))
(let ((initial-workspaces (frame-list)))
(if (not (exwm-workspace--minibuffer-own-frame-p))
;; Initialize workspaces with minibuffers.
(when (< 1 (length initial-workspaces))
;; Exclude the initial frame.
(dolist (i initial-workspaces)
(unless (frame-parameter i 'window-id)
(setq initial-workspaces (delq i initial-workspaces))))
(setq exwm-workspace--client
(frame-parameter (car initial-workspaces) 'client))
(let ((f (car initial-workspaces)))
;; Remove the possible internal border.
(set-frame-parameter f 'internal-border-width 0)
;; Prevent user from deleting the first frame by accident.
(set-frame-parameter f 'client nil)))
;; Initialize workspaces without minibuffers. ;; Initialize workspaces without minibuffers.
(setq exwm-workspace--minibuffer (setq exwm-workspace--minibuffer
(make-frame '((window-system . x) (minibuffer . only) (make-frame '((window-system . x) (minibuffer . only)
(left . 10000) (right . 10000) (left . 10000) (right . 10000)
(width . 1) (height . 1) (width . 1) (height . 1)
(client . nil)))) (client . nil))))
;; Remove/hide existing frames.
(dolist (f initial-workspaces)
(if (frame-parameter f 'client)
(progn
(unless exwm-workspace--client
(setq exwm-workspace--client (frame-parameter f 'client)))
(make-frame-invisible f))
(when (eq 'x (framep f)) ;do not delete the initial frame.
(delete-frame f))))
;; This is the only usable minibuffer frame. ;; This is the only usable minibuffer frame.
(setq default-minibuffer-frame exwm-workspace--minibuffer) (setq default-minibuffer-frame exwm-workspace--minibuffer)
(exwm-workspace--modify-all-x-frames-parameters (exwm-workspace--modify-all-x-frames-parameters
@ -1546,13 +1491,73 @@ applied to all subsequently created X frames."
(setq exwm-workspace--timer (setq exwm-workspace--timer
(run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty)) (run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty))
(add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear) (add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
;; Recreate one frame with the external minibuffer set.
(setq initial-workspaces (list (make-frame '((window-system . x)
(client . nil)))))
;; The default behavior of `display-buffer' (indirectly called by ;; The default behavior of `display-buffer' (indirectly called by
;; `minibuffer-completion-help') is not correct here. ;; `minibuffer-completion-help') is not correct here.
(cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist (cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist
:test #'equal)) :test #'equal))
(defun exwm-workspace--exit-minibuffer-frame ()
;; Only on minibuffer-frame.
(remove-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
(remove-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
(remove-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
(when exwm-workspace--timer
(cancel-timer exwm-workspace--timer)
(setq exwm-workspace--timer nil))
(setq display-buffer-alist
(cl-delete '(exwm-workspace--display-buffer) display-buffer-alist
:test #'equal))
(setq default-minibuffer-frame nil)
(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))
(xcb:+request exwm--connection
(make-instance 'xcb:MapWindow
:window id)))
(setq exwm-workspace--minibuffer nil))
(defun exwm-workspace--init ()
"Initialize workspace module."
;; Prevent unexpected exit
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
(setq exwm-workspace--fullscreen-frame-count 0)
(exwm-workspace--modify-all-x-frames-parameters
'((internal-border-width . 0)))
(let ((initial-workspaces (frame-list)))
(if (not (exwm-workspace--minibuffer-own-frame-p))
;; Initialize workspaces with minibuffers.
(when (< 1 (length initial-workspaces))
;; Exclude the initial frame.
(dolist (i initial-workspaces)
(unless (frame-parameter i 'window-id)
(setq initial-workspaces (delq i initial-workspaces))))
(setq exwm-workspace--client
(frame-parameter (car initial-workspaces) 'client))
(let ((f (car initial-workspaces)))
;; Remove the possible internal border.
(set-frame-parameter f 'internal-border-width 0)
;; Prevent user from deleting the first frame by accident.
(set-frame-parameter f 'client nil)))
(exwm-workspace--init-minibuffer-frame)
;; Remove/hide existing frames.
(dolist (f initial-workspaces)
(if (frame-parameter f 'client)
(progn
(unless exwm-workspace--client
(setq exwm-workspace--client (frame-parameter f 'client)))
(make-frame-invisible f))
(when (eq 'x (framep f)) ;do not delete the initial frame.
(delete-frame f))))
;; Recreate one frame with the external minibuffer set.
(setq initial-workspaces (list (make-frame '((window-system . x)
(client . nil))))))
;; Prevent `other-buffer' from selecting already displayed EXWM buffers. ;; Prevent `other-buffer' from selecting already displayed EXWM buffers.
(modify-all-frames-parameters (modify-all-frames-parameters
'((buffer-predicate . exwm-layout--other-buffer-predicate))) '((buffer-predicate . exwm-layout--other-buffer-predicate)))
@ -1586,28 +1591,38 @@ applied to all subsequently created X frames."
(defun exwm-workspace--exit () (defun exwm-workspace--exit ()
"Exit the workspace module." "Exit the workspace module."
(setq confirm-kill-emacs nil (setq confirm-kill-emacs nil)
exwm-workspace--list nil (when (exwm-workspace--minibuffer-own-frame-p)
exwm-workspace--client nil (exwm-workspace--exit-minibuffer-frame))
exwm-workspace--minibuffer nil
exwm-workspace--fullscreen-frame-count 0
default-minibuffer-frame nil)
(remove-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
(remove-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
(when exwm-workspace--timer
(cancel-timer exwm-workspace--timer)
(setq exwm-workspace--timer nil))
(remove-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
(setq display-buffer-alist
(cl-delete '(exwm-workspace--display-buffer) display-buffer-alist
:test #'equal))
(advice-remove 'x-create-frame #'exwm-workspace--x-create-frame) (advice-remove 'x-create-frame #'exwm-workspace--x-create-frame)
(advice-remove 'handle-focus-in #'exwm-workspace--handle-focus-in) (advice-remove 'handle-focus-in #'exwm-workspace--handle-focus-in)
(advice-remove 'handle-focus-out #'exwm-workspace--handle-focus-out) (advice-remove 'handle-focus-out #'exwm-workspace--handle-focus-out)
(remove-hook 'after-make-frame-functions (remove-hook 'after-make-frame-functions
#'exwm-workspace--on-after-make-frame) #'exwm-workspace--on-after-make-frame)
(remove-hook 'delete-frame-functions (remove-hook 'delete-frame-functions
#'exwm-workspace--on-delete-frame)) #'exwm-workspace--on-delete-frame)
;; Hide & reparent out all frames (save-set can't be used here since
;; X windows will be re-mapped).
(setq exwm-workspace--current nil)
(dolist (i exwm-workspace--list)
(exwm-workspace--remove-frame-as-workspace i)
(modify-frame-parameters i '((exwm-selected-window . nil)
(exwm-urgency . nil)
(exwm-outer-id . nil)
(exwm-id . nil)
(exwm-container . nil)
;; (internal-border-width . nil) ; integerp
;; (client . nil)
(fullscreen . nil)
(buffer-predicate . nil))))
;; Restore the 'client' frame parameter (before `exwm--exit').
(when exwm-workspace--client
(dolist (f exwm-workspace--list)
(set-frame-parameter f 'client exwm-workspace--client))
(when (exwm-workspace--own-frame-p)
(set-frame-parameter exwm-workspace--minibuffer 'client
exwm-workspace--client))
(setq exwm-workspace--client nil)))
(defun exwm-workspace--post-init () (defun exwm-workspace--post-init ()
"The second stage in the initialization of the workspace module." "The second stage in the initialization of the workspace module."