mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-27 14:57:59 +01:00
Avoid redundant input focus transfer
* exwm-input.el (exwm-input--set-focus): Check for current focused X window before making an input focus transfer. (exwm-input--on-buffer-list-update): Remove the `this-command' check.
This commit is contained in:
parent
3420cd24d1
commit
6a3e9b2c64
1 changed files with 43 additions and 28 deletions
|
@ -164,32 +164,48 @@ This value should always be overwritten.")
|
||||||
|
|
||||||
(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."
|
||||||
(when (exwm--id->buffer id)
|
(let ((from (slot-value (xcb:+request-unchecked+reply exwm--connection
|
||||||
(exwm--log "id=#x%x" id)
|
(make-instance 'xcb:GetInputFocus))
|
||||||
(with-current-buffer (exwm--id->buffer id)
|
'focus))
|
||||||
(exwm-input--update-timestamp
|
tree)
|
||||||
(lambda (timestamp id send-input-focus wm-take-focus)
|
(if (or (exwm--id->buffer from)
|
||||||
(when send-input-focus
|
(eq from id))
|
||||||
(xcb:+request exwm--connection
|
(exwm--log "#x%x => #x%x" (or from 0) (or id 0))
|
||||||
(make-instance 'xcb:SetInputFocus
|
;; Attempt to find the top-level X window for a 'focus proxy'.
|
||||||
:revert-to xcb:InputFocus:Parent
|
(unless (= from xcb:Window:None)
|
||||||
:focus id
|
(setq tree (xcb:+request-unchecked+reply exwm--connection
|
||||||
:time timestamp)))
|
(make-instance 'xcb:QueryTree
|
||||||
(when wm-take-focus
|
:window from)))
|
||||||
(let ((event (make-instance 'xcb:icccm:WM_TAKE_FOCUS
|
(when tree
|
||||||
:window id
|
(setq from (slot-value tree 'parent))))
|
||||||
:time timestamp)))
|
(exwm--log "#x%x (corrected) => #x%x" (or from 0) (or id 0)))
|
||||||
(setq event (xcb:marshal event exwm--connection))
|
(when (and (exwm--id->buffer id)
|
||||||
|
;; Avoid redundant input focus transfer.
|
||||||
|
(not (eq from id)))
|
||||||
|
(with-current-buffer (exwm--id->buffer id)
|
||||||
|
(exwm-input--update-timestamp
|
||||||
|
(lambda (timestamp id send-input-focus wm-take-focus)
|
||||||
|
(when send-input-focus
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:icccm:SendEvent
|
(make-instance 'xcb:SetInputFocus
|
||||||
:destination id
|
:revert-to xcb:InputFocus:Parent
|
||||||
:event event))))
|
:focus id
|
||||||
(exwm-input--set-active-window id)
|
:time timestamp)))
|
||||||
(xcb:flush exwm--connection))
|
(when wm-take-focus
|
||||||
id
|
(let ((event (make-instance 'xcb:icccm:WM_TAKE_FOCUS
|
||||||
(or exwm--hints-input
|
:window id
|
||||||
(not (memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols)))
|
:time timestamp)))
|
||||||
(memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols)))))
|
(setq event (xcb:marshal event exwm--connection))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:icccm:SendEvent
|
||||||
|
:destination id
|
||||||
|
:event event))))
|
||||||
|
(exwm-input--set-active-window id)
|
||||||
|
(xcb:flush exwm--connection))
|
||||||
|
id
|
||||||
|
(or exwm--hints-input
|
||||||
|
(not (memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols)))
|
||||||
|
(memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols))))))
|
||||||
|
|
||||||
(defun exwm-input--update-timestamp (callback &rest args)
|
(defun exwm-input--update-timestamp (callback &rest args)
|
||||||
"Fetch the latest timestamp from the server and feed it to CALLBACK.
|
"Fetch the latest timestamp from the server and feed it to CALLBACK.
|
||||||
|
@ -276,9 +292,8 @@ ARGS are additional arguments to CALLBACK."
|
||||||
|
|
||||||
(defun exwm-input--on-buffer-list-update ()
|
(defun exwm-input--on-buffer-list-update ()
|
||||||
"Run in `buffer-list-update-hook' to track input focus."
|
"Run in `buffer-list-update-hook' to track input focus."
|
||||||
(when (and (not (eq this-command #'handle-switch-frame))
|
(when (and (not (exwm-workspace--client-p))
|
||||||
(not exwm-input--skip-buffer-list-update)
|
(not exwm-input--skip-buffer-list-update))
|
||||||
(not (exwm-workspace--client-p)))
|
|
||||||
(exwm--log "current-buffer=%S selected-window=%S"
|
(exwm--log "current-buffer=%S selected-window=%S"
|
||||||
(current-buffer) (selected-window))
|
(current-buffer) (selected-window))
|
||||||
(redirect-frame-focus (selected-frame) nil)
|
(redirect-frame-focus (selected-frame) nil)
|
||||||
|
|
Loading…
Reference in a new issue