about summary refs log tree commit diff
path: root/exwm-floating.el
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2016-02-20T06·52+0800
committerChris Feng <chris.w.feng@gmail.com>2016-02-20T06·52+0800
commit1c79e1c2384128915357ea629fc2a0503bd36733 (patch)
treeea513389fc4628128d78b6d6a4080b93dba6e945 /exwm-floating.el
parent33254c37df052996d63ff2a55efeb2b6e8799694 (diff)
Prevent/Reduce flickering issues with floating X windows
* exwm-floating.el (exwm-floating--set-floating)
(exwm-floating--unset-floating): Prevent flickering when creating/removing
a floating X window.
* exwm-layout.el (exwm-layout--show): Show X windows after resizing to
prevent flickering.
* exwm-manage.el (exwm-manage--unmanage-window): Reduce flickering by
hiding the container.
(exwm-manage--kill-buffer-query-function): Prevent flickering by hiding the
container (except that the X window destroys itself after receiving the
WM_DELETE_WINDOW client message).
Diffstat (limited to 'exwm-floating.el')
-rw-r--r--exwm-floating.el35
1 files changed, 30 insertions, 5 deletions
diff --git a/exwm-floating.el b/exwm-floating.el
index 209539eb4a..276948801d 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -193,17 +193,42 @@
       (remove-hook 'window-configuration-change-hook #'exwm-layout--refresh)
       (set-window-buffer window (current-buffer)) ;this changes current buffer
       (add-hook 'window-configuration-change-hook #'exwm-layout--refresh)
-      (set-window-dedicated-p window t)
-      (exwm-layout--show id window))
-    (select-frame-set-input-focus frame))
-  (run-hooks 'exwm-floating-setup-hook))
+      (set-window-dedicated-p window t))
+    (select-frame-set-input-focus frame)
+    ;; `x_make_frame_visible' autoraises the frame.  Force lowering it.
+    (xcb:+request exwm--connection
+        (make-instance 'xcb:ConfigureWindow
+                       :window outer-id
+                       :value-mask xcb:ConfigWindow:StackMode
+                       :stack-mode xcb:StackMode:Below))
+    ;; Show the X window with its container (and flush).
+    (exwm-layout--show id window))
+  (run-hooks 'exwm-floating-setup-hook)
+  ;; Redraw the frame.
+  (redisplay))
 
 (defun exwm-floating--unset-floating (id)
   "Make window ID non-floating."
   (let ((buffer (exwm--id->buffer id)))
     (with-current-buffer buffer
-      ;; Reparent the frame back to the root window.
       (when exwm--floating-frame
+        ;; The X window is already mapped.
+        ;; Unmap the container to prevent flickering.
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:UnmapWindow :window exwm--container))
+        (xcb:flush exwm--connection)
+        ;; Unmap the X window.
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ChangeWindowAttributes
+                           :window id :value-mask xcb:CW:EventMask
+                           :event-mask xcb:EventMask:NoEvent))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:UnmapWindow :window id))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ChangeWindowAttributes
+                           :window id :value-mask xcb:CW:EventMask
+                           :event-mask exwm--client-event-mask))
+        ;; Reparent the floating frame back to the root window.
         (let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id)))
           (xcb:+request exwm--connection
               (make-instance 'xcb:UnmapWindow :window frame-id))