From fe9be0b3efab284dae9eb1de37e97a70a9e08bd2 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Thu, 3 Mar 2016 19:34:17 +0800 Subject: [PATCH] Handle buffer change after a buffer is killed * exwm-manage.el (exwm-manage--kill-buffer-query-function): Handle buffer change. * exwm-workspace.el (exwm-workspace--show-minibuffer): Revert the change made in 93e42136 (the problem has not been fully resolved). --- exwm-manage.el | 95 ++++++++++++++++++++++++----------------------- exwm-workspace.el | 10 ++++- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/exwm-manage.el b/exwm-manage.el index fd1d64b..659e426 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -334,56 +334,57 @@ corresponding buffer.") (xcb:flush exwm--connection) ;; Wait for DestroyNotify event. (throw 'return nil)) - ;; Try to close the X window with WM_DELETE_WINDOW client message. - (xcb:+request exwm--connection - (make-instance 'xcb:icccm:SendEvent - :destination exwm--id - :event (xcb:marshal - (make-instance 'xcb:icccm:WM_DELETE_WINDOW - :window exwm--id) - exwm--connection))) - (xcb:flush exwm--connection) - ;; - (unless (memq xcb:Atom:_NET_WM_PING exwm--protocols) - ;; The window does not support _NET_WM_PING. To make sure it'll die, - ;; kill it after the time runs out. - ;; Hide the container to prevent flickering. + (let ((id exwm--id)) + ;; Try to close the X window with WM_DELETE_WINDOW client message. (xcb:+request exwm--connection - (make-instance 'xcb:UnmapWindow :window exwm--container)) + (make-instance 'xcb:icccm:SendEvent + :destination id + :event (xcb:marshal + (make-instance 'xcb:icccm:WM_DELETE_WINDOW + :window id) + exwm--connection))) (xcb:flush exwm--connection) - (run-with-timer exwm-manage-ping-timeout nil - `(lambda () (exwm-manage--kill-client ,exwm--id))) - ;; Wait for DestroyNotify event. - (throw 'return nil)) - ;; Try to determine if the X window is dead with _NET_WM_PING. - (setq exwm-manage--ping-lock t) - (xcb:+request exwm--connection - (make-instance 'xcb:SendEvent - :propagate 0 - :destination exwm--id - :event-mask xcb:EventMask:NoEvent - :event (xcb:marshal - (make-instance 'xcb:ewmh:_NET_WM_PING - :window exwm--id - :timestamp 0 - :client-window exwm--id) - exwm--connection))) - (xcb:flush exwm--connection) - (with-timeout (exwm-manage-ping-timeout - (if (yes-or-no-p (format "'%s' is not responding. \ + ;; + (unless (memq xcb:Atom:_NET_WM_PING exwm--protocols) + ;; The window does not support _NET_WM_PING. To make sure it'll die, + ;; kill it after the time runs out. + ;; Hide the container to prevent flickering. + (xcb:+request exwm--connection + (make-instance 'xcb:UnmapWindow :window exwm--container)) + (xcb:flush exwm--connection) + (run-with-timer exwm-manage-ping-timeout nil + `(lambda () (exwm-manage--kill-client ,id))) + ;; Wait for DestroyNotify event. + (throw 'return nil)) + ;; Try to determine if the X window is dead with _NET_WM_PING. + (setq exwm-manage--ping-lock t) + (xcb:+request exwm--connection + (make-instance 'xcb:SendEvent + :propagate 0 + :destination id + :event-mask xcb:EventMask:NoEvent + :event (xcb:marshal + (make-instance 'xcb:ewmh:_NET_WM_PING + :window id + :timestamp 0 + :client-window id) + exwm--connection))) + (xcb:flush exwm--connection) + (with-timeout (exwm-manage-ping-timeout + (if (yes-or-no-p (format "'%s' is not responding. \ Would you like to kill it? " - (buffer-name))) - (progn (exwm-manage--kill-client exwm--id) - ;; Kill the unresponsive X window and - ;; wait for DestroyNotify event. - (throw 'return nil)) - ;; Give up. - (throw 'return nil))) - (while (and exwm-manage--ping-lock - (exwm--id->buffer exwm--id)) ;may have been destroyed. - (accept-process-output nil 0.1)) - ;; Give up. - (throw 'return nil)))) + (buffer-name))) + (progn (exwm-manage--kill-client id) + ;; Kill the unresponsive X window and + ;; wait for DestroyNotify event. + (throw 'return nil)) + ;; Give up. + (throw 'return nil))) + (while (and exwm-manage--ping-lock + (exwm--id->buffer id)) ;may have been destroyed. + (accept-process-output nil 0.1)) + ;; Give up. + (throw 'return nil))))) (defun exwm-manage--kill-client (&optional id) "Kill an X client." diff --git a/exwm-workspace.el b/exwm-workspace.el index 6fc38d4..b2fb648 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -513,7 +513,15 @@ The optional FORCE option is for internal use only." (make-instance 'xcb:MapWindow :window (frame-parameter exwm-workspace--minibuffer 'exwm-container))) - (xcb:flush exwm--connection)) + (xcb:flush exwm--connection) + ;; Unfortunately we need the following lines to workaround a cursor + ;; flickering issue for line-mode floating X windows. They just make the + ;; minibuffer appear to be focused. + (with-current-buffer (window-buffer (minibuffer-window + exwm-workspace--minibuffer)) + (setq cursor-in-non-selected-windows + (frame-parameter exwm-workspace--minibuffer 'cursor-type)))) + (defun exwm-workspace--hide-minibuffer () "Hide the minibuffer frame."