]> git.sur5r.net Git - i3/i3/blobdiff - src/tree.c
Merge branch 'master' into next
[i3/i3] / src / tree.c
index 2973c4b8edfb713f616cf6b69bf8ec524b12548b..836183ec114439aa2b5c6cac9092abd3b095dd4d 100644 (file)
@@ -235,7 +235,12 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
             return false;
         } else {
             xcb_void_cookie_t cookie;
-            /* un-parent the window */
+            /* Ignore any further events by clearing the event mask,
+             * unmap the window,
+             * then reparent it to the root window. */
+            xcb_change_window_attributes(conn, con->window->id,
+                    XCB_CW_EVENT_MASK, (uint32_t[]){ XCB_NONE });
+            xcb_unmap_window(conn, con->window->id);
             cookie = xcb_reparent_window(conn, con->window->id, root, 0, 0);
 
             /* Ignore X11 errors for the ReparentWindow request.
@@ -354,15 +359,24 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
  */
 void tree_close_con(kill_window_t kill_window) {
     assert(focused != NULL);
-    if (focused->type == CT_WORKSPACE) {
-        LOG("Cannot close workspace\n");
-        return;
-    }
 
     /* There *should* be no possibility to focus outputs / root container */
     assert(focused->type != CT_OUTPUT);
     assert(focused->type != CT_ROOT);
 
+    if (focused->type == CT_WORKSPACE) {
+        DLOG("Workspaces cannot be close, closing all children instead\n");
+        Con *child, *nextchild;
+        for (child = TAILQ_FIRST(&(focused->focus_head)); child; ) {
+            nextchild = TAILQ_NEXT(child, focused);
+            DLOG("killing child=%p\n", child);
+            tree_close(child, kill_window, false, false);
+            child = nextchild;
+        }
+
+        return;
+    }
+
     /* Kill con */
     tree_close(focused, kill_window, false, false);
 }
@@ -373,17 +387,23 @@ void tree_close_con(kill_window_t kill_window) {
  *
  */
 void tree_split(Con *con, orientation_t orientation) {
-    /* for a workspace, we just need to change orientation */
-    if (con->type == CT_WORKSPACE) {
-        DLOG("Workspace, simply changing orientation to %d\n", orientation);
-        con->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
-        return;
-    }
-    else if (con->type == CT_FLOATING_CON) {
+    if (con->type == CT_FLOATING_CON) {
         DLOG("Floating containers can't be split.\n");
         return;
     }
 
+    if (con->type == CT_WORKSPACE) {
+        if (con_num_children(con) < 2) {
+            DLOG("Just changing orientation of workspace\n");
+            con->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
+            return;
+        } else {
+            /* if there is more than one container on the workspace
+             * move them into a new container and handle this instead */
+            con = workspace_encapsulate(con);
+        }
+    }
+
     Con *parent = con->parent;
 
     /* Force re-rendering to make the indicator border visible. */
@@ -691,6 +711,8 @@ void tree_flatten(Con *con) {
      * the con’s parent to be redundant */
     if (!con_is_split(con) ||
         !con_is_split(child) ||
+        (con->layout != L_SPLITH && con->layout != L_SPLITV) ||
+        (child->layout != L_SPLITH && child->layout != L_SPLITV) ||
         con_orientation(con) == con_orientation(child) ||
         con_orientation(child) != con_orientation(parent))
         goto recurse;