* keybindings. */
static char **binding_workspace_names = NULL;
+/*
+ * Returns the workspace with the given name or NULL if such a workspace does
+ * not exist.
+ *
+ */
+Con *get_existing_workspace_by_name(const char *name) {
+ Con *output, *workspace = NULL;
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
+ GREP_FIRST(workspace, output_get_content(output), !strcasecmp(child->name, name));
+ }
+
+ return workspace;
+}
+
+/*
+ * Returns the workspace with the given number or NULL if such a workspace does
+ * not exist.
+ *
+ */
+Con *get_existing_workspace_by_num(int num) {
+ Con *output, *workspace = NULL;
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
+ GREP_FIRST(workspace, output_get_content(output), child->num == num);
+ }
+
+ return workspace;
+}
+
/*
* Sets ws->layout to splith/splitv if default_orientation was specified in the
* configfile. Otherwise, it uses splith/splitv depending on whether the output
*
*/
Con *workspace_get(const char *num, bool *created) {
- Con *output, *workspace = NULL;
-
- TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
- GREP_FIRST(workspace, output_get_content(output), !strcasecmp(child->name, num));
+ Con *workspace = get_existing_workspace_by_name(num);
if (workspace == NULL) {
LOG("Creating new workspace \"%s\"\n", num);
/* unless an assignment is found, we will create this workspace on the current output */
- output = con_get_output(focused);
+ Con *output = con_get_output(focused);
/* look for assignments */
struct Workspace_Assignment *assignment;
*/
Con *create_workspace_on_output(Output *output, Con *content) {
/* add a workspace to this output */
- Con *out, *current;
char *name;
bool exists = true;
Con *ws = con_new(NULL, NULL);
if (assigned)
continue;
- current = NULL;
- TAILQ_FOREACH(out, &(croot->nodes_head), nodes)
- GREP_FIRST(current, output_get_content(out), !strcasecmp(child->name, target_name));
- exists = (current != NULL);
+ exists = (get_existing_workspace_by_name(target_name) != NULL);
if (!exists) {
ws->name = sstrdup(target_name);
/* Set ->num to the number of the workspace, if the name actually
DLOG("Getting next unused workspace by number\n");
int c = 0;
while (exists) {
- c++;
-
- ws->num = c;
-
- current = NULL;
- TAILQ_FOREACH(out, &(croot->nodes_head), nodes)
- GREP_FIRST(current, output_get_content(out), child->num == ws->num);
- exists = (current != NULL);
-
+ exists = (get_existing_workspace_by_num(++c) != NULL);
DLOG("result for ws %d: exists = %d\n", c, exists);
}
+ ws->num = c;
sasprintf(&(ws->name), "%d", c);
}
con_attach(ws, content, false);
/*
* Callback to reset the urgent flag of the given con to false. May be started by
- * _workspace_show to avoid urgency hints being lost by switching to a workspace
+ * workspace_show to avoid urgency hints being lost by switching to a workspace
* focusing the con.
*
*/
}
}
-static void _workspace_show(Con *workspace) {
+/*
+ * Switches to the given workspace
+ *
+ */
+void workspace_show(Con *workspace) {
Con *current, *old = NULL;
Con *old_focus = focused;
* focused) are skipped, see bug #868. */
if (current && !con_is_internal(current)) {
FREE(previous_workspace_name);
- if (current) {
- previous_workspace_name = sstrdup(current->name);
- DLOG("Setting previous_workspace_name = %s\n", previous_workspace_name);
- }
+ previous_workspace_name = sstrdup(current->name);
+ DLOG("Setting previous_workspace_name = %s\n", previous_workspace_name);
}
workspace_reassign_sticky(workspace);
y(free);
+ /* Avoid calling output_push_sticky_windows later with a freed container. */
+ if (old == old_focus) {
+ old_focus = NULL;
+ }
+
ewmh_update_number_of_desktops();
ewmh_update_desktop_names();
ewmh_update_desktop_viewport();
output_push_sticky_windows(old_focus);
}
-/*
- * Switches to the given workspace
- *
- */
-void workspace_show(Con *workspace) {
- _workspace_show(workspace);
-}
-
/*
* Looks up the workspace by name and switches to it.
*
void workspace_show_by_name(const char *num) {
Con *workspace;
workspace = workspace_get(num, NULL);
- _workspace_show(workspace);
+ workspace_show(workspace);
}
/*
/* 2: copy layout from workspace */
split->layout = ws->layout;
- Con *old_focused = TAILQ_FIRST(&(ws->focus_head));
-
/* 3: move the existing cons of this workspace below the new con */
+ Con **focus_order = get_focus_order(ws);
+
DLOG("Moving cons\n");
while (!TAILQ_EMPTY(&(ws->nodes_head))) {
Con *child = TAILQ_FIRST(&(ws->nodes_head));
con_attach(child, split, true);
}
+ set_focus_order(split, focus_order);
+ free(focus_order);
+
/* 4: switch workspace layout */
ws->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
DLOG("split->layout = %d, ws->layout = %d\n", split->layout, ws->layout);
/* 6: fix the percentages */
con_fix_percent(ws);
-
- if (old_focused)
- con_focus(old_focused);
}
/*
new->parent = ws;
new->layout = ws->layout;
+ Con **focus_order = get_focus_order(ws);
+
DLOG("Moving children of workspace %p / %s into container %p\n",
ws, ws->name, new);
-
Con *child;
while (!TAILQ_EMPTY(&(ws->nodes_head))) {
child = TAILQ_FIRST(&(ws->nodes_head));
con_attach(child, new, true);
}
+ set_focus_order(new, focus_order);
+ free(focus_order);
+
con_attach(new, ws, true);
return new;
* Move the given workspace to the specified output.
* This returns true if and only if moving the workspace was successful.
*/
-bool workspace_move_to_output(Con *ws, const char *name) {
- LOG("Trying to move workspace %p / %s to output \"%s\".\n", ws, ws->name, name);
+bool workspace_move_to_output(Con *ws, Output *output) {
+ LOG("Trying to move workspace %p / %s to output %p / \"%s\".\n", ws, ws->name, output, output_primary_name(output));
Output *current_output = get_output_for_con(ws);
if (current_output == NULL) {
return false;
}
- Output *output = get_output_from_string(current_output, name);
- if (!output) {
- ELOG("Could not get output from string \"%s\"\n", name);
- return false;
- }
-
Con *content = output_get_content(output->con);
LOG("got output %p with content %p\n", output, content);
TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) {
if (assignment->output == NULL || strcmp(assignment->output, output_primary_name(current_output)) != 0)
continue;
-
/* check if this workspace is already attached to the tree */
- Con *workspace = NULL, *out;
- TAILQ_FOREACH(out, &(croot->nodes_head), nodes)
- GREP_FIRST(workspace, output_get_content(out),
- !strcasecmp(child->name, assignment->name));
- if (workspace != NULL)
+ if (get_existing_workspace_by_name(assignment->name) != NULL) {
continue;
+ }
/* so create the workspace referenced to by this assignment */
LOG("Creating workspace from assignment %s.\n", assignment->name);