Skip to content

Commit ad8cddc

Browse files
committed
Improve detection of focus changes
* exwm-input.el: (exwm-input--on-buffer-list-update): Keep track of last selected window and buffer, update focus only when those change. (exwm-input--update-focus-defer): Add commentary. (exwm-input--buffer-list-update-last-selected-window) (exwm-input--buffer-list-update-last-selected-buffer): Add variables. (exwm-input--skip-buffer-list-update): Remove variable. (exwm-input--on-buffer-list-update): Stop checking `exwm-input--skip-buffer-list-update'; it's no longer needed when keeping track selected window and buffer. * exwm-manage.el (exwm-manage--manage-window): Remove binding of `exwm-input--skip-buffer-list-update'.
1 parent 95d6aa9 commit ad8cddc

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

exwm-input.el

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ defined in `exwm-mode-map' here."
117117

118118
(defvar exwm-input--simulation-keys nil "Simulation keys in line-mode.")
119119

120-
(defvar exwm-input--skip-buffer-list-update nil
121-
"Skip the upcoming 'buffer-list-update'.")
122-
123120
(defvar exwm-input--temp-line-mode nil
124121
"Non-nil indicates it's in temporary line-mode for char-mode.")
125122

@@ -140,6 +137,12 @@ defined in `exwm-mode-map' here."
140137
(defvar exwm-input--update-focus-window nil "The (Emacs) window to be focused.
141138
This value should always be overwritten.")
142139

140+
(defvar exwm-input--last-selected-window nil
141+
"Last selected window. Help us discern cause of `buffer-list-update-hook'.")
142+
143+
(defvar exwm-input--last-selected-buffer nil
144+
"Last selected window. Help us discern cause of `buffer-list-update-hook'.")
145+
143146
(defvar exwm-input--echo-area-timer nil "Timer for detecting echo area dirty.")
144147

145148
(defvar exwm-input--event-hook nil
@@ -292,13 +295,25 @@ ARGS are additional arguments to CALLBACK."
292295

293296
(defun exwm-input--on-buffer-list-update ()
294297
"Run in `buffer-list-update-hook' to track input focus."
295-
(when (and (not (exwm-workspace--client-p))
296-
(not exwm-input--skip-buffer-list-update))
297-
(exwm--log "current-buffer=%S selected-window=%S"
298-
(current-buffer) (selected-window))
299-
(redirect-frame-focus (selected-frame) nil)
300-
(setq exwm-input--update-focus-window (selected-window))
301-
(exwm-input--update-focus-defer)))
298+
;; `buffer-list-update-hook' is invoked by several functions
299+
;; (`get-buffer-create', `select-window', `with-temp-buffer', etc.), but we
300+
;; just want to notice when a different window has been selected, or when the
301+
;; selected window displays a different buffer, so that we can set the focus
302+
;; to the associated X window (in case of an `exwm-mode' buffer). In order to
303+
;; differentiate, we keep track of the last selected window and buffer in the
304+
;; `exwm-input--last-selected-window' and
305+
;; `exwm-input--last-selected-buffer' variables.
306+
(let* ((win (selected-window))
307+
(buf (window-buffer win)))
308+
(when (and (not (exwm-workspace--client-p))
309+
(not (and (eq exwm-input--last-selected-window win)
310+
(eq exwm-input--last-selected-buffer buf))))
311+
(setq exwm-input--last-selected-window win)
312+
(setq exwm-input--last-selected-buffer buf)
313+
(exwm--log "selected-window=%S current-buffer=%S" win buf)
314+
(redirect-frame-focus (selected-frame) nil)
315+
(setq exwm-input--update-focus-window (selected-window))
316+
(exwm-input--update-focus-defer))))
302317

303318
(defun exwm-input--update-focus-defer ()
304319
"Defer updating input focus."

exwm-manage.el

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ want to match against EXWM internal variables such as `exwm-title',
151151
(defvar exwm-manage--ping-lock nil
152152
"Non-nil indicates EXWM is pinging a window.")
153153

154-
(defvar exwm-input--skip-buffer-list-update)
155154
(defvar exwm-input-prefix-keys)
156155
(defvar exwm-workspace--current)
157156
(defvar exwm-workspace--id-struts-alist)
@@ -263,8 +262,7 @@ want to match against EXWM internal variables such as `exwm-title',
263262
(make-instance 'xcb:ChangeSaveSet
264263
:mode xcb:SetMode:Insert
265264
:window id))
266-
(with-current-buffer (let ((exwm-input--skip-buffer-list-update t))
267-
(generate-new-buffer "*EXWM*"))
265+
(with-current-buffer (generate-new-buffer "*EXWM*")
268266
;; Keep the oldest X window first.
269267
(setq exwm--id-buffer-alist
270268
(nconc exwm--id-buffer-alist `((,id . ,(current-buffer)))))
@@ -349,8 +347,7 @@ want to match against EXWM internal variables such as `exwm-title',
349347
:stack-mode xcb:StackMode:Below)))
350348
(xcb:flush exwm--connection)
351349
(setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
352-
(let ((kill-buffer-query-functions nil)
353-
(exwm-input--skip-buffer-list-update t))
350+
(let ((kill-buffer-query-functions nil))
354351
(kill-buffer (current-buffer)))
355352
(throw 'return 'ignored))
356353
(let ((index (plist-get exwm--configurations 'workspace)))

0 commit comments

Comments
 (0)