about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--exwm-core.el9
-rw-r--r--exwm-input.el37
-rw-r--r--exwm-layout.el9
-rw-r--r--exwm-manage.el2
-rw-r--r--exwm-workspace.el13
5 files changed, 39 insertions, 31 deletions
diff --git a/exwm-core.el b/exwm-core.el
index 750f134d1e8f..146594da0a16 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 3a817be4cd6e..6a60ac35d082 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 ba7f65cf3bab..29273a933e2d 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 fffc677c7f0e..2b964756351c 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 bebd954940f2..d513172b66f5 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