]> git.sur5r.net Git - i3/i3/blobdiff - src/con.c
resize/unmap container x11 windows on demand (makes background images visible again)
[i3/i3] / src / con.c
index dc9e0a54172f90c921f11451ecf1726b8d068d24..e92322734234d1646e6620f41be0bc6a00a62f45 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -41,14 +41,15 @@ Con *con_new(Con *parent) {
     /* TODO: remove window coloring after test-phase */
     LOG("color %s\n", colors[cnt]);
     new->name = strdup(colors[cnt]);
-    uint32_t cp = get_colorpixel(colors[cnt]);
+    //uint32_t cp = get_colorpixel(colors[cnt]);
     cnt++;
     if ((cnt % (sizeof(colors) / sizeof(char*))) == 0)
         cnt = 0;
 
     x_con_init(new);
 
-    xcb_change_window_attributes(conn, new->frame, XCB_CW_BACK_PIXEL, &cp);
+    // TODO: this needs to be integrated into src/x.c and updated on config file reloads
+    xcb_change_window_attributes(conn, new->frame, XCB_CW_BACK_PIXEL, &config.client.background);
 
     TAILQ_INIT(&(new->floating_head));
     TAILQ_INIT(&(new->nodes_head));
@@ -286,6 +287,20 @@ Con *con_for_window(i3Window *window, Match **store_match) {
     return NULL;
 }
 
+/*
+ * Returns the number of children of this container.
+ *
+ */
+int con_num_children(Con *con) {
+    Con *child;
+    int children = 0;
+
+    TAILQ_FOREACH(child, &(con->nodes_head), nodes)
+        children++;
+
+    return children;
+}
+
 /*
  * Updates the percent attribute of the children of the given container. This
  * function needs to be called when a window is added or removed from a
@@ -294,9 +309,7 @@ Con *con_for_window(i3Window *window, Match **store_match) {
  */
 void con_fix_percent(Con *con, int action) {
     Con *child;
-    int children = 0;
-    TAILQ_FOREACH(child, &(con->nodes_head), nodes)
-        children++;
+    int children = con_num_children(con);
     /* TODO: better document why this math works */
     double fix;
     if (action == WINDOW_ADD)
@@ -360,19 +373,110 @@ void con_toggle_fullscreen(Con *con) {
  *
  */
 void con_move_to_workspace(Con *con, Con *workspace) {
-    /* 1: get the focused container of this workspace by going down as far as
+    /* 1: save the container which is going to be focused after the current
+     * container is moved away */
+    Con *focus_next = con_next_focused(con);
+
+    /* 2: get the focused container of this workspace by going down as far as
      * possible */
     Con *next = workspace;
 
     while (!TAILQ_EMPTY(&(next->focus_head)))
         next = TAILQ_FIRST(&(next->focus_head));
 
-    /* 2: we go up one level, but only when next is a normal container */
+    /* 3: we go up one level, but only when next is a normal container */
     if (next->type != CT_WORKSPACE)
         next = next->parent;
 
     DLOG("Re-attaching container to %p / %s\n", next, next->name);
-    /* 3: re-attach the con to the parent of this focused container */
+    /* 4: re-attach the con to the parent of this focused container */
     con_detach(con);
     con_attach(con, next);
+
+    /* 5: keep focus on the current workspace */
+    con_focus(focus_next);
+}
+
+/*
+ * Returns the orientation of the given container (for stacked containers,
+ * vertical orientation is used regardless of the actual orientation of the
+ * container).
+ *
+ */
+int con_orientation(Con *con) {
+    /* stacking containers behave like they are in vertical orientation */
+    if (con->layout == L_STACKED)
+        return VERT;
+
+    return con->orientation;
+}
+
+/*
+ * Returns the container which will be focused next when the given container
+ * is not available anymore. Called in tree_close and con_move_to_workspace
+ * to properly restore focus.
+ *
+ */
+Con *con_next_focused(Con *con) {
+    Con *next;
+    /* floating containers are attached to a workspace, so we focus either the
+     * next floating container (if any) or the workspace itself. */
+    if (con->type == CT_FLOATING_CON) {
+        next = TAILQ_NEXT(con, floating_windows);
+        if (next == TAILQ_END(&(parent->floating_head)))
+            next = con_get_workspace(con);
+        return next;
+    }
+
+    /* try to focus the next container on the same level as this one */
+    next = TAILQ_NEXT(con, focused);
+
+    /* if that was not possible, go up to its parent */
+    if (next == TAILQ_END(&(parent->nodes_head)))
+        next = con->parent;
+
+    /* now go down the focus stack as far as
+     * possible, excluding the current container */
+    while (!TAILQ_EMPTY(&(next->focus_head)) &&
+           TAILQ_FIRST(&(next->focus_head)) != con)
+        next = TAILQ_FIRST(&(next->focus_head));
+
+    return next;
+}
+
+/*
+ * Returns a "relative" Rect which contains the amount of pixels that need to
+ * be added to the original Rect to get the final position (obviously the
+ * amount of pixels for normal, 1pixel and borderless are different).
+ *
+ */
+Rect con_border_style_rect(Con *con) {
+    switch (con_border_style(con)) {
+    case BS_NORMAL:
+        return (Rect){2, 0, -(2 * 2), -2};
+
+    case BS_1PIXEL:
+        return (Rect){1, 1, -2, -2};
+
+    case BS_NONE:
+        return (Rect){0, 0, 0, 0};
+
+    default:
+        assert(false);
+    }
+}
+
+/*
+ * Use this function to get a container’s border style. This is important
+ * because when inside a stack, the border style is always BS_NORMAL.
+ * For tabbed mode, the same applies, with one exception: when the container is
+ * borderless and the only element in the tabbed container, the border is not
+ * rendered.
+ *
+ */
+int con_border_style(Con *con) {
+    if (con->parent->layout == L_STACKED)
+        return BS_NORMAL;
+
+    return con->border_style;
 }