From 3a6da21189a3e4d9df5891e24f968d3497cb94ba Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Sun, 2 Apr 2023 10:04:03 -0700 Subject: refactor(3p/exwm): Simplify and improve focus handling - No need for two different timers, roll them into one. - Debounce focus updates. - Handle "no focus" frames. Depot note: This patch was taken from Sibalien's fork of EXWM, and I'm experimentally adding it here to see if it has any effect on wonkiness around focusing. Change-Id: Ifabfccc80817daabedd31e51532aef3c4277e2ed Reviewed-on: https://cl.tvl.fyi/c/depot/+/10046 Reviewed-by: tazjin Tested-by: BuildkiteCI --- third_party/exwm/exwm-input.el | 47 +++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) (limited to 'third_party') diff --git a/third_party/exwm/exwm-input.el b/third_party/exwm/exwm-input.el index 05b021093c..4c762c40fe 100644 --- a/third_party/exwm/exwm-input.el +++ b/third_party/exwm/exwm-input.el @@ -129,17 +129,12 @@ defined in `exwm-mode-map' here." (defvar exwm-input--timestamp-window nil) -(defvar exwm-input--update-focus-defer-timer nil "Timer for polling the lock.") - (defvar exwm-input--update-focus-lock nil "Lock for solving input focus update contention.") (defvar exwm-input--update-focus-timer nil "Timer for deferring the update of input focus.") -(defvar exwm-input--update-focus-window nil "The (Emacs) window to be focused. -This value should always be overwritten.") - (defvar exwm-input--echo-area-timer nil "Timer for detecting echo area dirty.") (defvar exwm-input--event-hook nil @@ -299,37 +294,35 @@ ARGS are additional arguments to CALLBACK." (exwm--terminal-p)) ; skip other terminals, e.g. TTY client frames (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))) (defun exwm-input--update-focus-defer () "Defer updating input focus." - (when exwm-input--update-focus-defer-timer - (cancel-timer exwm-input--update-focus-defer-timer)) - (if exwm-input--update-focus-lock - (setq exwm-input--update-focus-defer-timer - (exwm--defer 0 #'exwm-input--update-focus-defer)) - (setq exwm-input--update-focus-defer-timer nil) - (when exwm-input--update-focus-timer - (cancel-timer exwm-input--update-focus-timer)) - (setq exwm-input--update-focus-timer - ;; Attempt to accumulate successive events close enough. - (run-with-timer exwm-input--update-focus-interval - nil - #'exwm-input--update-focus-commit - exwm-input--update-focus-window)))) + (redirect-frame-focus (selected-frame) nil) + (when exwm-input--update-focus-timer + (cancel-timer exwm-input--update-focus-timer)) + (setq exwm-input--update-focus-timer + ;; Attempt to accumulate successive events close enough. + (run-with-timer exwm-input--update-focus-interval + nil + #'exwm-input--update-focus-commit + (selected-window)))) (defun exwm-input--update-focus-commit (window) "Commit updating input focus." - (setq exwm-input--update-focus-lock t) - (unwind-protect - (exwm-input--update-focus window) - (setq exwm-input--update-focus-lock nil))) + (let ((cwin (selected-window))) + (if exwm-input--update-focus-lock + (unless (eq exwm-input--update-focus-lock cwin) + (exwm-input--update-focus-defer)) + (if (and cwin window (eq cwin window)) + (let ((exwm-input--update-focus-lock cwin)) + (exwm-input--update-focus window)) + (exwm-input--update-focus-defer))))) (defun exwm-input--update-focus (window) "Update input focus." - (when (window-live-p window) + (when (and (window-live-p window) + (not (frame-parameter (window-frame window) 'no-accept-focus))) (exwm--log "focus-window=%s focus-buffer=%s" window (window-buffer window)) (with-current-buffer (window-buffer window) (if (derived-mode-p 'exwm-mode) @@ -1233,8 +1226,6 @@ One use is to access the keymap bound to KEYS (as prefix keys) in `char-mode'." (setq exwm-input--echo-area-timer nil)) (remove-hook 'echo-area-clear-hook #'exwm-input--on-echo-area-clear) (remove-hook 'buffer-list-update-hook #'exwm-input--on-buffer-list-update) - (when exwm-input--update-focus-defer-timer - (cancel-timer exwm-input--update-focus-defer-timer)) (when exwm-input--update-focus-timer (cancel-timer exwm-input--update-focus-timer)) ;; Make input focus working even without a WM. -- cgit 1.4.1