ewmh_update_number_of_desktops();
ewmh_update_desktop_names();
ewmh_update_desktop_viewport();
+ ewmh_update_wm_desktop();
if (created != NULL)
*created = true;
} else if (created != NULL) {
}
DLOG("Saving workspace name \"%s\"\n", target_name);
- binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char*));
- binding_workspace_names[n-1] = target_name;
+ binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char *));
+ binding_workspace_names[n - 1] = target_name;
}
- binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char*));
- binding_workspace_names[n-1] = NULL;
+ binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char *));
+ binding_workspace_names[n - 1] = NULL;
}
/*
static void _workspace_show(Con *workspace) {
Con *current, *old = NULL;
+ Con *old_focus = focused;
/* safe-guard against showing i3-internal workspaces like __i3_scratch */
if (con_is_internal(workspace))
DLOG("old = %p / %s\n", old, (old ? old->name : "(null)"));
/* Close old workspace if necessary. This must be done *after* doing
- * urgency handling, because tree_close() will do a con_focus() on the next
+ * urgency handling, because tree_close_internal() will do a con_focus() on the next
* client, which will clear the urgency flag too early. Also, there is no
* way for con_focus() to know about when to clear urgency immediately and
* when to defer it. */
if (!workspace_is_visible(old)) {
LOG("Closing old workspace (%p / %s), it is empty\n", old, old->name);
yajl_gen gen = ipc_marshal_workspace_event("empty", old, NULL);
- tree_close(old, DONT_KILL_WINDOW, false, false);
+ tree_close_internal(old, DONT_KILL_WINDOW, false, false);
const unsigned char *payload;
ylength length;
ewmh_update_number_of_desktops();
ewmh_update_desktop_names();
ewmh_update_desktop_viewport();
+ ewmh_update_wm_desktop();
}
}
ewmh_update_current_desktop();
/* Push any sticky windows to the now visible workspace. */
- output_push_sticky_windows();
+ output_push_sticky_windows(old_focus);
}
/*
*/
Con *workspace_next(void) {
Con *current = con_get_workspace(focused);
- Con *next = NULL;
+ Con *next = NULL, *first = NULL, *first_opposite = NULL;
Con *output;
if (current->num == -1) {
/* If currently a named workspace, find next named workspace. */
- next = TAILQ_NEXT(current, nodes);
- } else {
- /* If currently a numbered workspace, find next numbered workspace. */
- TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
- /* Skip outputs starting with __, they are internal. */
- if (con_is_internal(output))
- continue;
- NODES_FOREACH(output_get_content(output)) {
- if (child->type != CT_WORKSPACE)
- continue;
- if (child->num == -1)
- break;
- /* Need to check child against current and next because we are
- * traversing multiple lists and thus are not guaranteed the
- * relative order between the list of workspaces. */
- if (current->num < child->num && (!next || child->num < next->num))
- next = child;
- }
- }
- }
-
- /* Find next named workspace. */
- if (!next) {
+ if ((next = TAILQ_NEXT(current, nodes)) != NULL)
+ return next;
bool found_current = false;
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
/* Skip outputs starting with __, they are internal. */
NODES_FOREACH(output_get_content(output)) {
if (child->type != CT_WORKSPACE)
continue;
+ if (!first)
+ first = child;
+ if (!first_opposite && child->num != -1)
+ first_opposite = child;
if (child == current) {
- found_current = 1;
- } else if (child->num == -1 && (current->num != -1 || found_current)) {
+ found_current = true;
+ } else if (child->num == -1 && found_current) {
next = child;
- goto workspace_next_end;
+ return next;
}
}
}
- }
-
- /* Find first workspace. */
- if (!next) {
+ } else {
+ /* If currently a numbered workspace, find next numbered workspace. */
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
/* Skip outputs starting with __, they are internal. */
if (con_is_internal(output))
NODES_FOREACH(output_get_content(output)) {
if (child->type != CT_WORKSPACE)
continue;
- if (!next || (child->num != -1 && child->num < next->num))
+ if (!first)
+ first = child;
+ if (!first_opposite && child->num == -1)
+ first_opposite = child;
+ if (child->num == -1)
+ break;
+ /* Need to check child against current and next because we are
+ * traversing multiple lists and thus are not guaranteed the
+ * relative order between the list of workspaces. */
+ if (current->num < child->num && (!next || child->num < next->num))
next = child;
}
}
}
-workspace_next_end:
+
+ if (!next)
+ next = first_opposite ? first_opposite : first;
+
return next;
}
*/
Con *workspace_prev(void) {
Con *current = con_get_workspace(focused);
- Con *prev = NULL;
+ Con *prev = NULL, *first_opposite = NULL, *last = NULL;
Con *output;
if (current->num == -1) {
prev = TAILQ_PREV(current, nodes_head, nodes);
if (prev && prev->num != -1)
prev = NULL;
+ if (!prev) {
+ bool found_current = false;
+ TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes) {
+ /* Skip outputs starting with __, they are internal. */
+ if (con_is_internal(output))
+ continue;
+ NODES_FOREACH_REVERSE(output_get_content(output)) {
+ if (child->type != CT_WORKSPACE)
+ continue;
+ if (!last)
+ last = child;
+ if (!first_opposite && child->num != -1)
+ first_opposite = child;
+ if (child == current) {
+ found_current = true;
+ } else if (child->num == -1 && found_current) {
+ prev = child;
+ goto workspace_prev_end;
+ }
+ }
+ }
+ }
} else {
/* If numbered workspace, find previous numbered workspace. */
TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes) {
if (con_is_internal(output))
continue;
NODES_FOREACH_REVERSE(output_get_content(output)) {
- if (child->type != CT_WORKSPACE || child->num == -1)
+ if (child->type != CT_WORKSPACE)
+ continue;
+ if (!last)
+ last = child;
+ if (!first_opposite && child->num == -1)
+ first_opposite = child;
+ if (child->num == -1)
continue;
/* Need to check child against current and previous because we
* are traversing multiple lists and thus are not guaranteed
}
}
- /* Find previous named workspace. */
- if (!prev) {
- bool found_current = false;
- TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes) {
- /* Skip outputs starting with __, they are internal. */
- if (con_is_internal(output))
- continue;
- NODES_FOREACH_REVERSE(output_get_content(output)) {
- if (child->type != CT_WORKSPACE)
- continue;
- if (child == current) {
- found_current = true;
- } else if (child->num == -1 && (current->num != -1 || found_current)) {
- prev = child;
- goto workspace_prev_end;
- }
- }
- }
- }
-
- /* Find last workspace. */
- if (!prev) {
- TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes) {
- /* Skip outputs starting with __, they are internal. */
- if (con_is_internal(output))
- continue;
- NODES_FOREACH_REVERSE(output_get_content(output)) {
- if (child->type != CT_WORKSPACE)
- continue;
- if (!prev || child->num > prev->num)
- prev = child;
- }
- }
- }
+ if (!prev)
+ prev = first_opposite ? first_opposite : last;
workspace_prev_end:
return prev;
if (child->type != CT_WORKSPACE)
continue;
if (child == current) {
- found_current = 1;
+ found_current = true;
} else if (child->num == -1 && (current->num != -1 || found_current)) {
next = child;
goto workspace_next_on_output_end;
* 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, char *name) {
+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);
Con *current_output_con = con_get_output(ws);