Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions exwm-input.el
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ defined in `exwm-mode-map' here."

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

(defvar exwm-input--skip-buffer-list-update nil
"Skip the upcoming 'buffer-list-update'.")

(defvar exwm-input--temp-line-mode nil
"Non-nil indicates it's in temporary line-mode for char-mode.")

Expand All @@ -138,8 +135,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
Expand Down Expand Up @@ -292,13 +297,24 @@ 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 (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."
Expand Down
7 changes: 2 additions & 5 deletions exwm-manage.el
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ want to match against EXWM internal variables such as `exwm-title',
(defvar exwm-manage--ping-lock nil
"Non-nil indicates EXWM is pinging a window.")

(defvar exwm-input--skip-buffer-list-update)
(defvar exwm-input-prefix-keys)
(defvar exwm-workspace--current)
(defvar exwm-workspace--id-struts-alist)
Expand Down Expand Up @@ -263,8 +262,7 @@ want to match against EXWM internal variables such as `exwm-title',
(make-instance 'xcb:ChangeSaveSet
:mode xcb:SetMode:Insert
:window id))
(with-current-buffer (let ((exwm-input--skip-buffer-list-update t))
(generate-new-buffer "*EXWM*"))
(with-current-buffer (generate-new-buffer "*EXWM*")
;; Keep the oldest X window first.
(setq exwm--id-buffer-alist
(nconc exwm--id-buffer-alist `((,id . ,(current-buffer)))))
Expand Down Expand Up @@ -349,8 +347,7 @@ want to match against EXWM internal variables such as `exwm-title',
:stack-mode xcb:StackMode:Below)))
(xcb:flush exwm--connection)
(setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
(let ((kill-buffer-query-functions nil)
(exwm-input--skip-buffer-list-update t))
(let ((kill-buffer-query-functions nil))
(kill-buffer (current-buffer)))
(throw 'return 'ignored))
(let ((index (plist-get exwm--configurations 'workspace)))
Expand Down