Support for killing the X terminal
Check whether frames are alive upon teardown, as it might not be the case when the terminal is killed as `delete-terminal-functions' might be invoked after the terminal is deleted. * exwm-core.el (exwm--terminal): New variable holding the terminal EXWM runs under. (exwm-init, exwm-exit): Set and unset it. * exwm.el (exwm--on-delete-terminal): New function for exiting EXWM when the terminal is deleted. (exwm-init): Use it. * exwm.el (exwm--confirm-kill-terminal, exwm-init): Ask for confirmation before deleting terminal. * exwm-workspace.el (exwm-workspace--fullscreen-workspace): New function. Ensure the frame is alive. (exwm-workspace--add-frame-as-workspace): Use it. (exwm-workspace--exit-minibuffer-frame): Cancel `exwm-workspace--display-echo-area-timer'. (exwm-workspace--exit-minibuffer-frame): Ensure the minibuffer frame is alive. (exwm-workspace--exit): Ignore dead workspace frames.
This commit is contained in:
parent
a11bb099fb
commit
1aa4ca781d
3 changed files with 63 additions and 25 deletions
|
@ -59,6 +59,9 @@ Here are some predefined candidates:
|
||||||
|
|
||||||
(defvar exwm--connection nil "X connection.")
|
(defvar exwm--connection nil "X connection.")
|
||||||
|
|
||||||
|
(defvar exwm--terminal nil
|
||||||
|
"Terminal corresponding to `exwm--connection'.")
|
||||||
|
|
||||||
(defvar exwm--wmsn-window nil
|
(defvar exwm--wmsn-window nil
|
||||||
"An X window owning the WM_S0 selection.")
|
"An X window owning the WM_S0 selection.")
|
||||||
|
|
||||||
|
|
|
@ -1372,7 +1372,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
|
||||||
(make-instance 'xcb:MapWindow :window container)))
|
(make-instance 'xcb:MapWindow :window container)))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
;; Delay making the workspace fullscreen until Emacs becomes idle
|
;; Delay making the workspace fullscreen until Emacs becomes idle
|
||||||
(exwm--defer 0 #'set-frame-parameter frame 'fullscreen 'fullboth)
|
(exwm--defer 0 #'exwm-workspace--fullscreen-workspace frame)
|
||||||
;; Update EWMH properties.
|
;; Update EWMH properties.
|
||||||
(exwm-workspace--update-ewmh-props)
|
(exwm-workspace--update-ewmh-props)
|
||||||
(if exwm-workspace--create-silently
|
(if exwm-workspace--create-silently
|
||||||
|
@ -1463,6 +1463,12 @@ Return nil if FRAME is the only workspace."
|
||||||
(exwm-workspace--remove-frame-as-workspace frame)
|
(exwm-workspace--remove-frame-as-workspace frame)
|
||||||
(remhash frame exwm-workspace--client-p-hash-table))))
|
(remhash frame exwm-workspace--client-p-hash-table))))
|
||||||
|
|
||||||
|
(defun exwm-workspace--fullscreen-workspace (frame)
|
||||||
|
"Make workspace FRAME fullscreen.
|
||||||
|
Called from a timer."
|
||||||
|
(when (frame-live-p frame)
|
||||||
|
(set-frame-parameter frame 'fullscreen 'fullboth)))
|
||||||
|
|
||||||
(defun exwm-workspace--on-after-make-frame (frame)
|
(defun exwm-workspace--on-after-make-frame (frame)
|
||||||
"Hook run upon `make-frame' that configures FRAME as a workspace."
|
"Hook run upon `make-frame' that configures FRAME as a workspace."
|
||||||
(cond
|
(cond
|
||||||
|
@ -1606,6 +1612,8 @@ applied to all subsequently created X frames."
|
||||||
(remove-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
|
(remove-hook 'minibuffer-setup-hook #'exwm-workspace--on-minibuffer-setup)
|
||||||
(remove-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
|
(remove-hook 'minibuffer-exit-hook #'exwm-workspace--on-minibuffer-exit)
|
||||||
(remove-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
(remove-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
||||||
|
(when exwm-workspace--display-echo-area-timer
|
||||||
|
(cancel-timer exwm-workspace--display-echo-area-timer))
|
||||||
(when exwm-workspace--timer
|
(when exwm-workspace--timer
|
||||||
(cancel-timer exwm-workspace--timer)
|
(cancel-timer exwm-workspace--timer)
|
||||||
(setq exwm-workspace--timer nil))
|
(setq exwm-workspace--timer nil))
|
||||||
|
@ -1613,6 +1621,7 @@ applied to all subsequently created X frames."
|
||||||
(cl-delete '(exwm-workspace--display-buffer) display-buffer-alist
|
(cl-delete '(exwm-workspace--display-buffer) display-buffer-alist
|
||||||
:test #'equal))
|
:test #'equal))
|
||||||
(setq default-minibuffer-frame nil)
|
(setq default-minibuffer-frame nil)
|
||||||
|
(when (frame-live-p exwm-workspace--minibuffer) ; might be already dead
|
||||||
(let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id)))
|
(let ((id (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id)))
|
||||||
(when (and exwm-workspace--minibuffer id)
|
(when (and exwm-workspace--minibuffer id)
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
|
@ -1621,7 +1630,7 @@ applied to all subsequently created X frames."
|
||||||
:parent exwm--root
|
:parent exwm--root
|
||||||
:x 0
|
:x 0
|
||||||
:y 0)))
|
:y 0)))
|
||||||
(setq exwm-workspace--minibuffer nil)))
|
(setq exwm-workspace--minibuffer nil))))
|
||||||
|
|
||||||
(defun exwm-workspace--init ()
|
(defun exwm-workspace--init ()
|
||||||
"Initialize workspace module."
|
"Initialize workspace module."
|
||||||
|
@ -1712,6 +1721,7 @@ applied to all subsequently created X frames."
|
||||||
;; X windows will be re-mapped).
|
;; X windows will be re-mapped).
|
||||||
(setq exwm-workspace--current nil)
|
(setq exwm-workspace--current nil)
|
||||||
(dolist (i exwm-workspace--list)
|
(dolist (i exwm-workspace--list)
|
||||||
|
(when (frame-live-p i) ; might be already dead
|
||||||
(exwm-workspace--remove-frame-as-workspace i)
|
(exwm-workspace--remove-frame-as-workspace i)
|
||||||
(modify-frame-parameters i '((exwm-selected-window . nil)
|
(modify-frame-parameters i '((exwm-selected-window . nil)
|
||||||
(exwm-urgency . nil)
|
(exwm-urgency . nil)
|
||||||
|
@ -1719,17 +1729,20 @@ applied to all subsequently created X frames."
|
||||||
(exwm-id . nil)
|
(exwm-id . nil)
|
||||||
(exwm-container . nil)
|
(exwm-container . nil)
|
||||||
;; (internal-border-width . nil) ; integerp
|
;; (internal-border-width . nil) ; integerp
|
||||||
;; (client . nil)
|
|
||||||
(fullscreen . nil)
|
(fullscreen . nil)
|
||||||
(buffer-predicate . nil))))
|
(buffer-predicate . nil)))
|
||||||
;; Restore the 'client' frame parameter (before `exwm-exit').
|
;; Restore the 'client' frame parameter (before `exwm-exit').
|
||||||
(when exwm-workspace--client
|
(when exwm-workspace--client
|
||||||
(dolist (f exwm-workspace--list)
|
(set-frame-parameter f 'client exwm-workspace--client))))
|
||||||
(set-frame-parameter f 'client exwm-workspace--client))
|
;; Restore the 'client' frame parameter (before `exwm-exit').
|
||||||
(when (exwm-workspace--minibuffer-own-frame-p)
|
(when exwm-workspace--client
|
||||||
|
(when (and exwm-workspace--minibuffer-own-frame-p
|
||||||
|
(frame-live-p exwm-workspace--minibuffer))
|
||||||
(set-frame-parameter exwm-workspace--minibuffer 'client
|
(set-frame-parameter exwm-workspace--minibuffer 'client
|
||||||
exwm-workspace--client))
|
exwm-workspace--client))
|
||||||
(setq exwm-workspace--client nil)))
|
(setq exwm-workspace--client nil))
|
||||||
|
;; Don't let dead frames linger.
|
||||||
|
(setq exwm-workspace--list 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."
|
||||||
|
|
24
exwm.el
24
exwm.el
|
@ -604,6 +604,13 @@
|
||||||
(eq selection xcb:Atom:WM_S0))
|
(eq selection xcb:Atom:WM_S0))
|
||||||
(exwm-exit))))
|
(exwm-exit))))
|
||||||
|
|
||||||
|
(defun exwm--on-delete-terminal (terminal)
|
||||||
|
"Handle terminal being deleted without Emacs being killed.
|
||||||
|
This may happen when invoking `save-buffers-kill-terminal' within an emacsclient
|
||||||
|
session."
|
||||||
|
(when (eq terminal exwm--terminal)
|
||||||
|
(exwm-exit)))
|
||||||
|
|
||||||
(defun exwm--init-icccm-ewmh ()
|
(defun exwm--init-icccm-ewmh ()
|
||||||
"Initialize ICCCM/EWMH support."
|
"Initialize ICCCM/EWMH support."
|
||||||
(exwm--log)
|
(exwm--log)
|
||||||
|
@ -840,6 +847,7 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(progn
|
(progn
|
||||||
(exwm-enable 'undo) ;never initialize again
|
(exwm-enable 'undo) ;never initialize again
|
||||||
|
(setq exwm--terminal (frame-terminal frame))
|
||||||
(setq exwm--connection (xcb:connect))
|
(setq exwm--connection (xcb:connect))
|
||||||
(set-process-query-on-exit-flag (slot-value exwm--connection 'process)
|
(set-process-query-on-exit-flag (slot-value exwm--connection 'process)
|
||||||
nil) ;prevent query message on exit
|
nil) ;prevent query message on exit
|
||||||
|
@ -862,6 +870,10 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
|
||||||
;; Disable some features not working well with EXWM
|
;; Disable some features not working well with EXWM
|
||||||
(setq use-dialog-box nil
|
(setq use-dialog-box nil
|
||||||
confirm-kill-emacs #'exwm--confirm-kill-emacs)
|
confirm-kill-emacs #'exwm--confirm-kill-emacs)
|
||||||
|
(advice-add 'save-buffers-kill-terminal
|
||||||
|
:before-while #'exwm--confirm-kill-terminal)
|
||||||
|
;; Clean up if the terminal is deleted.
|
||||||
|
(add-hook 'delete-terminal-functions 'exwm--on-delete-terminal)
|
||||||
(exwm--lock)
|
(exwm--lock)
|
||||||
(exwm--init-icccm-ewmh)
|
(exwm--init-icccm-ewmh)
|
||||||
(exwm-layout--init)
|
(exwm-layout--init)
|
||||||
|
@ -898,7 +910,9 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
|
||||||
(when exwm--connection
|
(when exwm--connection
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
(xcb:disconnect exwm--connection))
|
(xcb:disconnect exwm--connection))
|
||||||
(setq exwm--connection nil))
|
(setq exwm--connection nil)
|
||||||
|
(setq exwm--terminal nil)
|
||||||
|
(exwm--log "Exited"))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun exwm-enable (&optional undo)
|
(defun exwm-enable (&optional undo)
|
||||||
|
@ -977,6 +991,14 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
|
||||||
;; For other types, return the value as-is.
|
;; For other types, return the value as-is.
|
||||||
(t result))))))
|
(t result))))))
|
||||||
|
|
||||||
|
(defun exwm--confirm-kill-terminal (&optional _)
|
||||||
|
"Confirm before killing terminal."
|
||||||
|
;; This is invoked instead of `save-buffers-kill-emacs' (C-x C-c) on client
|
||||||
|
;; frames.
|
||||||
|
(if (eq (frame-terminal) exwm--terminal)
|
||||||
|
(exwm--confirm-kill-emacs "[EXWM] Kill terminal?")
|
||||||
|
t))
|
||||||
|
|
||||||
(defun exwm--confirm-kill-emacs (prompt &optional force)
|
(defun exwm--confirm-kill-emacs (prompt &optional force)
|
||||||
"Confirm before exiting Emacs."
|
"Confirm before exiting Emacs."
|
||||||
(exwm--log)
|
(exwm--log)
|
||||||
|
|
Loading…
Reference in a new issue