FREE(con->name);
con->name = sstrdup(output->name);
con->type = CT_OUTPUT;
+ con->layout = L_OUTPUT;
}
con->rect = output->rect;
output->con = con;
char *name;
asprintf(&name, "[i3 con] output %s", con->name);
x_set_name(con, name);
- free(name);
+ FREE(name);
if (reused) {
DLOG("Not adding workspace, this was a reused con\n");
return;
}
+
+ DLOG("Changing layout, adding top/bottom dockarea\n");
+ Con *topdock = con_new(NULL);
+ topdock->type = CT_DOCKAREA;
+ topdock->layout = L_DOCKAREA;
+ topdock->orientation = VERT;
+ /* this container swallows dock clients */
+ Match *match = scalloc(sizeof(Match));
+ match_init(match);
+ match->dock = M_DOCK_TOP;
+ match->insert_where = M_BELOW;
+ TAILQ_INSERT_TAIL(&(topdock->swallow_head), match, matches);
+
+ topdock->name = sstrdup("topdock");
+
+ asprintf(&name, "[i3 con] top dockarea %s", con->name);
+ x_set_name(topdock, name);
+ FREE(name);
+ DLOG("attaching\n");
+ con_attach(topdock, con, false);
+
+ /* content container */
+
+ DLOG("adding main content container\n");
+ Con *content = con_new(NULL);
+ content->type = CT_CON;
+ content->name = sstrdup("content");
+
+ asprintf(&name, "[i3 con] content %s", con->name);
+ x_set_name(content, name);
+ FREE(name);
+ con_attach(content, con, false);
+
+ /* bottom dock container */
+ Con *bottomdock = con_new(NULL);
+ bottomdock->type = CT_DOCKAREA;
+ bottomdock->layout = L_DOCKAREA;
+ bottomdock->orientation = VERT;
+ /* this container swallows dock clients */
+ match = scalloc(sizeof(Match));
+ match_init(match);
+ match->dock = M_DOCK_BOTTOM;
+ match->insert_where = M_BELOW;
+ TAILQ_INSERT_TAIL(&(bottomdock->swallow_head), match, matches);
+
+ bottomdock->name = sstrdup("bottomdock");
+
+ asprintf(&name, "[i3 con] bottom dockarea %s", con->name);
+ x_set_name(bottomdock, name);
+ FREE(name);
+ DLOG("attaching\n");
+ con_attach(bottomdock, con, false);
+
DLOG("Now adding a workspace\n");
/* add a workspace to this output */
int c = 0;
bool exists = true;
while (exists) {
- Con *out, *current;
+ Con *out, *current, *child;
c++;
exists = false;
TAILQ_FOREACH(out, &(croot->nodes_head), nodes) {
TAILQ_FOREACH(current, &(out->nodes_head), nodes) {
- if (strcasecmp(current->name, ws->name) != 0)
+ if (current->type != CT_CON)
continue;
- exists = true;
- break;
+ TAILQ_FOREACH(child, &(current->nodes_head), nodes) {
+ if (strcasecmp(child->name, ws->name) != 0)
+ continue;
+
+ exists = true;
+ break;
+ }
}
}
DLOG("result for ws %s / %d: exists = %d\n", ws->name, c, exists);
}
ws->num = c;
- con_attach(ws, con, false);
+ con_attach(ws, content, false);
asprintf(&name, "[i3 con] workspace %s", ws->name);
x_set_name(ws, name);
free(name);
ws->fullscreen_mode = CF_OUTPUT;
- ws->orientation = HORIZ;
+
+ /* If default_orientation is set to NO_ORIENTATION we determine
+ * orientation depending on output resolution. */
+ if (config.default_orientation == NO_ORIENTATION) {
+ ws->orientation = (output->rect.height > output->rect.width) ? VERT : HORIZ;
+ DLOG("Auto orientation. Workspace size set to (%d,%d), setting orientation to %d.\n",
+ output->rect.width, output->rect.height, ws->orientation);
+ } else {
+ ws->orientation = config.default_orientation;
+ }
+
/* TODO: Set focus in main.c */
con_focus(ws);
DLOG("Output mode changed, updating rect\n");
assert(output->con != NULL);
output->con->rect = output->rect;
+
+ Con *content, *workspace, *child;
+
+ /* Point content to the container of the workspaces */
+ content = output_get_content(output->con);
+
+ /* If default_orientation is NO_ORIENTATION, we change the orientation of
+ * the workspaces and their childs depending on output resolution. This is
+ * only done for workspaces with maximum one child. */
+ if (config.default_orientation == NO_ORIENTATION) {
+ TAILQ_FOREACH(workspace, &(content->nodes_head), nodes) {
+ /* Workspaces with more than one child are left untouched because
+ * we do not want to change an existing layout. */
+ if (con_num_children(workspace) > 1)
+ continue;
+
+ workspace->orientation = (output->rect.height > output->rect.width) ? VERT : HORIZ;
+ DLOG("Setting workspace [%d,%s]'s orientation to %d.\n", workspace->num, workspace->name, workspace->orientation);
+ if ((child = TAILQ_FIRST(&(workspace->nodes_head)))) {
+ child->orientation = workspace->orientation;
+ DLOG("Setting child [%d,%s]'s orientation to %d.\n", child->num, child->name, child->orientation);
+ }
+ }
+ }
+
#if 0
Rect bar_rect = {output->rect.x,
output->rect.y + output->rect.height - (font->height + 6),
DLOG("Output %s disabled, re-assigning workspaces/docks\n", output->name);
if ((first = get_first_output()) == NULL)
- die("No usable outputs available\n");
+ die("No usable outputs available\n");
+
+ /* TODO: refactor the following code into a nice function. maybe
+ * use an on_destroy callback which is implement differently for
+ * different container types (CT_CONTENT vs. CT_DOCKAREA)? */
+ Con *first_content = output_get_content(first->con);
if (output->con != NULL) {
/* We need to move the workspaces from the disappearing output to the first output */
/* 2: iterate through workspaces and re-assign them */
Con *current;
- while (!TAILQ_EMPTY(&(output->con->nodes_head))) {
- current = TAILQ_FIRST(&(output->con->nodes_head));
+ Con *old_content = output_get_content(output->con);
+ while (!TAILQ_EMPTY(&(old_content->nodes_head))) {
+ current = TAILQ_FIRST(&(old_content->nodes_head));
DLOG("Detaching current = %p / %s\n", current, current->name);
con_detach(current);
DLOG("Re-attaching current = %p / %s\n", current, current->name);
- con_attach(current, first->con, false);
+ con_attach(current, first_content, false);
DLOG("Done, next\n");
}
DLOG("re-attached all workspaces\n");
con_focus(next);
}
+ /* 3: move the dock clients to the first output */
+ Con *child;
+ TAILQ_FOREACH(child, &(output->con->nodes_head), nodes) {
+ if (child->type != CT_DOCKAREA)
+ continue;
+ DLOG("Handling dock con %p\n", child);
+ Con *dock;
+ while (!TAILQ_EMPTY(&(child->nodes_head))) {
+ dock = TAILQ_FIRST(&(child->nodes_head));
+ Con *nc;
+ Match *match;
+ nc = con_for_window(first->con, dock->window, &match);
+ DLOG("Moving dock client %p to nc %p\n", dock, nc);
+ con_detach(dock);
+ DLOG("Re-attaching\n");
+ con_attach(dock, nc, false);
+ DLOG("Done\n");
+ }
+ }
+
DLOG("destroying disappearing con %p\n", output->con);
tree_close(output->con, false, true);
DLOG("Done. Should be fine now\n");
disable_randr(conn);
}
- //ewmh_update_workarea();
+ ewmh_update_workarea();
#if 0
/* Just go through each active output and associate one workspace */
continue;
DLOG("Focusing primary output %s\n", output->name);
- Con *next = output->con;
- while (!TAILQ_EMPTY(&(next->focus_head)))
- next = TAILQ_FIRST(&(next->focus_head));
-
- DLOG("focusing %p\n", next);
- con_focus(next);
+ con_focus(con_descend_focused(output->con));
}
/* render_layout flushes */