[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 71a3984 5/5: Fix various input focus issues
From: |
Chris Feng |
Subject: |
[elpa] externals/exwm 71a3984 5/5: Fix various input focus issues |
Date: |
Sun, 19 Nov 2017 02:17:48 -0500 (EST) |
branch: externals/exwm
commit 71a39840b239a51eed7455877517ebe612892eff
Author: Chris Feng <address@hidden>
Commit: Chris Feng <address@hidden>
Fix various input focus issues
* exwm-input.el (exwm-input--on-buffer-list-update): Cancel the frame
redirection introduced by 421c0512f7.
* exwm-input.el (exwm-input--on-buffer-list-update): Only ignore temp
buffers just switched from.
* exwm-input.el (exwm-input--update-focus-commit): New function for
ensuring the input focus lock can always be released.
(exwm-input--update-focus-defer, exwm-input--update-focus): Use it.
* exwm-input.el (exwm-input--update-focus): No need to select frames;
only transfer X input focus.
* exwm-core.el (exwm--defer): New macro for correcting the use of
`run-with-idle-timer' by taking `current-idle-time' into account.
* exwm-input.el (exwm-input--update-focus-defer)
(exwm-input--update-focus):
* exwm-layout.el (exwm-layout--on-minibuffer-setup)
(exwm-layout--on-echo-area-change):
* exwm-manage.el (exwm-manage--unmanage-window)
(exwm-workspace--prompt-delete):
* exwm-workspace.el (exwm-workspace-switch)
(exwm-workspace--add-frame-as-workspace):
Use it.
---
exwm-core.el | 9 +++++++++
exwm-input.el | 37 +++++++++++++++++++------------------
exwm-layout.el | 9 ++++-----
exwm-manage.el | 2 +-
exwm-workspace.el | 13 ++++++-------
5 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/exwm-core.el b/exwm-core.el
index 750f134..146594d 100644
--- a/exwm-core.el
+++ b/exwm-core.el
@@ -75,6 +75,15 @@
xcb:EventMask:StructureNotify))))
(xcb:flush exwm--connection))
+(defmacro exwm--defer (secs function &rest args)
+ "Defer the action until SECS seconds later.
+
+The action is to call FUNCTION with arguments ARGS."
+ `(run-with-idle-timer (time-add (or (current-idle-time) 0) ,secs)
+ nil
+ ,function
+ ,@args))
+
(defconst exwm--client-event-mask
(eval-when-compile
(logior xcb:EventMask:StructureNotify xcb:EventMask:PropertyChange))
diff --git a/exwm-input.el b/exwm-input.el
index 3a817be..6a60ac3 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -158,7 +158,9 @@ This value should always be overwritten.")
;; The following conditions filter out events relating to temp
;; buffers.
(eq (current-buffer) (window-buffer))
- (not (get-buffer " *temp*")))
+ (not (string-prefix-p " *temp*"
+ (buffer-name (car (last (buffer-list)))))))
+ (redirect-frame-focus (selected-frame) nil)
(setq exwm-input--update-focus-window (selected-window))
(exwm-input--update-focus-defer)))
@@ -186,15 +188,14 @@ This value should always be overwritten.")
(cancel-timer exwm-input--update-focus-defer-timer))
(if exwm-input--update-focus-lock
(setq exwm-input--update-focus-defer-timer
- (run-with-idle-timer 0 nil
- #'exwm-input--update-focus-defer))
+ (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
- (run-with-idle-timer exwm-input--update-focus-interval nil
- #'exwm-input--update-focus
- exwm-input--update-focus-window))))
+ (exwm--defer exwm-input--update-focus-interval
+ #'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--set-state "exwm-layout.el" (id state))
@@ -203,17 +204,22 @@ This value should always be overwritten.")
(frame-or-index &optional force))
(declare-function exwm-workspace--workspace-p "exwm-workspace.el" (workspace))
+(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)))
+
(defun exwm-input--update-focus (window)
"Update input focus."
- (setq exwm-input--update-focus-lock t)
(when (window-live-p window)
(with-current-buffer (window-buffer window)
(if (eq major-mode 'exwm-mode)
(if (not (eq exwm--frame exwm-workspace--current))
(progn
(set-frame-parameter exwm--frame 'exwm-selected-window window)
- (run-with-idle-timer 0 nil #'exwm-workspace-switch
- exwm--frame))
+ (exwm--defer 0 #'exwm-workspace-switch exwm--frame))
(exwm--log "Set focus on #x%x" exwm--id)
(exwm-input--set-focus exwm--id)
(when exwm--floating-frame
@@ -237,21 +243,16 @@ This value should always be overwritten.")
(progn
(set-frame-parameter (selected-frame) 'exwm-selected-window
window)
- (run-with-idle-timer 0 nil #'exwm-workspace-switch
- (selected-frame)))
+ (exwm--defer 0 #'exwm-workspace-switch (selected-frame)))
;; The focus is still on the current workspace.
(if (not (and (exwm-workspace--minibuffer-own-frame-p)
(minibufferp)))
- (select-frame-set-input-focus (window-frame window) t)
+ (x-focus-frame (window-frame window))
;; X input focus should be set on the previously selected
;; frame.
- (select-frame-set-input-focus (window-frame
- (minibuffer-selected-window))
- t)
- (select-frame (window-frame window) t))
+ (x-focus-frame (window-frame (minibuffer-selected-window))))
(exwm-input--set-active-window)
- (xcb:flush exwm--connection))))))
- (setq exwm-input--update-focus-lock nil))
+ (xcb:flush exwm--connection)))))))
(defun exwm-input--on-minibuffer-setup ()
"Run in `minibuffer-setup-hook' to set input focus."
diff --git a/exwm-layout.el b/exwm-layout.el
index ba7f65c..29273a9 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -407,10 +407,9 @@ selected by `other-buffer'."
(defun exwm-layout--on-minibuffer-setup ()
"Refresh layout when minibuffer grows."
(unless (exwm-workspace--client-p)
- (run-with-idle-timer 0.01 nil ;FIXME
- (lambda ()
- (when (< 1 (window-height (minibuffer-window)))
- (exwm-layout--refresh))))))
+ (exwm--defer 0 (lambda ()
+ (when (< 1 (window-height (minibuffer-window)))
+ (exwm-layout--refresh))))))
(defun exwm-layout--on-echo-area-change (&optional dirty)
"Run when message arrives or in `echo-area-clear-hook' to refresh layout."
@@ -421,7 +420,7 @@ selected by `other-buffer'."
(frame-width exwm-workspace--current))))
(if dirty
(exwm-layout--refresh)
- (run-with-idle-timer 0.01 nil #'exwm-layout--refresh)))) ;FIXME
+ (exwm--defer 0 #'exwm-layout--refresh))))
;;;###autoload
(defun exwm-layout-enlarge-window (delta &optional horizontal)
diff --git a/exwm-manage.el b/exwm-manage.el
index fffc677..2b96475 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -410,7 +410,7 @@ manager is shutting down."
(select-window
(frame-selected-window exwm-workspace--current)))
(kill-buffer buffer)))))
- (run-with-idle-timer 0 nil kill-buffer-func buffer)
+ (exwm--defer 0 kill-buffer-func buffer)
(when (active-minibuffer-window)
(exit-minibuffer))))))
diff --git a/exwm-workspace.el b/exwm-workspace.el
index bebd954..d513172 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -145,7 +145,7 @@ Please manually run the hook
`exwm-workspace-list-change-hook' afterwards.")
(if (eq frame exwm-workspace--current)
;; Abort the recursive minibuffer if deleting the current workspace.
(progn
- (run-with-idle-timer 0 nil #'delete-frame frame)
+ (exwm--defer 0 #'delete-frame frame)
(abort-recursive-edit))
(delete-frame frame)
(exwm-workspace--update-switch-history)
@@ -488,10 +488,10 @@ The optional FORCE option is for internal use only."
(set-frame-parameter frame 'exwm-selected-window nil)
;; Close the (possible) active minibuffer
(when (active-minibuffer-window)
- (run-with-idle-timer 0 nil (lambda ()
- ;; Might be aborted by then.
- (when (active-minibuffer-window)
- (abort-recursive-edit)))))
+ (exwm--defer 0 (lambda ()
+ ;; Might be aborted by then.
+ (when (active-minibuffer-window)
+ (abort-recursive-edit)))))
(if (exwm-workspace--minibuffer-own-frame-p)
;; Resize the minibuffer frame.
(exwm-workspace--resize-minibuffer-frame)
@@ -1275,8 +1275,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p'
first."
(make-instance 'xcb:MapWindow :window workspace)))
(xcb:flush exwm--connection)
;; Delay making the workspace fullscreen until Emacs becomes idle
- (run-with-idle-timer 0 nil #'set-frame-parameter
- frame 'fullscreen 'fullboth)
+ (exwm--defer 0 #'set-frame-parameter frame 'fullscreen 'fullboth)
;; Update EWMH properties.
(exwm-workspace--update-ewmh-props)
(if exwm-workspace--create-silently