From 39dc328157a970742aa40d3d9169376d2208fce3 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Thu, 14 Jul 2016 22:08:27 +0800 Subject: Fix various stability issues * exwm-input.el (exwm-input--on-KeyPress-line-mode) (exwm-input--on-KeyPress-char-mode): Append events at the tail. * exwm-manage.el (exwm-manage--unmanage-window): Remove the _NET_WM_DESKTOP property when an X window is withdrawn. * exwm-systemtray.el (exwm-systemtray--init): * exwm-workspace.el (exwm-workspace--confirm-kill-emacs): Issue warning rather than error when there's an existing tray running. * exwm.el (exwm--on-ClientMessage): The buffer window can be on a floating frame. --- exwm-input.el | 6 ++++-- exwm-manage.el | 14 ++++++++++++-- exwm-systemtray.el | 6 ++++-- exwm-workspace.el | 2 +- exwm.el | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/exwm-input.el b/exwm-input.el index 3cb189bb50f9..8813f762c67e 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -313,7 +313,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") (unless minibuffer-window (setq exwm-input--during-key-sequence t)) ;; Feed this event to command loop. Also force it to be added to ;; `this-command-keys'. - (push (cons t event) unread-command-events)) + (setq unread-command-events + (append unread-command-events `((t . ,event))))) (xcb:+request exwm--connection (make-instance 'xcb:AllowEvents :mode (or mode xcb:Allow:ReplayKeyboard) @@ -336,7 +337,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") (setq exwm-input--temp-line-mode t exwm-input--during-key-sequence t) (exwm-input--grab-keyboard)) ;grab keyboard temporarily - (push event unread-command-events)))) + (setq unread-command-events + (append unread-command-events (list event)))))) (xcb:+request exwm--connection (make-instance 'xcb:AllowEvents :mode xcb:Allow:AsyncKeyboard diff --git a/exwm-manage.el b/exwm-manage.el index d4b3de48f904..13948902d281 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -248,7 +248,11 @@ corresponding buffer.") (run-hooks 'exwm-manage-finish-hook))))) (defun exwm-manage--unmanage-window (id &optional withdraw-only) - "Unmanage window ID." + "Unmanage window ID. + +If WITHDRAW-ONLY is non-nil, the X window will be properly placed back to the +root window. Set WITHDRAW-ONLY to 'quit if this functions is used when window +manager is shutting down." (let ((buffer (exwm--id->buffer id))) (exwm--log "Unmanage #x%x (buffer: %s, widthdraw: %s)" id buffer withdraw-only) @@ -295,7 +299,13 @@ corresponding buffer.") ;; Delete WM_STATE property (xcb:+request exwm--connection (make-instance 'xcb:DeleteProperty - :window id :property xcb:Atom:WM_STATE))) + :window id :property xcb:Atom:WM_STATE)) + (unless (eq withdraw-only 'quit) + ;; Remove _NET_WM_DESKTOP. + (xcb:+request exwm--connection + (make-instance 'xcb:DeleteProperty + :window id + :property xcb:Atom:_NET_WM_DESKTOP)))) (when exwm--floating-frame ;; Unmap the floating frame before destroying the containers. (let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id))) diff --git a/exwm-systemtray.el b/exwm-systemtray.el index d1783debdb15..db0e0455d2dd 100644 --- a/exwm-systemtray.el +++ b/exwm-systemtray.el @@ -296,7 +296,7 @@ You shall use the default value if using auto-hide minibuffer.") (defvar xcb:Atom:_NET_SYSTEM_TRAY_S0) (defvar exwm-workspace--minibuffer) -(defun exwm-systemtray--init () +(cl-defun exwm-systemtray--init () "Initialize system tray module." (cl-assert (not exwm-systemtray--connection)) (cl-assert (not exwm-systemtray--list)) @@ -319,7 +319,9 @@ You shall use the default value if using auto-hide minibuffer.") (make-instance 'xcb:GetSelectionOwner :selection xcb:Atom:_NET_SYSTEM_TRAY_S0)) (when (/= owner xcb:Window:None) - (error "[EXWM] Other system tray detected"))) + (xcb:disconnect exwm-systemtray--connection) + (warn "[EXWM] Other system tray detected") + (cl-return-from exwm-systemtray--init))) (let ((id (xcb:generate-id exwm-systemtray--connection))) (setq exwm-systemtray--selection-owner-window id) (xcb:+request exwm-systemtray--connection diff --git a/exwm-workspace.el b/exwm-workspace.el index bde423d72729..6902151f4246 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -667,7 +667,7 @@ The optional FORCE option is for internal use only." x (if (= x 1) "" "s") prompt)))) ;; Unmanage all X windows. (dolist (i exwm--id-buffer-alist) - (exwm-manage--unmanage-window (car i) t) + (exwm-manage--unmanage-window (car i) 'quit) (xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window (car i)))) ;; Reparent out the minibuffer frame. diff --git a/exwm.el b/exwm.el index 232c863fad7b..3d7edcfeac16 100644 --- a/exwm.el +++ b/exwm.el @@ -327,7 +327,7 @@ (set-window-buffer (frame-selected-window exwm--frame) (current-buffer))) ;; Focus transfer. - (select-window (get-buffer-window))))))) + (select-window (get-buffer-window nil t))))))) ;; _NET_CLOSE_WINDOW. ((= type xcb:Atom:_NET_CLOSE_WINDOW) (let ((buffer (exwm--id->buffer id))) -- cgit 1.4.1