mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-23 21:17:59 +01:00
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:
parent
33a1a28476
commit
a51be88c1e
1 changed files with 132 additions and 117 deletions
|
@ -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,10 +1425,109 @@ 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-minibuffer-frame ()
|
||||||
|
;; Initialize workspaces without minibuffers.
|
||||||
|
(setq exwm-workspace--minibuffer
|
||||||
|
(make-frame '((window-system . x) (minibuffer . only)
|
||||||
|
(left . 10000) (right . 10000)
|
||||||
|
(width . 1) (height . 1)
|
||||||
|
(client . nil))))
|
||||||
|
;; This is the only usable minibuffer frame.
|
||||||
|
(setq default-minibuffer-frame exwm-workspace--minibuffer)
|
||||||
|
(exwm-workspace--modify-all-x-frames-parameters
|
||||||
|
'((minibuffer . nil)))
|
||||||
|
(let ((outer-id (string-to-number
|
||||||
|
(frame-parameter exwm-workspace--minibuffer
|
||||||
|
'outer-window-id)))
|
||||||
|
(window-id (string-to-number
|
||||||
|
(frame-parameter exwm-workspace--minibuffer
|
||||||
|
'window-id)))
|
||||||
|
(container (xcb:generate-id exwm--connection)))
|
||||||
|
(set-frame-parameter exwm-workspace--minibuffer
|
||||||
|
'exwm-outer-id outer-id)
|
||||||
|
(set-frame-parameter exwm-workspace--minibuffer 'exwm-id window-id)
|
||||||
|
(set-frame-parameter exwm-workspace--minibuffer 'exwm-container
|
||||||
|
container)
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:CreateWindow
|
||||||
|
:depth 0
|
||||||
|
:wid container
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0
|
||||||
|
:y 0
|
||||||
|
:width 1
|
||||||
|
:height 1
|
||||||
|
:border-width 0
|
||||||
|
:class xcb:WindowClass:InputOutput
|
||||||
|
:visual 0
|
||||||
|
:value-mask (logior xcb:CW:BackPixmap
|
||||||
|
xcb:CW:OverrideRedirect)
|
||||||
|
:background-pixmap xcb:BackPixmap:ParentRelative
|
||||||
|
:override-redirect 1))
|
||||||
|
(exwm--debug
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
||||||
|
:window container
|
||||||
|
:data "Minibuffer container")))
|
||||||
|
;; Reparent the minibuffer frame to the container.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
:window outer-id :parent container :x 0 :y 0))
|
||||||
|
;; Map the container.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:MapWindow
|
||||||
|
:window container))
|
||||||
|
;; Attach event listener for monitoring the frame
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ChangeWindowAttributes
|
||||||
|
:window outer-id
|
||||||
|
:value-mask xcb:CW:EventMask
|
||||||
|
:event-mask xcb:EventMask:StructureNotify))
|
||||||
|
(xcb:+event exwm--connection 'xcb:ConfigureNotify
|
||||||
|
#'exwm-workspace--on-ConfigureNotify))
|
||||||
|
;; Show/hide minibuffer / echo area when they're active/inactive.
|
||||||
|
(add-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
|
||||||
|
(add-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
|
||||||
|
(setq exwm-workspace--timer
|
||||||
|
(run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty))
|
||||||
|
(add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
||||||
|
;; The default behavior of `display-buffer' (indirectly called by
|
||||||
|
;; `minibuffer-completion-help') is not correct here.
|
||||||
|
(cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist
|
||||||
|
: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 ()
|
(defun exwm-workspace--init ()
|
||||||
"Initialize workspace module."
|
"Initialize workspace module."
|
||||||
;; Prevent unexpected exit
|
;; Prevent unexpected exit
|
||||||
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
|
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
|
||||||
|
(setq exwm-workspace--fullscreen-frame-count 0)
|
||||||
(exwm-workspace--modify-all-x-frames-parameters
|
(exwm-workspace--modify-all-x-frames-parameters
|
||||||
'((internal-border-width . 0)))
|
'((internal-border-width . 0)))
|
||||||
(let ((initial-workspaces (frame-list)))
|
(let ((initial-workspaces (frame-list)))
|
||||||
|
@ -1472,12 +1545,7 @@ applied to all subsequently created X frames."
|
||||||
(set-frame-parameter f 'internal-border-width 0)
|
(set-frame-parameter f 'internal-border-width 0)
|
||||||
;; Prevent user from deleting the first frame by accident.
|
;; Prevent user from deleting the first frame by accident.
|
||||||
(set-frame-parameter f 'client nil)))
|
(set-frame-parameter f 'client nil)))
|
||||||
;; Initialize workspaces without minibuffers.
|
(exwm-workspace--init-minibuffer-frame)
|
||||||
(setq exwm-workspace--minibuffer
|
|
||||||
(make-frame '((window-system . x) (minibuffer . only)
|
|
||||||
(left . 10000) (right . 10000)
|
|
||||||
(width . 1) (height . 1)
|
|
||||||
(client . nil))))
|
|
||||||
;; Remove/hide existing frames.
|
;; Remove/hide existing frames.
|
||||||
(dolist (f initial-workspaces)
|
(dolist (f initial-workspaces)
|
||||||
(if (frame-parameter f 'client)
|
(if (frame-parameter f 'client)
|
||||||
|
@ -1487,72 +1555,9 @@ applied to all subsequently created X frames."
|
||||||
(make-frame-invisible f))
|
(make-frame-invisible f))
|
||||||
(when (eq 'x (framep f)) ;do not delete the initial frame.
|
(when (eq 'x (framep f)) ;do not delete the initial frame.
|
||||||
(delete-frame f))))
|
(delete-frame f))))
|
||||||
;; This is the only usable minibuffer frame.
|
|
||||||
(setq default-minibuffer-frame exwm-workspace--minibuffer)
|
|
||||||
(exwm-workspace--modify-all-x-frames-parameters
|
|
||||||
'((minibuffer . nil)))
|
|
||||||
(let ((outer-id (string-to-number
|
|
||||||
(frame-parameter exwm-workspace--minibuffer
|
|
||||||
'outer-window-id)))
|
|
||||||
(window-id (string-to-number
|
|
||||||
(frame-parameter exwm-workspace--minibuffer
|
|
||||||
'window-id)))
|
|
||||||
(container (xcb:generate-id exwm--connection)))
|
|
||||||
(set-frame-parameter exwm-workspace--minibuffer
|
|
||||||
'exwm-outer-id outer-id)
|
|
||||||
(set-frame-parameter exwm-workspace--minibuffer 'exwm-id window-id)
|
|
||||||
(set-frame-parameter exwm-workspace--minibuffer 'exwm-container
|
|
||||||
container)
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:CreateWindow
|
|
||||||
:depth 0
|
|
||||||
:wid container
|
|
||||||
:parent exwm--root
|
|
||||||
:x 0
|
|
||||||
:y 0
|
|
||||||
:width 1
|
|
||||||
:height 1
|
|
||||||
:border-width 0
|
|
||||||
:class xcb:WindowClass:InputOutput
|
|
||||||
:visual 0
|
|
||||||
:value-mask (logior xcb:CW:BackPixmap
|
|
||||||
xcb:CW:OverrideRedirect)
|
|
||||||
:background-pixmap xcb:BackPixmap:ParentRelative
|
|
||||||
:override-redirect 1))
|
|
||||||
(exwm--debug
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
|
||||||
:window container
|
|
||||||
:data "Minibuffer container")))
|
|
||||||
;; Reparent the minibuffer frame to the container.
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ReparentWindow
|
|
||||||
:window outer-id :parent container :x 0 :y 0))
|
|
||||||
;; Map the container.
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:MapWindow
|
|
||||||
:window container))
|
|
||||||
;; Attach event listener for monitoring the frame
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ChangeWindowAttributes
|
|
||||||
:window outer-id
|
|
||||||
:value-mask xcb:CW:EventMask
|
|
||||||
:event-mask xcb:EventMask:StructureNotify))
|
|
||||||
(xcb:+event exwm--connection 'xcb:ConfigureNotify
|
|
||||||
#'exwm-workspace--on-ConfigureNotify))
|
|
||||||
;; Show/hide minibuffer / echo area when they're active/inactive.
|
|
||||||
(add-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
|
|
||||||
(add-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
|
|
||||||
(setq exwm-workspace--timer
|
|
||||||
(run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty))
|
|
||||||
(add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
|
||||||
;; Recreate one frame with the external minibuffer set.
|
;; Recreate one frame with the external minibuffer set.
|
||||||
(setq initial-workspaces (list (make-frame '((window-system . x)
|
(setq initial-workspaces (list (make-frame '((window-system . x)
|
||||||
(client . nil)))))
|
(client . nil))))))
|
||||||
;; The default behavior of `display-buffer' (indirectly called by
|
|
||||||
;; `minibuffer-completion-help') is not correct here.
|
|
||||||
(cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist
|
|
||||||
:test #'equal))
|
|
||||||
;; 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."
|
||||||
|
|
Loading…
Reference in a new issue