about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--exwm-floating.el109
-rw-r--r--exwm-input.el14
-rw-r--r--exwm-layout.el88
-rw-r--r--exwm-manage.el42
-rw-r--r--exwm-workspace.el60
5 files changed, 192 insertions, 121 deletions
diff --git a/exwm-floating.el b/exwm-floating.el
index 276948801d95..1ec54d10fa71 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -90,6 +90,7 @@
          (outer-id (string-to-number (frame-parameter frame 'outer-window-id)))
          (container (with-current-buffer (exwm--id->buffer id)
                       exwm--container))
+         (frame-container (xcb:generate-id exwm--connection))
          (window (frame-first-window frame)) ;and it's the only window
          (x (slot-value exwm--geometry 'x))
          (y (slot-value exwm--geometry 'y))
@@ -103,8 +104,9 @@
             y (- y (slot-value frame-geometry 'y))))
     (exwm--log "Floating geometry (original, relative): %dx%d%+d%+d"
                width height x y)
-    ;; Save window IDs
+    ;; Save frame parameters.
     (set-frame-parameter frame 'exwm-outer-id outer-id)
+    (set-frame-parameter frame 'exwm-container frame-container)
     ;; Set urgency flag if it's not appear in the active workspace
     (let ((idx (cl-position original-frame exwm-workspace--list)))
       (when (/= idx exwm-workspace-current-index)
@@ -163,18 +165,43 @@
     ;; timely.
     ;; The frame will be made visible by `select-frame-set-input-focus'.
     (make-frame-invisible frame)
-    (let ((edges (window-inside-pixel-edges window)))
-      (set-frame-size frame
-                      (+ width (- (frame-pixel-width frame)
-                                  (- (elt edges 2) (elt edges 0))))
-                      (+ height (- (frame-pixel-height frame)
-                                   (- (elt edges 3) (elt edges 1))))
-                      t))
-    ;; Reparent this frame to the container
+    (let* ((edges (window-inside-pixel-edges window))
+           (frame-width (+ width (- (frame-pixel-width frame)
+                                    (- (elt edges 2) (elt edges 0)))))
+           (frame-height (+ height (- (frame-pixel-height frame)
+                                      (- (elt edges 3) (elt edges 1))))))
+      (set-frame-size frame frame-width frame-height t)
+      ;; Create the frame container as the parent of the frame and
+      ;; a child of the X window container.
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:CreateWindow
+                         :depth 0 :wid frame-container
+                         :parent container
+                         :x 0 :y 0 :width width :height height :border-width 0
+                         :class xcb:WindowClass:CopyFromParent
+                         :visual 0      ;CopyFromParent
+                         :value-mask xcb:CW:OverrideRedirect
+                         :override-redirect 1))
+      ;; Put it at bottom.
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:ConfigureWindow
+                         :window frame-container
+                         :value-mask xcb:ConfigWindow:StackMode
+                         :stack-mode xcb:StackMode:Below))
+      ;; Map it.
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:MapWindow :window frame-container))
+      (exwm--debug
+       (xcb:+request exwm--connection
+           (make-instance 'xcb:ewmh:set-_NET_WM_NAME
+                          :window frame-container
+                          :data
+                          (format "floating frame container for 0x%x" id)))))
+    ;; Reparent this frame to its container.
     (xcb:+request exwm--connection
         (make-instance 'xcb:ReparentWindow
-                       :window outer-id :parent container :x 0 :y 0))
-    ;; Place the container
+                       :window outer-id :parent frame-container :x 0 :y 0))
+    ;; Place the X window container.
     (xcb:+request exwm--connection
         (make-instance 'xcb:ConfigureWindow
                        :window container
@@ -193,16 +220,9 @@
       (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))
-    (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))
+      (set-window-dedicated-p window t)
+      (exwm-layout--show id window))
+    (select-frame-set-input-focus frame))
   (run-hooks 'exwm-floating-setup-hook)
   ;; Redraw the frame.
   (redisplay))
@@ -229,29 +249,28 @@
                            :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)))
+        (let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id))
+              (frame-container (frame-parameter exwm--floating-frame
+                                                'exwm-container)))
           (xcb:+request exwm--connection
               (make-instance 'xcb:UnmapWindow :window frame-id))
           (xcb:+request exwm--connection
               (make-instance 'xcb:ReparentWindow
                              :window frame-id
                              :parent exwm--root
-                             :x 0 :y 0))))
-      ;; Reparent the container to the workspace
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:ReparentWindow
-                         :window exwm--container
-                         :parent (frame-parameter exwm-workspace--current
-                                                  'exwm-workspace)
-                         :x 0 :y 0))    ;temporary position
-      ;; Put the container just above the Emacs frame
+                             :x 0 :y 0))
+          ;; Also destroy its container.
+          (xcb:+request exwm--connection
+              (make-instance 'xcb:DestroyWindow :window frame-container))))
+      ;; Put the X window container just above the Emacs frame container
+      ;; (the stacking order won't change from now on).
       (xcb:+request exwm--connection
           (make-instance 'xcb:ConfigureWindow
                          :window exwm--container
                          :value-mask (logior xcb:ConfigWindow:Sibling
                                              xcb:ConfigWindow:StackMode)
                          :sibling (frame-parameter exwm-workspace--current
-                                                   'exwm-outer-id)
+                                                   'exwm-container)
                          :stack-mode xcb:StackMode:Above)))
     (xcb:flush exwm--connection)
     (with-current-buffer buffer
@@ -466,13 +485,19 @@
           (geometry (frame-parameter exwm-workspace--current 'exwm-geometry))
           (frame-x 0)
           (frame-y 0)
-          result)
+          result value-mask width height)
       (when geometry
         (setq frame-x (slot-value geometry 'x)
               frame-y (slot-value geometry 'y)))
       (xcb:unmarshal obj data)
       (setq result (funcall exwm-floating--moveresize-calculate
-                            (slot-value obj 'root-x) (slot-value obj 'root-y)))
+                            (slot-value obj 'root-x) (slot-value obj 'root-y))
+            value-mask (logand (aref result 1)
+                               (eval-when-compile
+                                 (logior xcb:ConfigWindow:Width
+                                         xcb:ConfigWindow:Height)))
+            width (aref result 4)
+            height (aref result 5))
       (with-current-buffer (aref result 0)
         (xcb:+request exwm--connection
             (make-instance 'xcb:ConfigureWindow
@@ -486,13 +511,17 @@
         (xcb:+request exwm--connection
             (make-instance 'xcb:ConfigureWindow
                            :window (frame-parameter exwm--floating-frame
+                                                    'exwm-container)
+                           :value-mask value-mask
+                           :width width
+                           :height height))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window (frame-parameter exwm--floating-frame
                                                     'exwm-outer-id)
-                           :value-mask
-                           (logand (aref result 1)
-                                   (eval-when-compile
-                                     (logior xcb:ConfigWindow:Width
-                                             xcb:ConfigWindow:Height)))
-                           :width (aref result 4) :height (aref result 5))))
+                           :value-mask value-mask
+                           :width width
+                           :height height)))
       (xcb:flush exwm--connection))))
 
 (defun exwm-floating-move (&optional delta-x delta-y)
diff --git a/exwm-input.el b/exwm-input.el
index 5e078030c2ef..0a50bef26203 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -113,8 +113,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
                 (exwm-workspace-switch exwm-workspace-current-index t))
             (exwm--log "Set focus on #x%x" exwm--id)
             (exwm-input--set-focus exwm--id)
-            ;; Adjust stacking orders
             (when exwm--floating-frame
+              ;; Adjust stacking orders of the floating container.
               (if (exwm-workspace--minibuffer-own-frame-p)
                   ;; Put this floating X window just below the minibuffer.
                   (xcb:+request exwm--connection
@@ -132,16 +132,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
                     (make-instance 'xcb:ConfigureWindow
                                    :window exwm--container
                                    :value-mask xcb:ConfigWindow:StackMode
-                                   :stack-mode xcb:StackMode:Above))))
-            ;; Make sure Emacs frames are at bottom.
-            (xcb:+request exwm--connection
-                (make-instance 'xcb:ConfigureWindow
-                               :window (frame-parameter
-                                        (or exwm--floating-frame exwm--frame)
-                                        'exwm-outer-id)
-                               :value-mask xcb:ConfigWindow:StackMode
-                               :stack-mode xcb:StackMode:BottomIf))
-            (xcb:flush exwm--connection))
+                                   :stack-mode xcb:StackMode:Above)))
+              (xcb:flush exwm--connection)))
         (when (eq (selected-window) exwm-input--focus-window)
           (exwm--log "Focus on %s" exwm-input--focus-window)
           (select-frame-set-input-focus (window-frame exwm-input--focus-window)
diff --git a/exwm-layout.el b/exwm-layout.el
index e3c1febc4478..c9146de3714e 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -55,37 +55,46 @@
   (exwm--log "Show #x%x in %s" id window)
   (let* ((edges (window-inside-absolute-pixel-edges window))
          (width (- (elt edges 2) (elt edges 0)))
-         (height (- (elt edges 3) (elt edges 1))))
+         (height (- (elt edges 3) (elt edges 1)))
+         frame-width frame-height)
     (with-current-buffer (exwm--id->buffer id)
-      (if exwm--floating-frame
-          ;; A floating X window is of the same size as the Emacs window,
-          ;; whereas its container is of the same size as the Emacs frame.
-          (progn
-            (xcb:+request exwm--connection
-                (make-instance 'xcb:ConfigureWindow
-                               :window exwm--container
-                               :value-mask (logior xcb:ConfigWindow:Width
-                                                   xcb:ConfigWindow:Height)
-                               :width (frame-pixel-width exwm--floating-frame)
-                               :height (frame-pixel-height
-                                        exwm--floating-frame)))
-            (xcb:+request exwm--connection
-                (make-instance 'xcb:ConfigureWindow
-                               :window exwm--id
-                               :value-mask (logior xcb:ConfigWindow:X
-                                                   xcb:ConfigWindow:Y
-                                                   xcb:ConfigWindow:Width
-                                                   xcb:ConfigWindow:Height)
-                               :x exwm-floating-border-width
-                               :y exwm-floating-border-width
-                               :width width
-                               :height height)))
-        (let ((relative-edges (window-inside-pixel-edges window)))
-          (exwm-layout--resize-container id exwm--container
-                                         (elt relative-edges 0)
-                                         (elt relative-edges 1)
-                                         width height
-                                         (active-minibuffer-window))))
+      (if (not exwm--floating-frame)
+          (let ((relative-edges (window-inside-pixel-edges window)))
+            (exwm-layout--resize-container id exwm--container
+                                           (elt relative-edges 0)
+                                           (elt relative-edges 1)
+                                           width height
+                                           (active-minibuffer-window)))
+        ;; A floating X window is of the same size as the Emacs window,
+        ;; whereas its container is of the same size as the Emacs frame.
+        (setq frame-width (frame-pixel-width exwm--floating-frame)
+              frame-height (frame-pixel-height exwm--floating-frame))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window exwm--container
+                           :value-mask (logior xcb:ConfigWindow:Width
+                                               xcb:ConfigWindow:Height)
+                           :width frame-width
+                           :height frame-height))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window (frame-parameter exwm--floating-frame
+                                                    'exwm-container)
+                           :value-mask (logior xcb:ConfigWindow:Width
+                                               xcb:ConfigWindow:Height)
+                           :width frame-width
+                           :height frame-height))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window exwm--id
+                           :value-mask (logior xcb:ConfigWindow:X
+                                               xcb:ConfigWindow:Y
+                                               xcb:ConfigWindow:Width
+                                               xcb:ConfigWindow:Height)
+                           :x exwm-floating-border-width
+                           :y exwm-floating-border-width
+                           :width width
+                           :height height)))
       ;; Make the resizing take effect.
       (xcb:flush exwm--connection)
       (xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id))
@@ -151,8 +160,7 @@
                            (make-instance 'xcb:GetGeometry
                                           :drawable exwm--container))))
         (setq exwm--floating-frame-position
-              (vector (slot-value geometry 'x) (slot-value geometry 'y))))
-      (xcb:flush exwm--connection))
+              (vector (slot-value geometry 'x) (slot-value geometry 'y)))))
     (exwm-layout--resize-container exwm--id exwm--container 0 0
                                    (exwm-workspace--current-width)
                                    (exwm-workspace--current-height))
@@ -205,12 +213,14 @@
                                      :width (x-display-pixel-width)
                                      :height (x-display-pixel-height))))
         (id (frame-parameter frame 'exwm-outer-id))
+        (container (frame-parameter frame 'exwm-container))
         (workspace (frame-parameter frame 'exwm-workspace)))
     (with-slots (x y width height) geometry
       (when (and (eq frame exwm-workspace--current)
                  (exwm-workspace--minibuffer-own-frame-p))
         (exwm-workspace--resize-minibuffer-frame width height))
-      (exwm-layout--resize-container id workspace x y width height)
+      (exwm-layout--resize-container id container 0 0 width height)
+      (exwm-layout--resize-container nil workspace x y width height t)
       (xcb:flush exwm--connection)))
   (cl-incf exwm-layout--fullscreen-frame-count))
 
@@ -349,6 +359,12 @@ windows."
                                                     'exwm-outer-id)
                            :value-mask xcb:ConfigWindow:Width
                            :width width))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window (frame-parameter exwm--floating-frame
+                                                    'exwm-container)
+                           :value-mask xcb:ConfigWindow:Width
+                           :width width))
         (xcb:flush exwm--connection))))
    (t
     (let* ((height (frame-pixel-height))
@@ -375,6 +391,12 @@ windows."
                                                     'exwm-outer-id)
                            :value-mask xcb:ConfigWindow:Height
                            :height height))
+        (xcb:+request exwm--connection
+            (make-instance 'xcb:ConfigureWindow
+                           :window (frame-parameter exwm--floating-frame
+                                                    'exwm-container)
+                           :value-mask xcb:ConfigWindow:Height
+                           :height height))
         (xcb:flush exwm--connection))))))
 
 ;;;###autoload
diff --git a/exwm-manage.el b/exwm-manage.el
index c9c6ff9d2c6c..fd1d64bafd3b 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -224,6 +224,9 @@ corresponding buffer.")
         (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:UnmapWindow :window id))
         ;;
         (setq exwm-workspace--switch-history-outdated t)
         ;;
@@ -256,18 +259,17 @@ corresponding buffer.")
           (xcb:+request exwm--connection
               (make-instance 'xcb:DeleteProperty
                              :window id :property xcb:Atom:WM_STATE)))
-        ;; Destroy the container (it seems it has to be delayed).
         (when exwm--floating-frame
-          ;; Unmap the floating frame.
+          ;; Unmap the floating frame before destroying the containers.
           (let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id)))
             (xcb:+request exwm--connection
                 (make-instance 'xcb:UnmapWindow :window window))
             (xcb:+request exwm--connection
                 (make-instance 'xcb:ReparentWindow
                                :window window :parent exwm--root :x 0 :y 0))))
+        ;; Destroy the X window container (and the frame container if any).
         (xcb:+request exwm--connection
             (make-instance 'xcb:DestroyWindow :window exwm--container))
-        (xcb:flush exwm--connection)
         (let ((kill-buffer-query-functions nil)
               (floating exwm--floating-frame))
           (kill-buffer)
@@ -310,12 +312,14 @@ corresponding buffer.")
           (make-instance 'xcb:UnmapWindow :window exwm--container))
       (xcb:flush exwm--connection)
       (when exwm--floating-frame
-        (xcb:+request exwm--connection
-            (make-instance 'xcb:ReparentWindow
-                           :window (frame-parameter exwm--floating-frame
-                                                    'exwm-outer-id)
-                           :parent exwm--root
-                           :x 0 :y 0)))
+        (let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id)))
+          (xcb:+request exwm--connection
+              (make-instance 'xcb:UnmapWindow :window window))
+          (xcb:+request exwm--connection
+              (make-instance 'xcb:ReparentWindow
+                             :window window
+                             :parent exwm--root
+                             :x 0 :y 0))))
       (xcb:+request exwm--connection
           (make-instance 'xcb:DestroyWindow :window exwm--container))
       (xcb:flush exwm--connection)
@@ -410,10 +414,13 @@ Would you like to kill it? "
   (let ((obj (make-instance 'xcb:ConfigureRequest))
         buffer edges)
     (xcb:unmarshal obj data)
-    (with-slots (window x y width height border-width value-mask)
+    (with-slots (window x y width height
+                        border-width sibling stack-mode value-mask)
         obj
-      (exwm--log "ConfigureRequest from #x%x (#x%x) @%dx%d%+d%+d, border: %d"
-                 window value-mask width height x y border-width)
+      (exwm--log "ConfigureRequest from #x%x (#x%x) @%dx%d%+d%+d; \
+border-width: %d; sibling: #x%x; stack-mode: %d"
+                 window value-mask width height x y
+                 border-width sibling stack-mode)
       (if (setq buffer (exwm--id->buffer window))
           ;; Send client message for managed windows
           (with-current-buffer buffer
@@ -440,16 +447,15 @@ Would you like to kill it? "
                                         :border-width 0 :override-redirect 0)
                                        exwm--connection))))
         (exwm--log "ConfigureWindow (preserve geometry)")
-        ;; Configure the unmanaged window without changing the stacking order.
+        ;; Configure the unmanaged window.
         (xcb:+request exwm--connection
             (make-instance 'xcb:ConfigureWindow
                            :window window
-                           :value-mask
-                           (logand value-mask
-                                   (lognot xcb:ConfigWindow:Sibling)
-                                   (lognot xcb:ConfigWindow:StackMode))
+                           :value-mask value-mask
                            :x x :y y :width width :height height
-                           :border-width border-width)))))
+                           :border-width border-width
+                           :sibling sibling
+                           :stack-mode stack-mode)))))
   (xcb:flush exwm--connection))
 
 (defun exwm-manage--on-MapRequest (data _synthetic)
diff --git a/exwm-workspace.el b/exwm-workspace.el
index 99e3b5510ea5..42c081820eb5 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -252,7 +252,7 @@ The optional FORCE option is for internal use only."
                (concat " " name)))))
         (setq exwm--frame frame)
         (if exwm--floating-frame
-            ;; Move the floating frame is enough
+            ;; Move the floating container.
             (progn
               (xcb:+request exwm--connection
                   (make-instance 'xcb:ReparentWindow
@@ -261,7 +261,7 @@ The optional FORCE option is for internal use only."
                                  (frame-parameter frame 'exwm-workspace)
                                  :x 0 :y 0))
               (xcb:flush exwm--connection))
-          ;; Move the window itself
+          ;; Move the X window container.
           (if (/= index exwm-workspace-current-index)
               (bury-buffer)
             (set-window-buffer (get-buffer-window (current-buffer) t)
@@ -483,28 +483,30 @@ This functions is modified from `display-buffer-reuse-window' and
           (0 (y-or-n-p prompt))
           (x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s"
                                   x (if (= x 1) "" "s") prompt))))
-    ;; Remove SubstructureRedirect event.
-    (xcb:+request exwm--connection
-        (make-instance 'xcb:ChangeWindowAttributes
-                       :window exwm--root :value-mask xcb:CW:EventMask
-                       :event-mask 0))
-    ;; Remove the _NET_SUPPORTING_WM_CHECK X window.
-    (with-slots (value)
-        (xcb:+request-unchecked+reply exwm--connection
-            (make-instance 'xcb:ewmh:get-_NET_SUPPORTING_WM_CHECK
-                           :window exwm--root))
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:DeleteProperty
-                         :window exwm--root
-                         :property xcb:Atom:_NET_SUPPORTING_WM_CHECK))
-      (xcb:+request exwm--connection
-          (make-instance 'xcb:DestroyWindow :window value)))
     ;; Unmanage all X windows.
     (dolist (i exwm--id-buffer-alist)
       (exwm-manage--unmanage-window (car i) t)
       (xcb:+request exwm--connection
           (make-instance 'xcb:MapWindow :window (car i))))
+    ;; Reparent out the minibuffer frame.
+    (when exwm-workspace-minibuffer-position
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:ReparentWindow
+                         :window (frame-parameter exwm-workspace--minibuffer
+                                                  'exwm-outer-id)
+                         :parent exwm--root
+                         :x 0
+                         :y 0)))
+    ;; Reparent out all workspace frames.
+    (dolist (f exwm-workspace--list)
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:ReparentWindow
+                         :window (frame-parameter f 'exwm-outer-id)
+                         :parent exwm--root
+                         :x 0
+                         :y 0)))
     (xcb:flush exwm--connection)
+    ;; Destroy all resources created by this connection.
     (xcb:disconnect exwm--connection)
     t))
 
@@ -589,9 +591,11 @@ This functions is modified from `display-buffer-reuse-window' and
   ;; Configure workspaces
   (dolist (i exwm-workspace--list)
     (let ((outer-id (string-to-number (frame-parameter i 'outer-window-id)))
+          (container (xcb:generate-id exwm--connection))
           (workspace (xcb:generate-id exwm--connection)))
       ;; Save window IDs
       (set-frame-parameter i 'exwm-outer-id outer-id)
+      (set-frame-parameter i 'exwm-container container)
       (set-frame-parameter i 'exwm-workspace workspace)
       (xcb:+request exwm--connection
           (make-instance 'xcb:CreateWindow
@@ -605,16 +609,34 @@ This functions is modified from `display-buffer-reuse-window' and
                                              xcb:CW:EventMask)
                          :override-redirect 1
                          :event-mask xcb:EventMask:SubstructureRedirect))
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:CreateWindow
+                         :depth 0 :wid container :parent workspace
+                         :x 0 :y 0
+                         :width (x-display-pixel-width)
+                         :height (x-display-pixel-height)
+                         :border-width 0 :class xcb:WindowClass:CopyFromParent
+                         :visual 0      ;CopyFromParent
+                         :value-mask xcb:CW:OverrideRedirect
+                         :override-redirect 1))
       (exwm--debug
        (xcb:+request exwm--connection
            (make-instance 'xcb:ewmh:set-_NET_WM_NAME
                           :window workspace
                           :data
                           (format "EXWM workspace %d"
+                                  (cl-position i exwm-workspace--list))))
+       (xcb:+request exwm--connection
+           (make-instance 'xcb:ewmh:set-_NET_WM_NAME
+                          :window container
+                          :data
+                          (format "EXWM workspace %d frame container"
                                   (cl-position i exwm-workspace--list)))))
       (xcb:+request exwm--connection
           (make-instance 'xcb:ReparentWindow
-                         :window outer-id :parent workspace :x 0 :y 0))
+                         :window outer-id :parent container :x 0 :y 0))
+      (xcb:+request exwm--connection
+          (make-instance 'xcb:MapWindow :window container))
       (xcb:+request exwm--connection
           (make-instance 'xcb:MapWindow :window workspace))))
   (xcb:flush exwm--connection)