]> git.sur5r.net Git - i3/i3/blobdiff - src/tree.c
i3-nagbar: explicitly set cursor using libxcursor if available
[i3/i3] / src / tree.c
index b40ba2a2879203b503d7640937184fae91f3ea13..5642c5c78f360148612af684bc1861e236fc9ed2 100644 (file)
@@ -4,7 +4,7 @@
  * vim:ts=4:sw=4:expandtab
  *
  * i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
  *
  * tree.c: Everything that primarily modifies the layout tree data structure.
  *
@@ -185,11 +185,11 @@ static bool _is_con_mapped(Con *con) {
  * recursively while deleting a containers children.
  *
  * The force_set_focus flag is specified in the case of killing a floating
- * window: tree_close() will be invoked for the CT_FLOATINGCON (the parent
+ * window: tree_close_internal() will be invoked for the CT_FLOATINGCON (the parent
  * container) and focus should be set there.
  *
  */
-bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool force_set_focus) {
+bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool force_set_focus) {
     bool was_mapped = con->mapped;
     Con *parent = con->parent;
 
@@ -202,7 +202,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
 
     /* remove the urgency hint of the workspace (if set) */
     if (con->urgent) {
-        con->urgent = false;
+        con_set_urgency(con, false);
         con_update_parents_urgency(con);
         workspace_update_urgent_flag(con_get_workspace(con));
     }
@@ -219,7 +219,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
     for (child = TAILQ_FIRST(&(con->nodes_head)); child;) {
         nextchild = TAILQ_NEXT(child, nodes);
         DLOG("killing child=%p\n", child);
-        if (!tree_close(child, kill_window, true, false))
+        if (!tree_close_internal(child, kill_window, true, false))
             abort_kill = true;
         child = nextchild;
     }
@@ -253,6 +253,13 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
             cookie = xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
                                          con->window->id, A_WM_STATE, A_WM_STATE, 32, 2, data);
 
+            /* Remove the window from the save set. All windows in the save set
+             * will be mapped when i3 closes its connection (e.g. when
+             * restarting). This is not what we want, since some apps keep
+             * unmapped windows around and don’t expect them to suddenly be
+             * mapped. See http://bugs.i3wm.org/1617 */
+            xcb_change_save_set(conn, XCB_SET_MODE_DELETE, con->window->id);
+
             /* Ignore X11 errors for the ReparentWindow request.
              * X11 Errors are returned when the window was already destroyed */
             add_ignore_event(cookie.sequence, 0);
@@ -303,7 +310,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
      * underlying container, see ticket #660.
      *
      * Rendering has to be avoided when dont_kill_parent is set (when
-     * tree_close calls itself recursively) because the tree is in a
+     * tree_close_internal calls itself recursively) because the tree is in a
      * non-renderable state during that time. */
     if (!dont_kill_parent)
         tree_render();
@@ -313,7 +320,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
 
     if (con_is_floating(con)) {
         DLOG("Container was floating, killing floating container\n");
-        tree_close(parent, DONT_KILL_WINDOW, false, (con == focused));
+        tree_close_internal(parent, DONT_KILL_WINDOW, false, (con == focused));
         DLOG("parent container killed\n");
     }
 
@@ -355,34 +362,6 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
     return true;
 }
 
-/*
- * Closes the current container using tree_close().
- *
- */
-void tree_close_con(kill_window_t kill_window) {
-    assert(focused != NULL);
-
-    /* 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);
-}
-
 /*
  * Splits (horizontally or vertically) the given container by creating a new
  * container which contains the old one and the future ones.
@@ -766,7 +745,7 @@ void tree_flatten(Con *con) {
 
     /* 4: close the redundant cons */
     DLOG("closing redundant cons\n");
-    tree_close(con, DONT_KILL_WINDOW, true, false);
+    tree_close_internal(con, DONT_KILL_WINDOW, true, false);
 
     /* Well, we got to abort the recursion here because we destroyed the
      * container. However, if tree_flatten() is called sufficiently often,