diff options
-rw-r--r-- | exwm-background.el | 6 | ||||
-rw-r--r-- | exwm-input.el | 22 | ||||
-rw-r--r-- | exwm-manage.el | 9 | ||||
-rw-r--r-- | exwm-systemtray.el | 27 | ||||
-rw-r--r-- | exwm-workspace.el | 81 | ||||
-rw-r--r-- | exwm-xim.el | 6 | ||||
-rw-r--r-- | exwm.el | 10 |
7 files changed, 89 insertions, 72 deletions
diff --git a/exwm-background.el b/exwm-background.el index e7a0360c97c0..f3e0d895c5de 100644 --- a/exwm-background.el +++ b/exwm-background.el @@ -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 diff --git a/exwm-input.el b/exwm-input.el index 79bc78ef0fe9..30ae89353e98 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -452,9 +452,12 @@ ARGS are additional arguments to CALLBACK." (t ;; Replay this event by default. (setq fake-last-command t) - (setq mode xcb:Allow:ReplayPointer)))) - (when fake-last-command - (exwm-input--fake-last-command)) + (setq mode xcb:Allow:ReplayPointer))) + (when fake-last-command + (if buffer + (with-current-buffer buffer + (exwm-input--fake-last-command)) + (exwm-input--fake-last-command)))) (xcb:+request exwm--connection (make-instance 'xcb:AllowEvents :mode mode :time xcb:Time:CurrentTime)) (xcb:flush exwm--connection)) @@ -1215,12 +1218,13 @@ 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. - (xcb:+request exwm--connection - (make-instance 'xcb:SetInputFocus - :revert-to xcb:InputFocus:PointerRoot - :focus exwm--root - :time xcb:Time:CurrentTime)) - (xcb:flush exwm--connection)) + (when (slot-value exwm--connection 'connected) + (xcb:+request exwm--connection + (make-instance 'xcb:SetInputFocus + :revert-to xcb:InputFocus:PointerRoot + :focus exwm--root + :time xcb:Time:CurrentTime)) + (xcb:flush exwm--connection))) diff --git a/exwm-manage.el b/exwm-manage.el index 36da1932c5b3..a94caeeab97c 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -426,7 +426,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 @@ -508,8 +510,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 diff --git a/exwm-systemtray.el b/exwm-systemtray.el index acefd09d23af..3fcbb8a214dd 100644 --- a/exwm-systemtray.el +++ b/exwm-systemtray.el @@ -653,19 +653,20 @@ indicate how to support actual transparency." "Exit the systemtray module." (exwm--log) (when exwm-systemtray--connection - ;; 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). - (xcb:+request exwm-systemtray--connection - (make-instance 'xcb:UnmapWindow - :window exwm-systemtray--embedder-window)) - (xcb:+request exwm-systemtray--connection - (make-instance 'xcb:ReparentWindow - :window exwm-systemtray--embedder-window - :parent exwm--root - :x 0 - :y 0)) - (xcb:disconnect 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). + (xcb:+request exwm-systemtray--connection + (make-instance 'xcb:UnmapWindow + :window exwm-systemtray--embedder-window)) + (xcb:+request exwm-systemtray--connection + (make-instance 'xcb:ReparentWindow + :window exwm-systemtray--embedder-window + :parent exwm--root + :x 0 + :y 0)) + (xcb:disconnect exwm-systemtray--connection)) (setq exwm-systemtray--connection nil exwm-systemtray--list nil exwm-systemtray--selection-owner-window nil diff --git a/exwm-workspace.el b/exwm-workspace.el index 626d29249eb0..dd1f22a9a2ac 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -1396,32 +1396,34 @@ 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) - (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)) - (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") - (let ((exwm-workspace--create-silently t)) - (setq next-frame (make-frame)))) - (dolist (pair exwm--id-buffer-alist) - (let ((other-frame (buffer-local-value 'exwm--frame (cdr pair)))) - ;; Move X windows to next-frame. - (when (eq other-frame frame) - (exwm-workspace-move-window next-frame (car pair))) - ;; Update the _NET_WM_DESKTOP property of each following X window. - (when (memq other-frame following-frames) - (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))) + (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") + (let ((exwm-workspace--create-silently t)) + (setq next-frame (make-frame)))) + (dolist (pair exwm--id-buffer-alist) + (let ((other-frame (buffer-local-value 'exwm--frame (cdr pair)))) + ;; Move X windows to next-frame. + (when (eq other-frame frame) + (exwm-workspace-move-window next-frame (car pair))) + ;; Update the _NET_WM_DESKTOP property of each following X window. + (when (memq other-frame following-frames) + (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)))) ;; Reparent out the frame. (let ((outer-id (frame-parameter frame 'exwm-outer-id))) (xcb:+request exwm--connection @@ -1455,8 +1457,9 @@ Return nil if FRAME is the only workspace." ;; Update EWMH properties. (exwm-workspace--update-ewmh-props) ;; Update switch history. - (setq exwm-workspace--switch-history-outdated t) - (run-hooks 'exwm-workspace-list-change-hook)) + (unless quit + (setq exwm-workspace--switch-history-outdated t) + (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." @@ -1630,7 +1633,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 @@ -1715,19 +1720,21 @@ 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) - (dolist (i exwm-workspace--list) - (when (frame-live-p i) ; might be already dead - (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 - (fullscreen . nil) - (buffer-predicate . 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 'quit) + (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 + (fullscreen . 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 () diff --git a/exwm-xim.el b/exwm-xim.el index 9589648d22ca..ac530f38930a 100644 --- a/exwm-xim.el +++ b/exwm-xim.el @@ -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 diff --git a/exwm.el b/exwm.el index 345f76beb66c..31fe6849559e 100644 --- a/exwm.el +++ b/exwm.el @@ -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. - (exwm-input--exit) - (exwm-manage--exit) - (exwm-workspace--exit) - (exwm-floating--exit) - (exwm-layout--exit) (when exwm--connection + (exwm-input--exit) + (exwm-manage--exit) + (exwm-workspace--exit) + (exwm-floating--exit) + (exwm-layout--exit) (xcb:flush exwm--connection) (xcb:disconnect exwm--connection)) (setq exwm--connection nil) |