Observe connection status on deinitialization

* exwm-workspace.el (exwm-workspace--remove-frame-as-workspace):
Add optional argument quit.

* exwm-background.el (exwm-background--exit):
* exwm-input.el (exwm-input--exit):
* exwm-manage.el (exwm-manage--unmanage-window):
* exwm-systemtray.el (exwm-systemtray--exit):
* exwm-workspace.el (exwm-workspace--exit-minibuffer-frame)
(exwm-workspace--exit):
* exwm-xim.el (exwm-xim--exit): Observe connection status when
deinitializing in order to support deinitializing when the
connection breaks.
This commit is contained in:
Adrián Medraño Calvo 2023-06-09 00:00:00 +00:00
parent cff02333e2
commit 7318f857f2
7 changed files with 77 additions and 64 deletions

View file

@ -172,19 +172,17 @@ replace it.")
(defun exwm-background--init ()
"Initialize background module."
(exwm--log)
(add-hook 'enable-theme-functions 'exwm-background--update)
(add-hook 'disable-theme-functions 'exwm-background--update)
(exwm-background--update))
(defun exwm-background--exit ()
"Uninitialize the background module."
(exwm--log)
(remove-hook 'enable-theme-functions 'exwm-background--update)
(remove-hook 'disable-theme-functions 'exwm-background--update)
(when exwm-background--connection
(when (and exwm-background--connection
(slot-value exwm-background--connection 'connected))
(xcb:disconnect exwm-background--connection))
(setq exwm-background--pixmap nil
exwm-background--connection nil

View file

@ -1215,7 +1215,7 @@ One use is to access the keymap bound to KEYS (as prefix keys) in char-mode."
(when exwm-input--update-focus-timer
(cancel-timer exwm-input--update-focus-timer))
;; Make input focus working even without a WM.
(when exwm--connection
(when (slot-value exwm--connection 'connected)
(xcb:+request exwm--connection
(make-instance 'xcb:SetInputFocus
:revert-to xcb:InputFocus:PointerRoot

View file

@ -430,7 +430,9 @@ manager is shutting down."
(exwm-workspace--update-workareas)
(dolist (f exwm-workspace--list)
(exwm-workspace--set-fullscreen f)))
(when (buffer-live-p buffer)
(when (and (buffer-live-p buffer)
;; Invoked from `exwm-manage--exit' upon disconnection.
(slot-value exwm--connection 'connected))
(with-current-buffer buffer
;; Unmap the X window.
(xcb:+request exwm--connection
@ -512,8 +514,11 @@ manager is shutting down."
(defun exwm-manage--kill-buffer-query-function ()
"Run in `kill-buffer-query-functions'."
(exwm--log "id=#x%x; buffer=%s" exwm--id (current-buffer))
(exwm--log "id=#x%x; buffer=%s" (or exwm--id 0) (current-buffer))
(catch 'return
(when (or (not exwm--connection)
(not (slot-value exwm--connection 'connected)))
(throw 'return t))
(when (or (not exwm--id)
(xcb:+request-checked+request-check exwm--connection
(make-instance 'xcb:ChangeWindowAttributes

View file

@ -652,6 +652,7 @@ indicate how to support actual transparency."
"Exit the systemtray module."
(exwm--log)
(when exwm-systemtray--connection
(when (slot-value exwm-systemtray--connection 'connected)
;; Hide & reparent out the embedder before disconnection to prevent
;; embedded icons from being reparented to an Emacs frame (which is the
;; parent of the embedder).
@ -664,7 +665,7 @@ indicate how to support actual transparency."
:parent exwm--root
:x 0
:y 0))
(xcb:disconnect exwm-systemtray--connection)
(xcb:disconnect exwm-systemtray--connection))
(setq exwm-systemtray--connection nil
exwm-systemtray--list nil
exwm-systemtray--selection-owner-window nil

View file

@ -1389,16 +1389,18 @@ Return nil if FRAME is the only workspace."
(unless (eq frame nextw)
nextw)))
(defun exwm-workspace--remove-frame-as-workspace (frame)
(defun exwm-workspace--remove-frame-as-workspace (frame &optional quit)
"Stop treating frame FRAME as a workspace."
;; TODO: restore all frame parameters (e.g. exwm-workspace, buffer-predicate,
;; etc)
(exwm--log "Removing frame `%s' as workspace" frame)
(unless quit
(let* ((next-frame (exwm-workspace--get-next-workspace frame))
(following-frames (cdr (memq frame exwm-workspace--list))))
;; Need to remove the workspace from the list for the correct calculation of
;; indexes below.
(setq exwm-workspace--list (delete frame exwm-workspace--list))
;; Move the windows to the next workspace and switch to it.
(unless next-frame
;; The user managed to delete the last workspace, so create a new one.
(exwm--log "Last workspace deleted; create a new one")
@ -1414,7 +1416,7 @@ Return nil if FRAME is the only workspace."
(exwm-workspace--set-desktop (car pair)))))
;; If the current workspace is deleted, switch to next one.
(when (eq frame exwm-workspace--current)
(exwm-workspace-switch next-frame)))
(exwm-workspace-switch next-frame))))
;; Reparent out the frame.
(let ((outer-id (frame-parameter frame 'exwm-outer-id)))
(xcb:+request exwm--connection
@ -1448,8 +1450,9 @@ Return nil if FRAME is the only workspace."
;; Update EWMH properties.
(exwm-workspace--update-ewmh-props)
;; Update switch history.
(unless quit
(setq exwm-workspace--switch-history-outdated t)
(run-hooks 'exwm-workspace-list-change-hook))
(run-hooks 'exwm-workspace-list-change-hook)))
(defun exwm-workspace--on-delete-frame (frame)
"Hook run upon `delete-frame' that tears down FRAME's configuration as a workspace."
@ -1623,7 +1626,9 @@ applied to all subsequently created X frames."
(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)))
(when (and exwm-workspace--minibuffer id)
(when (and exwm-workspace--minibuffer id
;; Invoked from `exwm-manage--exit' upon disconnection.
(slot-value exwm--connection 'connected))
(xcb:+request exwm--connection
(make-instance 'xcb:ReparentWindow
:window id
@ -1708,10 +1713,10 @@ applied to all subsequently created X frames."
#'exwm-workspace--on-echo-area-clear))
;; Hide & reparent out all frames (save-set can't be used here since
;; X windows will be re-mapped).
(setq exwm-workspace--current nil)
(when (slot-value exwm--connection 'connected)
(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 'quit)
(modify-frame-parameters i '((exwm-selected-window . nil)
(exwm-urgency . nil)
(exwm-outer-id . nil)
@ -1719,8 +1724,10 @@ applied to all subsequently created X frames."
(exwm-container . nil)
;; (internal-border-width . nil) ; integerp
(fullscreen . nil)
(buffer-predicate . nil)))))
(buffer-predicate . nil))))))
;; Don't let dead frames linger.
(setq exwm-workspace--current nil)
(setq exwm-workspace-current-index 0)
(setq exwm-workspace--list nil))
(defun exwm-workspace--post-init ()

View file

@ -754,10 +754,12 @@ Such event would be received when the client window is destroyed."
;; Close IMS communication connections.
(mapc (lambda (i)
(when (vectorp i)
(xcb:disconnect (elt i 0))))
(when (slot-value (elt i 0) 'connected)
(xcb:disconnect (elt i 0)))))
exwm-xim--server-client-plist)
;; Close the IMS connection.
(unless exwm-xim--conn
(unless (and exwm-xim--conn
(slot-value exwm-xim--conn 'connected))
(cl-return-from exwm-xim--exit))
;; Remove exwm-xim from XIM_SERVERS.
(let ((reply (xcb:+request-unchecked+reply exwm-xim--conn

View file

@ -907,12 +907,12 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'."
(run-hooks 'exwm-exit-hook)
(setq confirm-kill-emacs nil)
;; Exit modules.
(when exwm--connection
(exwm-input--exit)
(exwm-manage--exit)
(exwm-workspace--exit)
(exwm-floating--exit)
(exwm-layout--exit)
(when exwm--connection
(xcb:flush exwm--connection)
(xcb:disconnect exwm--connection))
(setq exwm--connection nil)