diff options
Diffstat (limited to 'sway/workspace.c')
-rw-r--r-- | sway/workspace.c | 149 |
1 files changed, 79 insertions, 70 deletions
diff --git a/sway/workspace.c b/sway/workspace.c index 80141f71..658f79bc 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -15,26 +15,7 @@ char *prev_workspace_name = NULL; -static swayc_t *workspace_by_name_only(const char *name); - -const char *workspace_output_open_name(swayc_t *output) { - struct workspace_output *wsop; - int i, len = config->workspace_outputs->length; - // Search config for output - for (i = 0; i < len; ++i) { - wsop = config->workspace_outputs->items[i]; - // Find matching outputs - if (strcasecmp(wsop->output, output->name)) { - // Check if workspace is available and use that name - if (!workspace_by_name(wsop->workspace)) { - return wsop->workspace; - } - } - } - return NULL; -} - -const char *workspace_next_name(void) { +char *workspace_next_name(void) { sway_log(L_DEBUG, "Workspace: Generating new name"); int i; int l = 1; @@ -44,29 +25,42 @@ const char *workspace_next_name(void) { for (i = 0; i < mode->bindings->length; ++i) { struct sway_binding *binding = mode->bindings->items[i]; - const char *command = binding->command; - const char *ws = "workspace"; - const int wslen = sizeof("workspace") - 1; - if (strncmp(ws, command, wslen) == 0) { - command += wslen; - // Skip whitespace - command += strspn(command, whitespace); - // make sure its not a special command - if (strcmp(command, "next") == 0 - || strcmp(command, "prev") == 0 - || strcmp(command, "next_on_output") == 0 - || strcmp(command, "prev_on_output") == 0 - || strcmp(command, "number") == 0 - || strcmp(command, "back_and_forth") == 0 - || strcmp(command, "current") == 0 - // Or if it already exists - || workspace_by_name_only(command)) { + const char* command = binding->command; + list_t *args = split_string(command, " "); + + if (strcmp("workspace", args->items[0]) == 0 && args->length > 1) { + sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", (char *)args->items[1]); + char* target = malloc(strlen(args->items[1]) + 1); + strcpy(target, args->items[1]); + while (*target == ' ' || *target == '\t') + target++; + + // Make sure that the command references an actual workspace + // not a command about workspaces + if (strcmp(target, "next") == 0 || + strcmp(target, "prev") == 0 || + strcmp(target, "next_on_output") == 0 || + strcmp(target, "prev_on_output") == 0 || + strcmp(target, "number") == 0 || + strcmp(target, "back_and_forth") == 0 || + strcmp(target, "current") == 0) + { + free_flat_list(args); continue; - } else { - // otherwise we found it - return command; } + + // Make sure that the workspace doesn't already exist + if (workspace_by_name(target)) { + free_flat_list(args); + continue; + } + + free_flat_list(args); + + sway_log(L_DEBUG, "Workspace: Found free name %s", target); + return target; } + free_flat_list(args); } // As a fall back, get the current number of active workspaces // and return that + 1 for the next workspace's name @@ -81,40 +75,55 @@ const char *workspace_next_name(void) { return name; } -swayc_t *workspace_by_name_only(const char *name) { - int i, len = root_container.children->length; - for (i = 0; i < len; ++i) { - swayc_t *op = root_container.children->items[i]; - int i, len = op->children->length; - for (i = 0; i < len; ++i) { - swayc_t *ws = op->children->items[i]; - if (strcasecmp(ws->name, name) == 0) { - return ws; +swayc_t *workspace_create(const char* name) { + swayc_t *parent; + // Search for workspace<->output pair + int i, e = config->workspace_outputs->length; + for (i = 0; i < e; ++i) { + struct workspace_output *wso = config->workspace_outputs->items[i]; + if (strcasecmp(wso->workspace, name) == 0) + { + // Find output to use if it exists + e = root_container.children->length; + for (i = 0; i < e; ++i) { + parent = root_container.children->items[i]; + if (strcmp(parent->name, wso->output) == 0) { + return new_workspace(parent, name); + } } + break; } } - return NULL; + // Otherwise create a new one + parent = get_focused_container(&root_container); + parent = swayc_parent_by_type(parent, C_OUTPUT); + return new_workspace(parent, name); +} + +static bool _workspace_by_name(swayc_t *view, void *data) { + return (view->type == C_WORKSPACE) && + (strcasecmp(view->name, (char *) data) == 0); } swayc_t *workspace_by_name(const char* name) { if (strcmp(name, "prev") == 0) { return workspace_prev(); - } else if (!strcmp(name, "prev_on_output")) { + } + else if (strcmp(name, "prev_on_output") == 0) { return workspace_output_prev(); - } else if (!strcmp(name, "next")) { + } + else if (strcmp(name, "next") == 0) { return workspace_next(); - } else if (!strcmp(name, "next_on_output")) { + } + else if (strcmp(name, "next_on_output") == 0) { return workspace_output_next(); - } else if (!strcmp(name, "current")) { + } + else if (strcmp(name, "current") == 0) { return swayc_active_workspace(); - } else if (!strcmp(name, "back_and_forth")) { - if (prev_workspace_name) { - name = prev_workspace_name; - } else { // If there is no prev workspace name. just return current - return swayc_active_workspace(); - } } - return workspace_by_name_only(name); + else { + return swayc_by_test(&root_container, _workspace_by_name, (void *) name); + } } /** @@ -172,19 +181,19 @@ swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { return NULL; } -swayc_t *workspace_output_next(void) { +swayc_t *workspace_output_next() { return workspace_output_prev_next_impl(swayc_active_output(), true); } -swayc_t *workspace_next(void) { +swayc_t *workspace_next() { return workspace_prev_next_impl(swayc_active_workspace(), true); } -swayc_t *workspace_output_prev(void) { +swayc_t *workspace_output_prev() { return workspace_output_prev_next_impl(swayc_active_output(), false); } -swayc_t *workspace_prev(void) { +swayc_t *workspace_prev() { return workspace_prev_next_impl(swayc_active_workspace(), false); } @@ -193,17 +202,17 @@ void workspace_switch(swayc_t *workspace) { return; } swayc_t *active_ws = swayc_active_workspace(); - // set workspace to prev_workspace - if (config->auto_back_and_forth && active_ws == workspace) { - workspace = new_workspace(NULL, "back_and_forth"); + if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { + swayc_t *new_ws = workspace_by_name(prev_workspace_name); + workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); } - // set prev workspace name if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) && active_ws != workspace)) { free(prev_workspace_name); - prev_workspace_name = strdup(active_ws->name); + prev_workspace_name = malloc(strlen(active_ws->name)+1); + strcpy(prev_workspace_name, active_ws->name); } sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); |