]> git.sur5r.net Git - i3/i3/blobdiff - src/tree.c
Merge branch 'master' into next
[i3/i3] / src / tree.c
index f5bac1939b0425b84f106d7a6d990323eb31b44f..3ed392ac125b9462699638978e5df83afa85ce4b 100644 (file)
@@ -15,7 +15,48 @@ struct Con *focused;
 struct all_cons_head all_cons = TAILQ_HEAD_INITIALIZER(all_cons);
 
 /*
- * Loads tree from ~/.i3/_restart.json (used for in-place restarts).
+ * Create the pseudo-output __i3. Output-independent workspaces such as
+ * __i3_scratch will live there.
+ *
+ */
+static Con *_create___i3(void) {
+    Con *__i3 = con_new(croot, NULL);
+    FREE(__i3->name);
+    __i3->name = sstrdup("__i3");
+    __i3->type = CT_OUTPUT;
+    __i3->layout = L_OUTPUT;
+    con_fix_percent(croot);
+    x_set_name(__i3, "[i3 con] pseudo-output __i3");
+    /* For retaining the correct position/size of a scratchpad window, the
+     * dimensions of the real outputs should be multiples of the __i3
+     * pseudo-output. */
+    __i3->rect.width = 1280;
+    __i3->rect.height = 1024;
+
+    /* Add a content container. */
+    DLOG("adding main content container\n");
+    Con *content = con_new(NULL, NULL);
+    content->type = CT_CON;
+    FREE(content->name);
+    content->name = sstrdup("content");
+
+    x_set_name(content, "[i3 con] content __i3");
+    con_attach(content, __i3, false);
+
+    /* Attach the __i3_scratch workspace. */
+    Con *ws = con_new(NULL, NULL);
+    ws->type = CT_WORKSPACE;
+    ws->num = -1;
+    ws->name = sstrdup("__i3_scratch");
+    con_attach(ws, content, false);
+    x_set_name(ws, "[i3 con] workspace __i3_scratch");
+    ws->fullscreen_mode = CF_OUTPUT;
+
+    return __i3;
+}
+
+/*
+ * Loads tree from 'path' (used for in-place restarts).
  *
  */
 bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry) {
@@ -47,6 +88,17 @@ bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry) {
     Con *ws = TAILQ_FIRST(&(out->nodes_head));
     printf("ws = %p\n", ws);
 
+    /* For in-place restarting into v4.2, we need to make sure the new
+     * pseudo-output __i3 is present. */
+    if (strcmp(out->name, "__i3") != 0) {
+        DLOG("Adding pseudo-output __i3 during inplace restart\n");
+        Con *__i3 = _create___i3();
+        /* Ensure that it is the first output, other places in the code make
+         * that assumption. */
+        TAILQ_REMOVE(&(croot->nodes_head), __i3, nodes);
+        TAILQ_INSERT_HEAD(&(croot->nodes_head), __i3, nodes);
+    }
+
     return true;
 }
 
@@ -66,6 +118,8 @@ void tree_init(xcb_get_geometry_reply_t *geometry) {
         geometry->width,
         geometry->height
     };
+
+    _create___i3();
 }
 
 /*
@@ -288,6 +342,11 @@ void tree_split(Con *con, orientation_t orientation) {
     }
 
     Con *parent = con->parent;
+
+    /* Force re-rendering to make the indicator border visible. */
+    FREE(con->deco_render_params);
+    FREE(parent->deco_render_params);
+
     /* if we are in a container whose parent contains only one
      * child (its split functionality is unused so far), we just change the
      * orientation (more intuitive than splitting again) */
@@ -316,38 +375,34 @@ void tree_split(Con *con, orientation_t orientation) {
 }
 
 /*
- * Moves focus one level up.
+ * Moves focus one level up. Returns true if focus changed.
  *
  */
-void level_up() {
-    /* We cannot go up when we are in fullscreen mode at the moment, that would
-     * be totally not intuitive */
-    if (focused->fullscreen_mode != CF_NONE) {
-        LOG("Currently in fullscreen, not going up\n");
-        return;
-    }
+bool level_up(void) {
     /* We can focus up to the workspace, but not any higher in the tree */
     if ((focused->parent->type != CT_CON &&
         focused->parent->type != CT_WORKSPACE) ||
         focused->type == CT_WORKSPACE) {
         LOG("Cannot go up any further\n");
-        return;
+        return false;
     }
     con_focus(focused->parent);
+    return true;
 }
 
 /*
- * Moves focus one level down.
+ * Moves focus one level down. Returns true if focus changed.
  *
  */
-void level_down() {
+bool level_down(void) {
     /* Go down the focus stack of the current node */
     Con *next = TAILQ_FIRST(&(focused->focus_head));
     if (next == TAILQ_END(&(focused->focus_head))) {
         printf("cannot go down\n");
-        return;
+        return false;
     }
     con_focus(next);
+    return true;
 }
 
 static void mark_unmapped(Con *con) {
@@ -369,7 +424,7 @@ static void mark_unmapped(Con *con) {
  * pushing the changes to X11 using x_push_changes().
  *
  */
-void tree_render() {
+void tree_render(void) {
     if (croot == NULL)
         return;
 
@@ -501,6 +556,10 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
         else next = TAILQ_LAST(&(parent->nodes_head), nodes_head);
     }
 
+    /* Don't violate fullscreen focus restrictions. */
+    if (!con_fullscreen_permits_focusing(next))
+        return false;
+
     /* 3: focus choice comes in here. at the moment we will go down
      * until we find a window */
     /* TODO: check for window, atm we only go down as far as possible */