mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-30 16:07:59 +01:00
Simplify and improve focus handling
- No need for two different timers, roll them into one. - Debounce focus updates, waiting until the focus has stabilized for a full focus interval. - Ignore windows in "no focus" frames. * exwm-input.el (exwm-input--update-focus-defer-timer): Remove the duplicate timer. (exwm-input--update-focus-lock): Bind `exwm-input--update-focus-window` instead. (exwm-input--on-buffer-list-update): Move focus logic to `exwm-input--update-focus-defer`. (exwm-input--update-focus-defer): Use a single `exwm-input--update-focus-timer` and don't record the window we're focusing, we pass that into `exwm-input--update-focus-commit` anyways. (exwm-input--update-focus-commit): Debounce focus updates and only commit them if the currently selected window matches the selected window when `exwm-input--update-focus-defer` was called. (exwm-input--update-focus-commit): Let-bind the window we're attempting to focus instead of setting a "locked" flag. This lets us deduplicate recursive attempts to re-focus the current window. (exwm-input--update-focus): Avoid focusing windows in frames with the `no-accept-focus` frame property. (exwm-input--exit): Remove references to `exwm-input--update-focus-defer-timer`.
This commit is contained in:
parent
089e0c8683
commit
b4aac53086
1 changed files with 26 additions and 30 deletions
|
@ -135,16 +135,11 @@ defined in `exwm-mode-map' here."
|
||||||
|
|
||||||
(defvar exwm-input--timestamp-window nil)
|
(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
|
(defvar exwm-input--update-focus-timer nil
|
||||||
"Timer for deferring the update of input focus.")
|
"Timer for deferring the update of input focus.")
|
||||||
|
|
||||||
(defvar exwm-input--update-focus-window nil "The (Emacs) window to be focused.
|
(defvar exwm-input--update-focus-window nil
|
||||||
This value should always be overwritten.")
|
"The window we're currently attempting to focus.")
|
||||||
|
|
||||||
(defvar exwm-input--echo-area-timer nil "Timer for detecting echo area dirty.")
|
(defvar exwm-input--echo-area-timer nil "Timer for detecting echo area dirty.")
|
||||||
|
|
||||||
|
@ -305,18 +300,11 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(exwm--terminal-p)) ; skip other terminals, e.g. TTY client frames
|
(exwm--terminal-p)) ; skip other terminals, e.g. TTY client frames
|
||||||
(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)
|
|
||||||
(setq exwm-input--update-focus-window (selected-window))
|
|
||||||
(exwm-input--update-focus-defer)))
|
(exwm-input--update-focus-defer)))
|
||||||
|
|
||||||
(defun exwm-input--update-focus-defer ()
|
(defun exwm-input--update-focus-defer ()
|
||||||
"Defer updating input focus."
|
"Defer updating input focus."
|
||||||
(when exwm-input--update-focus-defer-timer
|
(redirect-frame-focus (selected-frame) nil)
|
||||||
(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
|
(when exwm-input--update-focus-timer
|
||||||
(cancel-timer exwm-input--update-focus-timer))
|
(cancel-timer exwm-input--update-focus-timer))
|
||||||
(setq exwm-input--update-focus-timer
|
(setq exwm-input--update-focus-timer
|
||||||
|
@ -324,18 +312,28 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(run-with-timer exwm-input--update-focus-interval
|
(run-with-timer exwm-input--update-focus-interval
|
||||||
nil
|
nil
|
||||||
#'exwm-input--update-focus-commit
|
#'exwm-input--update-focus-commit
|
||||||
exwm-input--update-focus-window))))
|
(selected-window))))
|
||||||
|
|
||||||
(defun exwm-input--update-focus-commit (window)
|
(defun exwm-input--update-focus-commit (window)
|
||||||
"Commit updating input focus."
|
"Commit updating input focus."
|
||||||
(setq exwm-input--update-focus-lock t)
|
(let ((cwin (selected-window)))
|
||||||
(unwind-protect
|
(if exwm-input--update-focus-window
|
||||||
(exwm-input--update-focus window)
|
;; If we're currently focusing another window, enqueue a task to
|
||||||
(setq exwm-input--update-focus-lock nil)))
|
;; update the focus again after we're done. Otherwise, if we're
|
||||||
|
;; working on focusing this window, discard the duplicate event.
|
||||||
|
(unless (eq exwm-input--update-focus-window cwin)
|
||||||
|
(exwm-input--update-focus-defer))
|
||||||
|
;; Debounce focus updates. If we've switched windows since we scheduled
|
||||||
|
;; the focus commit, wait again until we've stabilized on a window.
|
||||||
|
(if (and cwin window (eq cwin window))
|
||||||
|
(let ((exwm-input--update-focus-window cwin))
|
||||||
|
(exwm-input--update-focus window))
|
||||||
|
(exwm-input--update-focus-defer)))))
|
||||||
|
|
||||||
(defun exwm-input--update-focus (window)
|
(defun exwm-input--update-focus (window)
|
||||||
"Update input focus."
|
"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))
|
(exwm--log "focus-window=%s focus-buffer=%s" window (window-buffer window))
|
||||||
(with-current-buffer (window-buffer window)
|
(with-current-buffer (window-buffer window)
|
||||||
(if (derived-mode-p 'exwm-mode)
|
(if (derived-mode-p 'exwm-mode)
|
||||||
|
@ -1234,8 +1232,6 @@ One use is to access the keymap bound to KEYS (as prefix keys) in `char-mode'."
|
||||||
(setq exwm-input--echo-area-timer nil))
|
(setq exwm-input--echo-area-timer nil))
|
||||||
(remove-hook 'echo-area-clear-hook #'exwm-input--on-echo-area-clear)
|
(remove-hook 'echo-area-clear-hook #'exwm-input--on-echo-area-clear)
|
||||||
(remove-hook 'buffer-list-update-hook #'exwm-input--on-buffer-list-update)
|
(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
|
(when exwm-input--update-focus-timer
|
||||||
(cancel-timer exwm-input--update-focus-timer))
|
(cancel-timer exwm-input--update-focus-timer))
|
||||||
;; Make input focus working even without a WM.
|
;; Make input focus working even without a WM.
|
||||||
|
|
Loading…
Reference in a new issue