about summary refs log tree commit diff
path: root/third_party
diff options
context:
space:
mode:
authorQiang Fang <qiang.fang@zoho.com.cn>2020-01-31T09·50+0800
committertazjin <mail@tazj.in>2021-09-16T11·33+0000
commite74f12f85b0f83d413da13b9a9f295a35eec399f (patch)
treef33345c72b8fed505fb242e91dc64f4be4f8c1e8 /third_party
parent6cfee7ef5a0062453e7ea040d065da06f61f1aed (diff)
refactor(3p/exwm): Improve detection of focus changes r/2874
	* exwm-input.el: (exwm-input--on-buffer-list-update): Keep track
	of last selected window and buffer, update focus only when any
	of those changes.
	(exwm-input--update-focus-defer): Add commentary.
	(exwm-input--update-focus-window-buffer): Add
	variable.

Imported from https://github.com/ch11ng/exwm/pull/737

Copyright-paperwork-exempt: yes
Co-Author: Adrián Medraño Calvo <adrian@medranocalvo.com>
Change-Id: I3e53bcf45f04d0f9a88b757dffefe6de20daadfb
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3561
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'third_party')
-rw-r--r--third_party/exwm/exwm-input.el34
1 files changed, 27 insertions, 7 deletions
diff --git a/third_party/exwm/exwm-input.el b/third_party/exwm/exwm-input.el
index decfc8128cc9..1120e81eba26 100644
--- a/third_party/exwm/exwm-input.el
+++ b/third_party/exwm/exwm-input.el
@@ -138,8 +138,16 @@ defined in `exwm-mode-map' here."
   "Timer for deferring the update of input focus.")
 
 (defvar exwm-input--update-focus-window nil "The (Emacs) window to be focused.
+It also helps us discern whether a `buffer-list-update-hook' was caused by a
+different window having been selected.
+
 This value should always be overwritten.")
 
+(defvar exwm-input--update-focus-window-buffer nil
+  "Buffer displayed in `exwm-input--update-focus-window'.
+Helps us discern whether a `buffer-list-update-hook' was caused by the selected
+window switching to a different buffer.")
+
 (defvar exwm-input--echo-area-timer nil "Timer for detecting echo area dirty.")
 
 (defvar exwm-input--event-hook nil
@@ -296,13 +304,25 @@ ARGS are additional arguments to CALLBACK."
 
 (defun exwm-input--on-buffer-list-update ()
   "Run in `buffer-list-update-hook' to track input focus."
-  (when (and (not (exwm-workspace--client-p))
-             (not exwm-input--skip-buffer-list-update))
-    (exwm--log "current-buffer=%S selected-window=%S"
-               (current-buffer) (selected-window))
-    (redirect-frame-focus (selected-frame) nil)
-    (setq exwm-input--update-focus-window (selected-window))
-    (exwm-input--update-focus-defer)))
+  ;; `buffer-list-update-hook' is invoked by several functions
+  ;; (`get-buffer-create', `select-window', `with-temp-buffer', etc.), but we
+  ;; just want to notice when a different window has been selected, or when the
+  ;; selected window displays a different buffer, so that we can set the focus
+  ;; to the associated X window (in case of an `exwm-mode' buffer).  In order to
+  ;; differentiate, we keep track of the last selected window and buffer in the
+  ;; `exwm-input--update-focus-window' and
+  ;; `exwm-input--update-focus-window-buffer' variables.
+  (let* ((win (selected-window))
+         (buf (window-buffer win)))
+    (when (and (not (exwm-workspace--client-p))
+             (not exwm-input--skip-buffer-list-update)
+               (not (and (eq exwm-input--update-focus-window win)
+                         (eq exwm-input--update-focus-window-buffer buf))))
+      (exwm--log "selected-window=%S current-buffer=%S" win buf)
+      (setq exwm-input--update-focus-window win)
+      (setq exwm-input--update-focus-window-buffer buf)
+      (redirect-frame-focus (selected-frame) nil)
+      (exwm-input--update-focus-defer))))
 
 (defun exwm-input--update-focus-defer ()
   "Defer updating input focus."