X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fworkspace.c;h=4b350b822730938ea4f0d6f73ef1b34b9d6e2909;hb=363417e01067efe2fce43f9bb47a2607c455d0ea;hp=d3a97453187ee63efefb66f92db78f8e8a722100;hpb=34b8a02a3678cdea5bf04d5c8d0dc9dd27004552;p=i3%2Fi3 diff --git a/src/workspace.c b/src/workspace.c index d3a97453..4b350b82 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -1,5 +1,3 @@ -#undef I3__FILE__ -#define I3__FILE__ "workspace.c" /* * vim:ts=4:sw=4:expandtab * @@ -101,6 +99,7 @@ Con *workspace_get(const char *num, bool *created) { 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) { @@ -189,7 +188,7 @@ Con *create_workspace_on_output(Output *output, Con *content) { struct Workspace_Assignment *assignment; TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) { if (strcmp(assignment->name, target_name) != 0 || - strcmp(assignment->output, output->name) == 0) + strcmp(assignment->output, output_primary_name(output)) == 0) continue; assigned = true; @@ -442,7 +441,7 @@ static void _workspace_show(Con *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. */ @@ -451,7 +450,7 @@ static void _workspace_show(Con *workspace) { 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; @@ -463,6 +462,7 @@ static void _workspace_show(Con *workspace) { ewmh_update_number_of_desktops(); ewmh_update_desktop_names(); ewmh_update_desktop_viewport(); + ewmh_update_wm_desktop(); } } @@ -506,34 +506,13 @@ void workspace_show_by_name(const char *num) { */ 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. */ @@ -542,18 +521,20 @@ Con *workspace_next(void) { NODES_FOREACH(output_get_content(output)) { if (child->type != CT_WORKSPACE) continue; + if (!first) + first = child; + if (!first_opposite || (child->num != -1 && child->num < first_opposite->num)) + 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)) @@ -561,12 +542,24 @@ Con *workspace_next(void) { NODES_FOREACH(output_get_content(output)) { if (child->type != CT_WORKSPACE) continue; - if (!next || (child->num != -1 && child->num < next->num)) + if (!first || (child->num != -1 && child->num < first->num)) + 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; } @@ -576,7 +569,7 @@ workspace_next_end: */ 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) { @@ -584,6 +577,28 @@ Con *workspace_prev(void) { 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 && child->num > first_opposite->num)) + first_opposite = child; + if (child == current) { + found_current = true; + } else if (child->num == -1 && found_current) { + prev = child; + return prev; + } + } + } + } } else { /* If numbered workspace, find previous numbered workspace. */ TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes) { @@ -591,7 +606,13 @@ Con *workspace_prev(void) { 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 || (child->num != -1 && last->num < child->num)) + 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 @@ -602,42 +623,9 @@ Con *workspace_prev(void) { } } - /* 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; } @@ -675,7 +663,7 @@ Con *workspace_next_on_output(void) { 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; @@ -918,20 +906,15 @@ Con *workspace_encapsulate(Con *ws) { * 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); - if (!current_output_con) { - ELOG("Could not get the output container for workspace %p / %s.\n", ws, ws->name); - return false; - } - - Output *current_output = get_output_by_name(current_output_con->name); - if (!current_output) { + Output *current_output = get_output_for_con(ws); + if (current_output == NULL) { ELOG("Cannot get current output. This is a bug in i3.\n"); return false; } + Output *output = get_output_from_string(current_output, name); if (!output) { ELOG("Could not get output from string \"%s\"\n", name); @@ -941,7 +924,7 @@ bool workspace_move_to_output(Con *ws, char *name) { Con *content = output_get_content(output->con); LOG("got output %p with content %p\n", output, content); - Con *previously_visible_ws = TAILQ_FIRST(&(content->nodes_head)); + Con *previously_visible_ws = TAILQ_FIRST(&(content->focus_head)); LOG("Previously visible workspace = %p / %s\n", previously_visible_ws, previously_visible_ws->name); bool workspace_was_visible = workspace_is_visible(ws); @@ -952,7 +935,7 @@ bool workspace_move_to_output(Con *ws, char *name) { bool used_assignment = false; struct Workspace_Assignment *assignment; TAILQ_FOREACH(assignment, &ws_assignments, ws_assignments) { - if (assignment->output == NULL || strcmp(assignment->output, current_output->name) != 0) + if (assignment->output == NULL || strcmp(assignment->output, output_primary_name(current_output)) != 0) continue; /* check if this workspace is already attached to the tree */