Another fix for input focus issues
* exwm-core.el (exwm--defer): * exwm-input.el (exwm-input--update-focus-defer): Avoid unnecessarily long delay. * exwm-input.el (exwm-input--on-FocusIn): Filter out FocusIn events generated as a result of grab/ungrab or when the keyboard is grabbed.
This commit is contained in:
parent
589b840409
commit
dd6596b1f4
2 changed files with 19 additions and 18 deletions
|
@ -76,10 +76,12 @@
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
|
|
||||||
(defmacro exwm--defer (secs function &rest args)
|
(defmacro exwm--defer (secs function &rest args)
|
||||||
"Defer the action until SECS seconds later.
|
"Defer the execution of FUNCTION.
|
||||||
|
|
||||||
The action is to call FUNCTION with arguments ARGS."
|
The action is to call FUNCTION with arguments ARGS. If Emacs is not idle,
|
||||||
`(run-with-idle-timer (time-add (or (current-idle-time) 0) ,secs)
|
defer the action until Emacs is idle. Otherwise, defer the action until at
|
||||||
|
least SECS seconds later."
|
||||||
|
`(run-with-idle-timer (time-add (or (current-idle-time) (- ,secs)) ,secs)
|
||||||
nil
|
nil
|
||||||
,function
|
,function
|
||||||
,@args))
|
,@args))
|
||||||
|
|
|
@ -116,18 +116,16 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(cdr exwm-input--timestamp-callback))
|
(cdr exwm-input--timestamp-callback))
|
||||||
(setq exwm-input--timestamp-callback nil)))))
|
(setq exwm-input--timestamp-callback nil)))))
|
||||||
|
|
||||||
(defun exwm-input--on-FocusIn (&rest _args)
|
(defun exwm-input--on-FocusIn (data _synthetic)
|
||||||
"Handle FocusIn events."
|
"Handle FocusIn events."
|
||||||
;; Not sure if this is the right thing to do but the point is the
|
(let ((obj (make-instance 'xcb:FocusIn)))
|
||||||
;; input focus should not stay at the root window or any container,
|
(xcb:unmarshal obj data)
|
||||||
;; or the result would be unpredictable. `x-focus-frame' would
|
(with-slots (mode) obj
|
||||||
;; first set the input focus to the (previously) selected frame, and
|
;; Revert input focus back to Emacs frame / X window when it's set on
|
||||||
;; then `select-window' would further update the input focus if the
|
;; the root window or some workspace container.
|
||||||
;; selected window is displaying an `exwm-mode' buffer. Perhaps we
|
(when (eq mode xcb:NotifyMode:Normal)
|
||||||
;; should carefully filter out FocusIn events with certain 'detail'
|
(x-focus-frame (selected-frame))
|
||||||
;; and 'mode' combinations, but this just works.
|
(select-window (selected-window))))))
|
||||||
(x-focus-frame (selected-frame))
|
|
||||||
(select-window (selected-window)))
|
|
||||||
|
|
||||||
(defun exwm-input--on-workspace-list-change ()
|
(defun exwm-input--on-workspace-list-change ()
|
||||||
"Run in `exwm-input--update-global-prefix-keys'."
|
"Run in `exwm-input--update-global-prefix-keys'."
|
||||||
|
@ -139,7 +137,6 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(make-instance 'xcb:ChangeWindowAttributes
|
(make-instance 'xcb:ChangeWindowAttributes
|
||||||
:window (frame-parameter f 'exwm-workspace)
|
:window (frame-parameter f 'exwm-workspace)
|
||||||
:value-mask xcb:CW:EventMask
|
:value-mask xcb:CW:EventMask
|
||||||
;; There should no other event selected there.
|
|
||||||
:event-mask xcb:EventMask:FocusChange))))
|
:event-mask xcb:EventMask:FocusChange))))
|
||||||
(exwm-input--update-global-prefix-keys)
|
(exwm-input--update-global-prefix-keys)
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
|
@ -193,9 +190,11 @@ This value should always be overwritten.")
|
||||||
(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
|
||||||
(exwm--defer exwm-input--update-focus-interval
|
;; Attempt to accumulate successive events close enough.
|
||||||
#'exwm-input--update-focus-commit
|
(run-with-timer exwm-input--update-focus-interval
|
||||||
exwm-input--update-focus-window))))
|
nil
|
||||||
|
#'exwm-input--update-focus-commit
|
||||||
|
exwm-input--update-focus-window))))
|
||||||
|
|
||||||
(declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id))
|
(declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id))
|
||||||
(declare-function exwm-layout--set-state "exwm-layout.el" (id state))
|
(declare-function exwm-layout--set-state "exwm-layout.el" (id state))
|
||||||
|
|
Loading…
Reference in a new issue