Fix input focus lost after closing window

Also insert some debug messages.
This commit is contained in:
Chris Feng 2015-08-07 20:22:12 +08:00
parent 2ad1a89db0
commit 84f0f0328b
4 changed files with 34 additions and 12 deletions

View file

@ -57,17 +57,22 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(defun exwm-input--set-focus (id) (defun exwm-input--set-focus (id)
"Set input focus to window ID in a proper way." "Set input focus to window ID in a proper way."
(exwm--with-current-id id (exwm--with-current-id id
(exwm--log "Set focus ID to #x%x" id)
(setq exwm-input--focus-id id) (setq exwm-input--focus-id id)
(if (and (not exwm--hints-input) (if (and (not exwm--hints-input)
(memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols)) (memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols))
(progn
(exwm--log "Focus on #x%x with WM_TAKE_FOCUS" id)
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:icccm:SendEvent (make-instance 'xcb:icccm:SendEvent
:destination id :destination id
:event (xcb:marshal :event (xcb:marshal
(make-instance 'xcb:icccm:WM_TAKE_FOCUS (make-instance 'xcb:icccm:WM_TAKE_FOCUS
:window id :window id
:time exwm-input--timestamp) :time
exwm--connection))) exwm-input--timestamp)
exwm--connection))))
(exwm--log "Focus on #x%x with SetInputFocus" id)
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:SetInputFocus (make-instance 'xcb:SetInputFocus
:revert-to xcb:InputFocus:Parent :focus id :revert-to xcb:InputFocus:Parent :focus id
@ -85,24 +90,34 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(setq exwm-input--focus-lock t) (setq exwm-input--focus-lock t)
(when (eq (current-buffer) (window-buffer)) ;e.g. with-temp-buffer (when (eq (current-buffer) (window-buffer)) ;e.g. with-temp-buffer
(if (eq major-mode 'exwm-mode) (if (eq major-mode 'exwm-mode)
(progn (setq exwm-input--focus-id exwm--id) (progn (exwm--log "Set focus ID to #x%x" exwm--id)
(setq exwm-input--focus-id exwm--id)
(when exwm--floating-frame (when exwm--floating-frame
(if (eq (selected-frame) exwm--floating-frame) (if (eq (selected-frame) exwm--floating-frame)
;; Cancel the possible input focus redirection ;; Cancel the possible input focus redirection
(redirect-frame-focus exwm--floating-frame nil) (progn
(exwm--log "Cancel input focus redirection on %s"
exwm--floating-frame)
(redirect-frame-focus exwm--floating-frame nil))
;; Focus the floating frame ;; Focus the floating frame
(exwm--log "Focus on floating frame %s"
exwm--floating-frame)
(x-focus-frame exwm--floating-frame))) (x-focus-frame exwm--floating-frame)))
;; Finally focus the window ;; Finally focus the window
(exwm-input--set-focus exwm-input--focus-id)) (exwm-input--set-focus exwm-input--focus-id))
(exwm--with-current-id exwm-input--focus-id (exwm--with-current-id exwm-input--focus-id
(exwm--log "Set focus ID to #x%x" xcb:Window:None)
(setq exwm-input--focus-id xcb:Window:None) (setq exwm-input--focus-id xcb:Window:None)
(let ((frame (selected-frame))) (let ((frame (selected-frame)))
(if exwm--floating-frame (if exwm--floating-frame
(unless (or (eq frame exwm--floating-frame) (unless (or (eq frame exwm--floating-frame)
(active-minibuffer-window)) (active-minibuffer-window))
;; Redirect input focus to the workspace frame ;; Redirect input focus to the workspace frame
(exwm--log "Redirect input focus (%s => %s)"
exwm--floating-frame frame)
(redirect-frame-focus exwm--floating-frame frame)) (redirect-frame-focus exwm--floating-frame frame))
;; Focus the workspace frame ;; Focus the workspace frame
(exwm--log "Focus on workspace %s" frame)
(x-focus-frame frame)))))) (x-focus-frame frame))))))
(setq exwm-input--focus-lock nil))) (setq exwm-input--focus-lock nil)))

View file

@ -28,6 +28,7 @@
(defun exwm-layout--show (id &optional window) (defun exwm-layout--show (id &optional window)
"Show window ID exactly fit in the Emacs window WINDOW." "Show window ID exactly fit in the Emacs window WINDOW."
(exwm--log "Show #x%x in %s" id window)
(xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id)) (xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:icccm:set-WM_STATE (make-instance 'xcb:icccm:set-WM_STATE
@ -69,6 +70,7 @@
"Hide window ID." "Hide window ID."
(unless (eq xcb:icccm:WM_STATE:IconicState ;already hidden (unless (eq xcb:icccm:WM_STATE:IconicState ;already hidden
(with-current-buffer (exwm--id->buffer id) exwm-state)) (with-current-buffer (exwm--id->buffer id) exwm-state))
(exwm--log "Hide #x%x" id)
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ChangeWindowAttributes (make-instance 'xcb:ChangeWindowAttributes
:window id :value-mask xcb:CW:EventMask :window id :value-mask xcb:CW:EventMask
@ -162,6 +164,7 @@
"Refresh layout." "Refresh layout."
(unless (compare-window-configurations exwm-layout--window-configuration (unless (compare-window-configurations exwm-layout--window-configuration
(current-window-configuration)) (current-window-configuration))
(exwm--log "Refresh layout")
(setq exwm-layout--window-configuration (current-window-configuration)) (setq exwm-layout--window-configuration (current-window-configuration))
(let ((frame (selected-frame)) (let ((frame (selected-frame))
windows) windows)

View file

@ -178,8 +178,10 @@ corresponding buffer.")
:window id :property xcb:Atom:WM_STATE)) :window id :property xcb:Atom:WM_STATE))
(xcb:flush exwm--connection)) (xcb:flush exwm--connection))
(setq kill-buffer-query-functions nil) (setq kill-buffer-query-functions nil)
(let ((floating exwm--floating-frame))
(kill-buffer) (kill-buffer)
(select-frame-set-input-focus exwm-workspace--current))))) (when floating
(select-frame-set-input-focus exwm-workspace--current)))))))
(defun exwm-manage--scan () (defun exwm-manage--scan ()
"Search for existing windows and try to manage them." "Search for existing windows and try to manage them."

View file

@ -152,7 +152,9 @@ The optional FORCE option is for internal use only."
"Fix unexpected frame switch." "Fix unexpected frame switch."
(unless exwm-workspace--switch-lock (unless exwm-workspace--switch-lock
(let ((index (cl-position (selected-frame) exwm-workspace--list))) (let ((index (cl-position (selected-frame) exwm-workspace--list)))
(exwm--log "Focus on workspace %s" index)
(when (and index (/= index exwm-workspace-current-index)) (when (and index (/= index exwm-workspace-current-index))
(exwm--log "Workspace was switched unexpectedly")
(exwm-workspace-switch index))))) (exwm-workspace-switch index)))))
(defun exwm-workspace-move-window (index &optional id) (defun exwm-workspace-move-window (index &optional id)