From 0ba6554c4f6c923274062862d895240eea4de350 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 11 Nov 2017 11:00:18 -0500 Subject: Move sway's internal tree code to sway/tree/ --- sway/tree/workspace.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 sway/tree/workspace.c (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c new file mode 100644 index 00000000..14cde146 --- /dev/null +++ b/sway/tree/workspace.c @@ -0,0 +1,373 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include +#include "sway/ipc-server.h" +#include "sway/workspace.h" +#include "sway/layout.h" +#include "sway/container.h" +#include "sway/handlers.h" +#include "sway/config.h" +#include "sway/focus.h" +#include "stringop.h" +#include "util.h" +#include "list.h" +#include "log.h" +#include "ipc.h" + +char *prev_workspace_name = NULL; +struct workspace_by_number_data { + int len; + const char *cset; + const char *name; +}; + +static bool workspace_valid_on_output(const char *output_name, const char *ws_name) { + int i; + for (i = 0; i < config->workspace_outputs->length; ++i) { + struct workspace_output *wso = config->workspace_outputs->items[i]; + if (strcasecmp(wso->workspace, ws_name) == 0) { + if (strcasecmp(wso->output, output_name) != 0) { + return false; + } + } + } + + return true; +} + +char *workspace_next_name(const char *output_name) { + sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name); + int i; + int l = 1; + // Scan all workspace bindings to find the next available workspace name, + // if none are found/available then default to a number + struct sway_mode *mode = config->current_mode; + + int order = INT_MAX; + char *target = NULL; + for (i = 0; i < mode->bindings->length; ++i) { + struct sway_binding *binding = mode->bindings->items[i]; + char *cmdlist = strdup(binding->command); + char *dup = cmdlist; + char *name = NULL; + + // workspace n + char *cmd = argsep(&cmdlist, " "); + if (cmdlist) { + name = argsep(&cmdlist, ",;"); + } + + if (strcmp("workspace", cmd) == 0 && name) { + sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", name); + char *_target = strdup(name); + strip_quotes(_target); + while (isspace(*_target)) + _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(_target); + free(dup); + continue; + } + + // Make sure that the workspace doesn't already exist + if (workspace_by_name(_target)) { + free(_target); + free(dup); + continue; + } + + // make sure that the workspace can appear on the given + // output + if (!workspace_valid_on_output(output_name, _target)) { + free(_target); + free(dup); + continue; + } + + if (binding->order < order) { + order = binding->order; + free(target); + target = _target; + sway_log(L_DEBUG, "Workspace: Found free name %s", _target); + } + } + free(dup); + } + if (target != NULL) { + return target; + } + // As a fall back, get the current number of active workspaces + // and return that + 1 for the next workspace's name + int ws_num = root_container.children->length; + if (ws_num >= 10) { + l = 2; + } else if (ws_num >= 100) { + l = 3; + } + char *name = malloc(l + 1); + if (!name) { + sway_log(L_ERROR, "Could not allocate workspace name"); + return NULL; + } + sprintf(name, "%d", ws_num++); + return name; +} + +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; + } + } + // 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") == 0) { + return workspace_output_prev(); + } + else if (strcmp(name, "next") == 0) { + return workspace_next(); + } + else if (strcmp(name, "next_on_output") == 0) { + return workspace_output_next(); + } + else if (strcmp(name, "current") == 0) { + return swayc_active_workspace(); + } + else { + return swayc_by_test(&root_container, _workspace_by_name, (void *) name); + } +} + +static bool _workspace_by_number(swayc_t *view, void *data) { + if (view->type != C_WORKSPACE) { + return false; + } + struct workspace_by_number_data *wbnd = data; + int a = strspn(view->name, wbnd->cset); + return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; +} +swayc_t *workspace_by_number(const char* name) { + struct workspace_by_number_data wbnd = {0, "1234567890", name}; + wbnd.len = strspn(name, wbnd.cset); + if (wbnd.len <= 0) { + return NULL; + } + return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); +} + +/** + * Get the previous or next workspace on the specified output. + * Wraps around at the end and beginning. + * If next is false, the previous workspace is returned, otherwise the next one is returned. + */ +swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { + if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { + return NULL; + } + + int i; + for (i = 0; i < output->children->length; i++) { + if (output->children->items[i] == output->focused) { + return output->children->items[wrap(i + (next ? 1 : -1), output->children->length)]; + } + } + + // Doesn't happen, at worst the for loop returns the previously active workspace + return NULL; +} + +/** + * Get the previous or next workspace. If the first/last workspace on an output is active, + * proceed to the previous/next output's previous/next workspace. + * If next is false, the previous workspace is returned, otherwise the next one is returned. + */ +swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { + if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { + return NULL; + } + + swayc_t *current_output = workspace->parent; + int offset = next ? 1 : -1; + int start = next ? 0 : 1; + int end = next ? (current_output->children->length) - 1 : current_output->children->length; + int i; + for (i = start; i < end; i++) { + if (current_output->children->items[i] == workspace) { + return current_output->children->items[i + offset]; + } + } + + // Given workspace is the first/last on the output, jump to the previous/next output + int num_outputs = root_container.children->length; + for (i = 0; i < num_outputs; i++) { + if (root_container.children->items[i] == current_output) { + swayc_t *next_output = root_container.children->items[wrap(i + offset, num_outputs)]; + return workspace_output_prev_next_impl(next_output, next); + } + } + + // Doesn't happen, at worst the for loop returns the previously active workspace on the active output + return NULL; +} + +swayc_t *workspace_output_next() { + return workspace_output_prev_next_impl(swayc_active_output(), true); +} + +swayc_t *workspace_next() { + return workspace_prev_next_impl(swayc_active_workspace(), true); +} + +swayc_t *workspace_output_prev() { + return workspace_output_prev_next_impl(swayc_active_output(), false); +} + +swayc_t *workspace_prev() { + return workspace_prev_next_impl(swayc_active_workspace(), false); +} + +bool workspace_switch(swayc_t *workspace) { + if (!workspace) { + return false; + } + swayc_t *active_ws = swayc_active_workspace(); + 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); + } + + if (!prev_workspace_name + || (strcmp(prev_workspace_name, active_ws->name) + && active_ws != workspace)) { + free(prev_workspace_name); + prev_workspace_name = malloc(strlen(active_ws->name) + 1); + if (!prev_workspace_name) { + sway_log(L_ERROR, "Unable to allocate previous workspace name"); + return false; + } + strcpy(prev_workspace_name, active_ws->name); + } + + // move sticky containers + if (swayc_parent_by_type(active_ws, C_OUTPUT) == swayc_parent_by_type(workspace, C_OUTPUT)) { + // don't change list while traversing it, use intermediate list instead + list_t *stickies = create_list(); + for (int i = 0; i < active_ws->floating->length; i++) { + swayc_t *cont = active_ws->floating->items[i]; + if (cont->sticky) { + list_add(stickies, cont); + } + } + for (int i = 0; i < stickies->length; i++) { + swayc_t *cont = stickies->items[i]; + sway_log(L_DEBUG, "Moving sticky container %p to %p:%s", + cont, workspace, workspace->name); + swayc_t *parent = remove_child(cont); + add_floating(workspace, cont); + // Destroy old container if we need to + destroy_container(parent); + } + list_free(stickies); + } + sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + if (!set_focused_container(get_focused_view(workspace))) { + return false; + } + swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); + arrange_backgrounds(); + arrange_windows(output, -1, -1); + return true; +} + +swayc_t *workspace_for_pid(pid_t pid) { + int i; + swayc_t *ws = NULL; + struct pid_workspace *pw = NULL; + + sway_log(L_DEBUG, "looking for workspace for pid %d", pid); + + // leaving this here as it's useful for debugging + // sway_log(L_DEBUG, "all pid_workspaces"); + // for (int k = 0; k < config->pid_workspaces->length; k++) { + // pw = config->pid_workspaces->items[k]; + // sway_log(L_DEBUG, "pid %d workspace %s time_added %li", *pw->pid, pw->workspace, *pw->time_added); + // } + + do { + for (i = 0; i < config->pid_workspaces->length; i++) { + pw = config->pid_workspaces->items[i]; + pid_t *pw_pid = pw->pid; + + if (pid == *pw_pid) { + sway_log(L_DEBUG, "found pid_workspace for pid %d, workspace %s", pid, pw->workspace); + break; // out of for loop + } + + pw = NULL; + } + + if (pw) { + break; // out of do-while loop + } + + pid = get_parent_pid(pid); + // no sense in looking for matches for pid 0. + // also, if pid == getpid(), that is the compositor's + // pid, which definitely isn't helpful + } while (pid > 0 && pid != getpid()); + + if (pw) { + ws = workspace_by_name(pw->workspace); + + if (!ws) { + sway_log(L_DEBUG, "Creating workspace %s for pid %d because it disappeared", pw->workspace, pid); + ws = workspace_create(pw->workspace); + } + + list_del(config->pid_workspaces, i); + } + + return ws; +} -- cgit v1.2.3 From 733993a651c71f7e2198d505960d6bbd31e0e107 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 18 Nov 2017 11:22:02 -0500 Subject: Move everything to sway/old/ --- sway/tree/workspace.c | 373 -------------------------------------------------- 1 file changed, 373 deletions(-) delete mode 100644 sway/tree/workspace.c (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c deleted file mode 100644 index 14cde146..00000000 --- a/sway/tree/workspace.c +++ /dev/null @@ -1,373 +0,0 @@ -#define _XOPEN_SOURCE 500 -#include -#include -#include -#include -#include -#include -#include -#include -#include "sway/ipc-server.h" -#include "sway/workspace.h" -#include "sway/layout.h" -#include "sway/container.h" -#include "sway/handlers.h" -#include "sway/config.h" -#include "sway/focus.h" -#include "stringop.h" -#include "util.h" -#include "list.h" -#include "log.h" -#include "ipc.h" - -char *prev_workspace_name = NULL; -struct workspace_by_number_data { - int len; - const char *cset; - const char *name; -}; - -static bool workspace_valid_on_output(const char *output_name, const char *ws_name) { - int i; - for (i = 0; i < config->workspace_outputs->length; ++i) { - struct workspace_output *wso = config->workspace_outputs->items[i]; - if (strcasecmp(wso->workspace, ws_name) == 0) { - if (strcasecmp(wso->output, output_name) != 0) { - return false; - } - } - } - - return true; -} - -char *workspace_next_name(const char *output_name) { - sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name); - int i; - int l = 1; - // Scan all workspace bindings to find the next available workspace name, - // if none are found/available then default to a number - struct sway_mode *mode = config->current_mode; - - int order = INT_MAX; - char *target = NULL; - for (i = 0; i < mode->bindings->length; ++i) { - struct sway_binding *binding = mode->bindings->items[i]; - char *cmdlist = strdup(binding->command); - char *dup = cmdlist; - char *name = NULL; - - // workspace n - char *cmd = argsep(&cmdlist, " "); - if (cmdlist) { - name = argsep(&cmdlist, ",;"); - } - - if (strcmp("workspace", cmd) == 0 && name) { - sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", name); - char *_target = strdup(name); - strip_quotes(_target); - while (isspace(*_target)) - _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(_target); - free(dup); - continue; - } - - // Make sure that the workspace doesn't already exist - if (workspace_by_name(_target)) { - free(_target); - free(dup); - continue; - } - - // make sure that the workspace can appear on the given - // output - if (!workspace_valid_on_output(output_name, _target)) { - free(_target); - free(dup); - continue; - } - - if (binding->order < order) { - order = binding->order; - free(target); - target = _target; - sway_log(L_DEBUG, "Workspace: Found free name %s", _target); - } - } - free(dup); - } - if (target != NULL) { - return target; - } - // As a fall back, get the current number of active workspaces - // and return that + 1 for the next workspace's name - int ws_num = root_container.children->length; - if (ws_num >= 10) { - l = 2; - } else if (ws_num >= 100) { - l = 3; - } - char *name = malloc(l + 1); - if (!name) { - sway_log(L_ERROR, "Could not allocate workspace name"); - return NULL; - } - sprintf(name, "%d", ws_num++); - return name; -} - -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; - } - } - // 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") == 0) { - return workspace_output_prev(); - } - else if (strcmp(name, "next") == 0) { - return workspace_next(); - } - else if (strcmp(name, "next_on_output") == 0) { - return workspace_output_next(); - } - else if (strcmp(name, "current") == 0) { - return swayc_active_workspace(); - } - else { - return swayc_by_test(&root_container, _workspace_by_name, (void *) name); - } -} - -static bool _workspace_by_number(swayc_t *view, void *data) { - if (view->type != C_WORKSPACE) { - return false; - } - struct workspace_by_number_data *wbnd = data; - int a = strspn(view->name, wbnd->cset); - return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; -} -swayc_t *workspace_by_number(const char* name) { - struct workspace_by_number_data wbnd = {0, "1234567890", name}; - wbnd.len = strspn(name, wbnd.cset); - if (wbnd.len <= 0) { - return NULL; - } - return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); -} - -/** - * Get the previous or next workspace on the specified output. - * Wraps around at the end and beginning. - * If next is false, the previous workspace is returned, otherwise the next one is returned. - */ -swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { - if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { - return NULL; - } - - int i; - for (i = 0; i < output->children->length; i++) { - if (output->children->items[i] == output->focused) { - return output->children->items[wrap(i + (next ? 1 : -1), output->children->length)]; - } - } - - // Doesn't happen, at worst the for loop returns the previously active workspace - return NULL; -} - -/** - * Get the previous or next workspace. If the first/last workspace on an output is active, - * proceed to the previous/next output's previous/next workspace. - * If next is false, the previous workspace is returned, otherwise the next one is returned. - */ -swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { - if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { - return NULL; - } - - swayc_t *current_output = workspace->parent; - int offset = next ? 1 : -1; - int start = next ? 0 : 1; - int end = next ? (current_output->children->length) - 1 : current_output->children->length; - int i; - for (i = start; i < end; i++) { - if (current_output->children->items[i] == workspace) { - return current_output->children->items[i + offset]; - } - } - - // Given workspace is the first/last on the output, jump to the previous/next output - int num_outputs = root_container.children->length; - for (i = 0; i < num_outputs; i++) { - if (root_container.children->items[i] == current_output) { - swayc_t *next_output = root_container.children->items[wrap(i + offset, num_outputs)]; - return workspace_output_prev_next_impl(next_output, next); - } - } - - // Doesn't happen, at worst the for loop returns the previously active workspace on the active output - return NULL; -} - -swayc_t *workspace_output_next() { - return workspace_output_prev_next_impl(swayc_active_output(), true); -} - -swayc_t *workspace_next() { - return workspace_prev_next_impl(swayc_active_workspace(), true); -} - -swayc_t *workspace_output_prev() { - return workspace_output_prev_next_impl(swayc_active_output(), false); -} - -swayc_t *workspace_prev() { - return workspace_prev_next_impl(swayc_active_workspace(), false); -} - -bool workspace_switch(swayc_t *workspace) { - if (!workspace) { - return false; - } - swayc_t *active_ws = swayc_active_workspace(); - 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); - } - - if (!prev_workspace_name - || (strcmp(prev_workspace_name, active_ws->name) - && active_ws != workspace)) { - free(prev_workspace_name); - prev_workspace_name = malloc(strlen(active_ws->name) + 1); - if (!prev_workspace_name) { - sway_log(L_ERROR, "Unable to allocate previous workspace name"); - return false; - } - strcpy(prev_workspace_name, active_ws->name); - } - - // move sticky containers - if (swayc_parent_by_type(active_ws, C_OUTPUT) == swayc_parent_by_type(workspace, C_OUTPUT)) { - // don't change list while traversing it, use intermediate list instead - list_t *stickies = create_list(); - for (int i = 0; i < active_ws->floating->length; i++) { - swayc_t *cont = active_ws->floating->items[i]; - if (cont->sticky) { - list_add(stickies, cont); - } - } - for (int i = 0; i < stickies->length; i++) { - swayc_t *cont = stickies->items[i]; - sway_log(L_DEBUG, "Moving sticky container %p to %p:%s", - cont, workspace, workspace->name); - swayc_t *parent = remove_child(cont); - add_floating(workspace, cont); - // Destroy old container if we need to - destroy_container(parent); - } - list_free(stickies); - } - sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - if (!set_focused_container(get_focused_view(workspace))) { - return false; - } - swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); - arrange_backgrounds(); - arrange_windows(output, -1, -1); - return true; -} - -swayc_t *workspace_for_pid(pid_t pid) { - int i; - swayc_t *ws = NULL; - struct pid_workspace *pw = NULL; - - sway_log(L_DEBUG, "looking for workspace for pid %d", pid); - - // leaving this here as it's useful for debugging - // sway_log(L_DEBUG, "all pid_workspaces"); - // for (int k = 0; k < config->pid_workspaces->length; k++) { - // pw = config->pid_workspaces->items[k]; - // sway_log(L_DEBUG, "pid %d workspace %s time_added %li", *pw->pid, pw->workspace, *pw->time_added); - // } - - do { - for (i = 0; i < config->pid_workspaces->length; i++) { - pw = config->pid_workspaces->items[i]; - pid_t *pw_pid = pw->pid; - - if (pid == *pw_pid) { - sway_log(L_DEBUG, "found pid_workspace for pid %d, workspace %s", pid, pw->workspace); - break; // out of for loop - } - - pw = NULL; - } - - if (pw) { - break; // out of do-while loop - } - - pid = get_parent_pid(pid); - // no sense in looking for matches for pid 0. - // also, if pid == getpid(), that is the compositor's - // pid, which definitely isn't helpful - } while (pid > 0 && pid != getpid()); - - if (pw) { - ws = workspace_by_name(pw->workspace); - - if (!ws) { - sway_log(L_DEBUG, "Creating workspace %s for pid %d because it disappeared", pw->workspace, pid); - ws = workspace_create(pw->workspace); - } - - list_del(config->pid_workspaces, i); - } - - return ws; -} -- cgit v1.2.3 From aeda2e077f6184ecd26dc078c7b5db7f0dc54fd7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 22 Nov 2017 20:39:27 -0500 Subject: Add workspace to outputs --- sway/tree/workspace.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 sway/tree/workspace.c (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c new file mode 100644 index 00000000..e8ed4102 --- /dev/null +++ b/sway/tree/workspace.c @@ -0,0 +1,26 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include "sway/container.h" +#include "log.h" + +void next_name_map(swayc_t *ws, void *data) { + int *count = data; + ++count; +} + +char *workspace_next_name(const char *output_name) { + sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", + output_name); + int count = 0; + next_name_map(&root_container, &count); + ++count; + int len = snprintf(NULL, 0, "%d", count); + char *name = malloc(len + 1); + if (!sway_assert(name, "Failed to allocate workspace name")) { + return NULL; + } + snprintf(name, len + 1, "%d", count); + return name; +} -- cgit v1.2.3 From 67985e903188a464e602d04f9ed218bd397f5ab1 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 5 Jan 2018 22:32:51 +0100 Subject: sway: change all sway_log to wlr_log --- sway/tree/workspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index e8ed4102..c37a873c 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -11,7 +11,7 @@ void next_name_map(swayc_t *ws, void *data) { } char *workspace_next_name(const char *output_name) { - sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", + wlr_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name); int count = 0; next_name_map(&root_container, &count); -- cgit v1.2.3 From b28602aa7425cf435150e6008624429737e037d3 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 30 Jan 2018 23:09:21 -0500 Subject: Implement workspaces --- sway/tree/workspace.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index c37a873c..23c630b6 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -2,8 +2,20 @@ #include #include #include +#include #include "sway/container.h" +#include "sway/input/input-manager.h" +#include "sway/input/seat.h" +#include "sway/workspace.h" #include "log.h" +#include "util.h" + +char *prev_workspace_name = NULL; +struct workspace_by_number_data { + int len; + const char *cset; + const char *name; +}; void next_name_map(swayc_t *ws, void *data) { int *count = data; @@ -24,3 +36,202 @@ char *workspace_next_name(const char *output_name) { snprintf(name, len + 1, "%d", count); return name; } + +static bool _workspace_by_number(swayc_t *view, void *data) { + if (view->type != C_WORKSPACE) { + return false; + } + struct workspace_by_number_data *wbnd = data; + int a = strspn(view->name, wbnd->cset); + return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; +} + +swayc_t *workspace_by_number(const char* name) { + struct workspace_by_number_data wbnd = {0, "1234567890", name}; + wbnd.len = strspn(name, wbnd.cset); + if (wbnd.len <= 0) { + return NULL; + } + return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); +} + +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) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + swayc_t *current_workspace = NULL, *current_output = NULL; + if (seat->focus) { + current_workspace = swayc_parent_by_type(seat->focus, C_WORKSPACE); + current_output = swayc_parent_by_type(seat->focus, C_OUTPUT); + } + if (strcmp(name, "prev") == 0) { + return workspace_prev(current_workspace); + } else if (strcmp(name, "prev_on_output") == 0) { + return workspace_output_prev(current_output); + } else if (strcmp(name, "next") == 0) { + return workspace_next(current_workspace); + } else if (strcmp(name, "next_on_output") == 0) { + return workspace_output_next(current_output); + } else if (strcmp(name, "current") == 0) { + return current_workspace; + } else { + return swayc_by_test(&root_container, _workspace_by_name, (void *) name); + } +} + +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; + } + } + // Otherwise create a new one + struct sway_seat *seat = input_manager_current_seat(input_manager); + parent = seat->focus; + parent = swayc_parent_by_type(parent, C_OUTPUT); + return new_workspace(parent, name); +} + +/** + * Get the previous or next workspace on the specified output. Wraps around at + * the end and beginning. If next is false, the previous workspace is returned, + * otherwise the next one is returned. + */ +swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { + if (!sway_assert(output->type == C_OUTPUT, + "Argument must be an output, is %d", output->type)) { + return NULL; + } + + int i; + for (i = 0; i < output->children->length; i++) { + if (output->children->items[i] == output->focused) { + return output->children->items[ + wrap(i + (next ? 1 : -1), output->children->length)]; + } + } + + // Doesn't happen, at worst the for loop returns the previously active workspace + return NULL; +} + +/** + * Get the previous or next workspace. If the first/last workspace on an output + * is active, proceed to the previous/next output's previous/next workspace. If + * next is false, the previous workspace is returned, otherwise the next one is + * returned. + */ +swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { + if (!sway_assert(workspace->type == C_WORKSPACE, + "Argument must be a workspace, is %d", workspace->type)) { + return NULL; + } + + swayc_t *current_output = workspace->parent; + int offset = next ? 1 : -1; + int start = next ? 0 : 1; + int end; + if (next) { + end = current_output->children->length - 1; + } else { + end = current_output->children->length; + } + int i; + for (i = start; i < end; i++) { + if (current_output->children->items[i] == workspace) { + return current_output->children->items[i + offset]; + } + } + + // Given workspace is the first/last on the output, jump to the previous/next output + int num_outputs = root_container.children->length; + for (i = 0; i < num_outputs; i++) { + if (root_container.children->items[i] == current_output) { + swayc_t *next_output = root_container.children->items[ + wrap(i + offset, num_outputs)]; + return workspace_output_prev_next_impl(next_output, next); + } + } + + // Doesn't happen, at worst the for loop returns the previously active workspace on the active output + return NULL; +} + +swayc_t *workspace_output_next(swayc_t *current) { + return workspace_output_prev_next_impl(current, true); +} + +swayc_t *workspace_next(swayc_t *current) { + return workspace_prev_next_impl(current, true); +} + +swayc_t *workspace_output_prev(swayc_t *current) { + return workspace_output_prev_next_impl(current, false); +} + +swayc_t *workspace_prev(swayc_t *current) { + return workspace_prev_next_impl(current, false); +} + +bool workspace_switch(swayc_t *workspace) { + if (!workspace) { + return false; + } + struct sway_seat *seat = input_manager_current_seat(input_manager); + if (!seat || !seat->focus) { + return false; + } + swayc_t *active_ws = seat->focus; + if (active_ws->type != C_WORKSPACE) { + swayc_parent_by_type(seat->focus, C_WORKSPACE); + } + + 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); + } + + if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) + && active_ws != workspace)) { + free(prev_workspace_name); + prev_workspace_name = malloc(strlen(active_ws->name) + 1); + if (!prev_workspace_name) { + wlr_log(L_ERROR, "Unable to allocate previous workspace name"); + return false; + } + strcpy(prev_workspace_name, active_ws->name); + } + + // TODO: Deal with sticky containers + + wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + // TODO FOCUS: Focus the last view this seat had focused on this workspace + if (workspace->children->length) { + // TODO FOCUS: This is really fucking stupid + sway_seat_set_focus(seat, workspace->children->items[0]); + } else { + sway_seat_set_focus(seat, workspace); + } + swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); + // TODO FOCUS: take a look at this + output->focused = workspace; + arrange_windows(output, -1, -1); + return true; +} -- cgit v1.2.3 From 515150229847c9ebdfd0cabb6f0026fca9d57a23 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 4 Feb 2018 13:39:10 -0500 Subject: basic focus overhaul --- sway/tree/workspace.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 23c630b6..ce5b425c 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -63,9 +63,10 @@ static bool _workspace_by_name(swayc_t *view, void *data) { swayc_t *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); swayc_t *current_workspace = NULL, *current_output = NULL; - if (seat->focus) { - current_workspace = swayc_parent_by_type(seat->focus, C_WORKSPACE); - current_output = swayc_parent_by_type(seat->focus, C_OUTPUT); + if (seat->has_focus) { + swayc_t *focus = sway_seat_get_focus(seat, &root_container); + current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); + current_output = swayc_parent_by_type(focus, C_OUTPUT); } if (strcmp(name, "prev") == 0) { return workspace_prev(current_workspace); @@ -102,7 +103,8 @@ swayc_t *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - parent = seat->focus; + swayc_t *focus = sway_seat_get_focus(seat, &root_container); + parent = focus; parent = swayc_parent_by_type(parent, C_OUTPUT); return new_workspace(parent, name); } @@ -193,12 +195,13 @@ bool workspace_switch(swayc_t *workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - if (!seat || !seat->focus) { + swayc_t *focus = sway_seat_get_focus(seat, &root_container); + if (!seat || !focus) { return false; } - swayc_t *active_ws = seat->focus; + swayc_t *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - swayc_parent_by_type(seat->focus, C_WORKSPACE); + swayc_parent_by_type(focus, C_WORKSPACE); } if (config->auto_back_and_forth -- cgit v1.2.3 From a7d49da23956c245f0e6b8f7dc9cb532eb14c4b9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 7 Feb 2018 18:17:57 -0500 Subject: separate seat get focus and seat get focus inactive --- sway/tree/workspace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index ce5b425c..29f07f74 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -63,8 +63,8 @@ static bool _workspace_by_name(swayc_t *view, void *data) { swayc_t *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); swayc_t *current_workspace = NULL, *current_output = NULL; - if (seat->has_focus) { - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus(seat); + if (focus) { current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); current_output = swayc_parent_by_type(focus, C_OUTPUT); } @@ -103,7 +103,7 @@ swayc_t *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); parent = focus; parent = swayc_parent_by_type(parent, C_OUTPUT); return new_workspace(parent, name); @@ -195,7 +195,7 @@ bool workspace_switch(swayc_t *workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } -- cgit v1.2.3 From 93084c9cf80901b160e0eb50b72a8e607289a678 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 10 Feb 2018 19:53:50 -0500 Subject: remove old focus member --- sway/tree/workspace.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 29f07f74..861fda4d 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -120,9 +120,15 @@ swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { return NULL; } + struct sway_seat *seat = input_manager_current_seat(input_manager); + swayc_t *focus = sway_seat_get_focus_inactive(seat, output); + swayc_t *workspace = (focus->type == C_WORKSPACE ? + focus : + swayc_parent_by_type(focus, C_WORKSPACE)); + int i; for (i = 0; i < output->children->length; i++) { - if (output->children->items[i] == output->focused) { + if (output->children->items[i] == workspace) { return output->children->items[ wrap(i + (next ? 1 : -1), output->children->length)]; } @@ -225,16 +231,12 @@ bool workspace_switch(swayc_t *workspace) { // TODO: Deal with sticky containers wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - // TODO FOCUS: Focus the last view this seat had focused on this workspace - if (workspace->children->length) { - // TODO FOCUS: This is really fucking stupid - sway_seat_set_focus(seat, workspace->children->items[0]); - } else { - sway_seat_set_focus(seat, workspace); + swayc_t *next = sway_seat_get_focus_inactive(seat, workspace); + if (next == NULL) { + next = workspace; } + sway_seat_set_focus(seat, next); swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); - // TODO FOCUS: take a look at this - output->focused = workspace; arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From 874f009866abaf8ca43ed4cd88a69d22a3fbfc5a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 12:15:31 -0400 Subject: move tree includes to their own directory --- sway/tree/workspace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 861fda4d..3da3fde6 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -3,10 +3,10 @@ #include #include #include -#include "sway/container.h" +#include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" -#include "sway/workspace.h" +#include "sway/tree/workspace.h" #include "log.h" #include "util.h" -- cgit v1.2.3 From b90099b4b7df8068446c658ab99b58ff83648954 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 16:17:55 -0400 Subject: rename container functions --- sway/tree/workspace.c | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 3da3fde6..32e82845 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -17,7 +17,7 @@ struct workspace_by_number_data { const char *name; }; -void next_name_map(swayc_t *ws, void *data) { +void next_name_map(struct sway_container *ws, void *data) { int *count = data; ++count; } @@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) { return name; } -static bool _workspace_by_number(swayc_t *view, void *data) { +static bool _workspace_by_number(struct sway_container *view, void *data) { if (view->type != C_WORKSPACE) { return false; } @@ -46,27 +46,27 @@ static bool _workspace_by_number(swayc_t *view, void *data) { return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; } -swayc_t *workspace_by_number(const char* name) { +struct sway_container *workspace_by_number(const char* name) { struct workspace_by_number_data wbnd = {0, "1234567890", name}; wbnd.len = strspn(name, wbnd.cset); if (wbnd.len <= 0) { return NULL; } - return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); + return sway_container_find(&root_container, _workspace_by_number, (void *) &wbnd); } -static bool _workspace_by_name(swayc_t *view, void *data) { +static bool _workspace_by_name(struct sway_container *view, void *data) { return (view->type == C_WORKSPACE) && (strcasecmp(view->name, (char *) data) == 0); } -swayc_t *workspace_by_name(const char *name) { +struct sway_container *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *current_workspace = NULL, *current_output = NULL; - swayc_t *focus = sway_seat_get_focus(seat); + struct sway_container *current_workspace = NULL, *current_output = NULL; + struct sway_container *focus = sway_seat_get_focus(seat); if (focus) { - current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); - current_output = swayc_parent_by_type(focus, C_OUTPUT); + current_workspace = sway_container_parent(focus, C_WORKSPACE); + current_output = sway_container_parent(focus, C_OUTPUT); } if (strcmp(name, "prev") == 0) { return workspace_prev(current_workspace); @@ -79,12 +79,12 @@ swayc_t *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current_workspace; } else { - return swayc_by_test(&root_container, _workspace_by_name, (void *) name); + return sway_container_find(&root_container, _workspace_by_name, (void *) name); } } -swayc_t *workspace_create(const char *name) { - swayc_t *parent; +struct sway_container *workspace_create(const char *name) { + struct sway_container *parent; // Search for workspace<->output pair int i, e = config->workspace_outputs->length; for (i = 0; i < e; ++i) { @@ -95,7 +95,7 @@ swayc_t *workspace_create(const char *name) { for (i = 0; i < e; ++i) { parent = root_container.children->items[i]; if (strcmp(parent->name, wso->output) == 0) { - return new_workspace(parent, name); + return sway_container_workspace_create(parent, name); } } break; @@ -103,10 +103,10 @@ swayc_t *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); parent = focus; - parent = swayc_parent_by_type(parent, C_OUTPUT); - return new_workspace(parent, name); + parent = sway_container_parent(parent, C_OUTPUT); + return sway_container_workspace_create(parent, name); } /** @@ -114,17 +114,17 @@ swayc_t *workspace_create(const char *name) { * the end and beginning. If next is false, the previous workspace is returned, * otherwise the next one is returned. */ -swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { +struct sway_container *workspace_output_prev_next_impl(struct sway_container *output, bool next) { if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { return NULL; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, output); - swayc_t *workspace = (focus->type == C_WORKSPACE ? + struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + struct sway_container *workspace = (focus->type == C_WORKSPACE ? focus : - swayc_parent_by_type(focus, C_WORKSPACE)); + sway_container_parent(focus, C_WORKSPACE)); int i; for (i = 0; i < output->children->length; i++) { @@ -144,13 +144,13 @@ swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { * next is false, the previous workspace is returned, otherwise the next one is * returned. */ -swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { +struct sway_container *workspace_prev_next_impl(struct sway_container *workspace, bool next) { if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { return NULL; } - swayc_t *current_output = workspace->parent; + struct sway_container *current_output = workspace->parent; int offset = next ? 1 : -1; int start = next ? 0 : 1; int end; @@ -170,7 +170,7 @@ swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { int num_outputs = root_container.children->length; for (i = 0; i < num_outputs; i++) { if (root_container.children->items[i] == current_output) { - swayc_t *next_output = root_container.children->items[ + struct sway_container *next_output = root_container.children->items[ wrap(i + offset, num_outputs)]; return workspace_output_prev_next_impl(next_output, next); } @@ -180,40 +180,40 @@ swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { return NULL; } -swayc_t *workspace_output_next(swayc_t *current) { +struct sway_container *workspace_output_next(struct sway_container *current) { return workspace_output_prev_next_impl(current, true); } -swayc_t *workspace_next(swayc_t *current) { +struct sway_container *workspace_next(struct sway_container *current) { return workspace_prev_next_impl(current, true); } -swayc_t *workspace_output_prev(swayc_t *current) { +struct sway_container *workspace_output_prev(struct sway_container *current) { return workspace_output_prev_next_impl(current, false); } -swayc_t *workspace_prev(swayc_t *current) { +struct sway_container *workspace_prev(struct sway_container *current) { return workspace_prev_next_impl(current, false); } -bool workspace_switch(swayc_t *workspace) { +bool workspace_switch(struct sway_container *workspace) { if (!workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } - swayc_t *active_ws = focus; + struct sway_container *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - swayc_parent_by_type(focus, C_WORKSPACE); + sway_container_parent(focus, C_WORKSPACE); } if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { - swayc_t *new_ws = workspace_by_name(prev_workspace_name); + struct sway_container *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); } @@ -231,12 +231,12 @@ bool workspace_switch(swayc_t *workspace) { // TODO: Deal with sticky containers wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - swayc_t *next = sway_seat_get_focus_inactive(seat, workspace); + struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); if (next == NULL) { next = workspace; } sway_seat_set_focus(seat, next); - swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); + struct sway_container *output = sway_container_parent(workspace, C_OUTPUT); arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From eca029f218fbb54ddf7316845be5d296e834358e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 17:06:29 -0400 Subject: more renaming things --- sway/tree/workspace.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 32e82845..0fdd9975 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -52,7 +52,7 @@ struct sway_container *workspace_by_number(const char* name) { if (wbnd.len <= 0) { return NULL; } - return sway_container_find(&root_container, _workspace_by_number, (void *) &wbnd); + return container_find(&root_container, _workspace_by_number, (void *) &wbnd); } static bool _workspace_by_name(struct sway_container *view, void *data) { @@ -65,8 +65,8 @@ struct sway_container *workspace_by_name(const char *name) { struct sway_container *current_workspace = NULL, *current_output = NULL; struct sway_container *focus = sway_seat_get_focus(seat); if (focus) { - current_workspace = sway_container_parent(focus, C_WORKSPACE); - current_output = sway_container_parent(focus, C_OUTPUT); + current_workspace = container_parent(focus, C_WORKSPACE); + current_output = container_parent(focus, C_OUTPUT); } if (strcmp(name, "prev") == 0) { return workspace_prev(current_workspace); @@ -79,7 +79,7 @@ struct sway_container *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current_workspace; } else { - return sway_container_find(&root_container, _workspace_by_name, (void *) name); + return container_find(&root_container, _workspace_by_name, (void *) name); } } @@ -95,7 +95,7 @@ struct sway_container *workspace_create(const char *name) { for (i = 0; i < e; ++i) { parent = root_container.children->items[i]; if (strcmp(parent->name, wso->output) == 0) { - return sway_container_workspace_create(parent, name); + return container_workspace_create(parent, name); } } break; @@ -105,8 +105,8 @@ struct sway_container *workspace_create(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); parent = focus; - parent = sway_container_parent(parent, C_OUTPUT); - return sway_container_workspace_create(parent, name); + parent = container_parent(parent, C_OUTPUT); + return container_workspace_create(parent, name); } /** @@ -124,7 +124,7 @@ struct sway_container *workspace_output_prev_next_impl(struct sway_container *ou struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); struct sway_container *workspace = (focus->type == C_WORKSPACE ? focus : - sway_container_parent(focus, C_WORKSPACE)); + container_parent(focus, C_WORKSPACE)); int i; for (i = 0; i < output->children->length; i++) { @@ -207,7 +207,7 @@ bool workspace_switch(struct sway_container *workspace) { } struct sway_container *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - sway_container_parent(focus, C_WORKSPACE); + container_parent(focus, C_WORKSPACE); } if (config->auto_back_and_forth @@ -236,7 +236,7 @@ bool workspace_switch(struct sway_container *workspace) { next = workspace; } sway_seat_set_focus(seat, next); - struct sway_container *output = sway_container_parent(workspace, C_OUTPUT); - arrange_windows(output, -1, -1); + struct sway_container *output = container_parent(workspace, C_OUTPUT); + container_arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From 4ec8bf4ceead0b78407c92bf90a42b95740123f9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 18:38:43 -0400 Subject: 80col --- sway/tree/workspace.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 0fdd9975..369cf14c 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -52,7 +52,8 @@ struct sway_container *workspace_by_number(const char* name) { if (wbnd.len <= 0) { return NULL; } - return container_find(&root_container, _workspace_by_number, (void *) &wbnd); + return container_find(&root_container, + _workspace_by_number, (void *) &wbnd); } static bool _workspace_by_name(struct sway_container *view, void *data) { @@ -79,7 +80,8 @@ struct sway_container *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current_workspace; } else { - return container_find(&root_container, _workspace_by_name, (void *) name); + return container_find(&root_container, _workspace_by_name, + (void *)name); } } @@ -103,7 +105,8 @@ struct sway_container *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = + sway_seat_get_focus_inactive(seat, &root_container); parent = focus; parent = container_parent(parent, C_OUTPUT); return container_workspace_create(parent, name); @@ -114,7 +117,8 @@ struct sway_container *workspace_create(const char *name) { * the end and beginning. If next is false, the previous workspace is returned, * otherwise the next one is returned. */ -struct sway_container *workspace_output_prev_next_impl(struct sway_container *output, bool next) { +struct sway_container *workspace_output_prev_next_impl( + struct sway_container *output, bool next) { if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { return NULL; @@ -134,7 +138,8 @@ struct sway_container *workspace_output_prev_next_impl(struct sway_container *ou } } - // Doesn't happen, at worst the for loop returns the previously active workspace + // Doesn't happen, at worst the for loop returns the previously active + // workspace return NULL; } @@ -144,7 +149,8 @@ struct sway_container *workspace_output_prev_next_impl(struct sway_container *ou * next is false, the previous workspace is returned, otherwise the next one is * returned. */ -struct sway_container *workspace_prev_next_impl(struct sway_container *workspace, bool next) { +struct sway_container *workspace_prev_next_impl( + struct sway_container *workspace, bool next) { if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { return NULL; @@ -166,7 +172,8 @@ struct sway_container *workspace_prev_next_impl(struct sway_container *workspace } } - // Given workspace is the first/last on the output, jump to the previous/next output + // Given workspace is the first/last on the output, jump to the + // previous/next output int num_outputs = root_container.children->length; for (i = 0; i < num_outputs; i++) { if (root_container.children->items[i] == current_output) { @@ -176,7 +183,8 @@ struct sway_container *workspace_prev_next_impl(struct sway_container *workspace } } - // Doesn't happen, at worst the for loop returns the previously active workspace on the active output + // Doesn't happen, at worst the for loop returns the previously active + // workspace on the active output return NULL; } @@ -201,7 +209,8 @@ bool workspace_switch(struct sway_container *workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = + sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } @@ -230,7 +239,8 @@ bool workspace_switch(struct sway_container *workspace) { // TODO: Deal with sticky containers - wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + wlr_log(L_DEBUG, "Switching to workspace %p:%s", + workspace, workspace->name); struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); if (next == NULL) { next = workspace; -- cgit v1.2.3 From 2778edef976a669dd0019ebb5327bcfeb4de13c5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 23:15:39 -0400 Subject: arrange windows --- sway/tree/workspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 369cf14c..ba04c55c 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -247,6 +247,6 @@ bool workspace_switch(struct sway_container *workspace) { } sway_seat_set_focus(seat, next); struct sway_container *output = container_parent(workspace, C_OUTPUT); - container_arrange_windows(output, -1, -1); + arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From d0c7f66e950689b70196a890b62b82ff3c66e103 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 23:29:29 -0400 Subject: Revert "Refactor tree" --- sway/tree/workspace.c | 92 +++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 51 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index ba04c55c..861fda4d 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -3,10 +3,10 @@ #include #include #include -#include "sway/tree/container.h" +#include "sway/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" -#include "sway/tree/workspace.h" +#include "sway/workspace.h" #include "log.h" #include "util.h" @@ -17,7 +17,7 @@ struct workspace_by_number_data { const char *name; }; -void next_name_map(struct sway_container *ws, void *data) { +void next_name_map(swayc_t *ws, void *data) { int *count = data; ++count; } @@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) { return name; } -static bool _workspace_by_number(struct sway_container *view, void *data) { +static bool _workspace_by_number(swayc_t *view, void *data) { if (view->type != C_WORKSPACE) { return false; } @@ -46,28 +46,27 @@ static bool _workspace_by_number(struct sway_container *view, void *data) { return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; } -struct sway_container *workspace_by_number(const char* name) { +swayc_t *workspace_by_number(const char* name) { struct workspace_by_number_data wbnd = {0, "1234567890", name}; wbnd.len = strspn(name, wbnd.cset); if (wbnd.len <= 0) { return NULL; } - return container_find(&root_container, - _workspace_by_number, (void *) &wbnd); + return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); } -static bool _workspace_by_name(struct sway_container *view, void *data) { +static bool _workspace_by_name(swayc_t *view, void *data) { return (view->type == C_WORKSPACE) && (strcasecmp(view->name, (char *) data) == 0); } -struct sway_container *workspace_by_name(const char *name) { +swayc_t *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *current_workspace = NULL, *current_output = NULL; - struct sway_container *focus = sway_seat_get_focus(seat); + swayc_t *current_workspace = NULL, *current_output = NULL; + swayc_t *focus = sway_seat_get_focus(seat); if (focus) { - current_workspace = container_parent(focus, C_WORKSPACE); - current_output = container_parent(focus, C_OUTPUT); + current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); + current_output = swayc_parent_by_type(focus, C_OUTPUT); } if (strcmp(name, "prev") == 0) { return workspace_prev(current_workspace); @@ -80,13 +79,12 @@ struct sway_container *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current_workspace; } else { - return container_find(&root_container, _workspace_by_name, - (void *)name); + return swayc_by_test(&root_container, _workspace_by_name, (void *) name); } } -struct sway_container *workspace_create(const char *name) { - struct sway_container *parent; +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) { @@ -97,7 +95,7 @@ struct sway_container *workspace_create(const char *name) { for (i = 0; i < e; ++i) { parent = root_container.children->items[i]; if (strcmp(parent->name, wso->output) == 0) { - return container_workspace_create(parent, name); + return new_workspace(parent, name); } } break; @@ -105,11 +103,10 @@ struct sway_container *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - sway_seat_get_focus_inactive(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); parent = focus; - parent = container_parent(parent, C_OUTPUT); - return container_workspace_create(parent, name); + parent = swayc_parent_by_type(parent, C_OUTPUT); + return new_workspace(parent, name); } /** @@ -117,18 +114,17 @@ struct sway_container *workspace_create(const char *name) { * the end and beginning. If next is false, the previous workspace is returned, * otherwise the next one is returned. */ -struct sway_container *workspace_output_prev_next_impl( - struct sway_container *output, bool next) { +swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { return NULL; } struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); - struct sway_container *workspace = (focus->type == C_WORKSPACE ? + swayc_t *focus = sway_seat_get_focus_inactive(seat, output); + swayc_t *workspace = (focus->type == C_WORKSPACE ? focus : - container_parent(focus, C_WORKSPACE)); + swayc_parent_by_type(focus, C_WORKSPACE)); int i; for (i = 0; i < output->children->length; i++) { @@ -138,8 +134,7 @@ struct sway_container *workspace_output_prev_next_impl( } } - // Doesn't happen, at worst the for loop returns the previously active - // workspace + // Doesn't happen, at worst the for loop returns the previously active workspace return NULL; } @@ -149,14 +144,13 @@ struct sway_container *workspace_output_prev_next_impl( * next is false, the previous workspace is returned, otherwise the next one is * returned. */ -struct sway_container *workspace_prev_next_impl( - struct sway_container *workspace, bool next) { +swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { return NULL; } - struct sway_container *current_output = workspace->parent; + swayc_t *current_output = workspace->parent; int offset = next ? 1 : -1; int start = next ? 0 : 1; int end; @@ -172,57 +166,54 @@ struct sway_container *workspace_prev_next_impl( } } - // Given workspace is the first/last on the output, jump to the - // previous/next output + // Given workspace is the first/last on the output, jump to the previous/next output int num_outputs = root_container.children->length; for (i = 0; i < num_outputs; i++) { if (root_container.children->items[i] == current_output) { - struct sway_container *next_output = root_container.children->items[ + swayc_t *next_output = root_container.children->items[ wrap(i + offset, num_outputs)]; return workspace_output_prev_next_impl(next_output, next); } } - // Doesn't happen, at worst the for loop returns the previously active - // workspace on the active output + // Doesn't happen, at worst the for loop returns the previously active workspace on the active output return NULL; } -struct sway_container *workspace_output_next(struct sway_container *current) { +swayc_t *workspace_output_next(swayc_t *current) { return workspace_output_prev_next_impl(current, true); } -struct sway_container *workspace_next(struct sway_container *current) { +swayc_t *workspace_next(swayc_t *current) { return workspace_prev_next_impl(current, true); } -struct sway_container *workspace_output_prev(struct sway_container *current) { +swayc_t *workspace_output_prev(swayc_t *current) { return workspace_output_prev_next_impl(current, false); } -struct sway_container *workspace_prev(struct sway_container *current) { +swayc_t *workspace_prev(swayc_t *current) { return workspace_prev_next_impl(current, false); } -bool workspace_switch(struct sway_container *workspace) { +bool workspace_switch(swayc_t *workspace) { if (!workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - sway_seat_get_focus_inactive(seat, &root_container); + swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } - struct sway_container *active_ws = focus; + swayc_t *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - container_parent(focus, C_WORKSPACE); + swayc_parent_by_type(focus, C_WORKSPACE); } if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { - struct sway_container *new_ws = workspace_by_name(prev_workspace_name); + swayc_t *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); } @@ -239,14 +230,13 @@ bool workspace_switch(struct sway_container *workspace) { // TODO: Deal with sticky containers - wlr_log(L_DEBUG, "Switching to workspace %p:%s", - workspace, workspace->name); - struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); + wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + swayc_t *next = sway_seat_get_focus_inactive(seat, workspace); if (next == NULL) { next = workspace; } sway_seat_set_focus(seat, next); - struct sway_container *output = container_parent(workspace, C_OUTPUT); + swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From dc8c9fbeb664518c76066cc28ee29452c6c30128 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 29 Mar 2018 23:41:33 -0400 Subject: Revert "Merge pull request #1653 from swaywm/revert-1647-refactor-tree" This reverts commit 472e81f35d689d67cda241acafda91c688d61046, reversing changes made to 6b7841b11ff4cd35f54d69dc92029855893e5ce0. --- sway/tree/workspace.c | 92 ++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 41 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 861fda4d..ba04c55c 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -3,10 +3,10 @@ #include #include #include -#include "sway/container.h" +#include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" -#include "sway/workspace.h" +#include "sway/tree/workspace.h" #include "log.h" #include "util.h" @@ -17,7 +17,7 @@ struct workspace_by_number_data { const char *name; }; -void next_name_map(swayc_t *ws, void *data) { +void next_name_map(struct sway_container *ws, void *data) { int *count = data; ++count; } @@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) { return name; } -static bool _workspace_by_number(swayc_t *view, void *data) { +static bool _workspace_by_number(struct sway_container *view, void *data) { if (view->type != C_WORKSPACE) { return false; } @@ -46,27 +46,28 @@ static bool _workspace_by_number(swayc_t *view, void *data) { return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; } -swayc_t *workspace_by_number(const char* name) { +struct sway_container *workspace_by_number(const char* name) { struct workspace_by_number_data wbnd = {0, "1234567890", name}; wbnd.len = strspn(name, wbnd.cset); if (wbnd.len <= 0) { return NULL; } - return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); + return container_find(&root_container, + _workspace_by_number, (void *) &wbnd); } -static bool _workspace_by_name(swayc_t *view, void *data) { +static bool _workspace_by_name(struct sway_container *view, void *data) { return (view->type == C_WORKSPACE) && (strcasecmp(view->name, (char *) data) == 0); } -swayc_t *workspace_by_name(const char *name) { +struct sway_container *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *current_workspace = NULL, *current_output = NULL; - swayc_t *focus = sway_seat_get_focus(seat); + struct sway_container *current_workspace = NULL, *current_output = NULL; + struct sway_container *focus = sway_seat_get_focus(seat); if (focus) { - current_workspace = swayc_parent_by_type(focus, C_WORKSPACE); - current_output = swayc_parent_by_type(focus, C_OUTPUT); + current_workspace = container_parent(focus, C_WORKSPACE); + current_output = container_parent(focus, C_OUTPUT); } if (strcmp(name, "prev") == 0) { return workspace_prev(current_workspace); @@ -79,12 +80,13 @@ swayc_t *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current_workspace; } else { - return swayc_by_test(&root_container, _workspace_by_name, (void *) name); + return container_find(&root_container, _workspace_by_name, + (void *)name); } } -swayc_t *workspace_create(const char *name) { - swayc_t *parent; +struct sway_container *workspace_create(const char *name) { + struct sway_container *parent; // Search for workspace<->output pair int i, e = config->workspace_outputs->length; for (i = 0; i < e; ++i) { @@ -95,7 +97,7 @@ swayc_t *workspace_create(const char *name) { for (i = 0; i < e; ++i) { parent = root_container.children->items[i]; if (strcmp(parent->name, wso->output) == 0) { - return new_workspace(parent, name); + return container_workspace_create(parent, name); } } break; @@ -103,10 +105,11 @@ swayc_t *workspace_create(const char *name) { } // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = + sway_seat_get_focus_inactive(seat, &root_container); parent = focus; - parent = swayc_parent_by_type(parent, C_OUTPUT); - return new_workspace(parent, name); + parent = container_parent(parent, C_OUTPUT); + return container_workspace_create(parent, name); } /** @@ -114,17 +117,18 @@ swayc_t *workspace_create(const char *name) { * the end and beginning. If next is false, the previous workspace is returned, * otherwise the next one is returned. */ -swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { +struct sway_container *workspace_output_prev_next_impl( + struct sway_container *output, bool next) { if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { return NULL; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, output); - swayc_t *workspace = (focus->type == C_WORKSPACE ? + struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + struct sway_container *workspace = (focus->type == C_WORKSPACE ? focus : - swayc_parent_by_type(focus, C_WORKSPACE)); + container_parent(focus, C_WORKSPACE)); int i; for (i = 0; i < output->children->length; i++) { @@ -134,7 +138,8 @@ swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { } } - // Doesn't happen, at worst the for loop returns the previously active workspace + // Doesn't happen, at worst the for loop returns the previously active + // workspace return NULL; } @@ -144,13 +149,14 @@ swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) { * next is false, the previous workspace is returned, otherwise the next one is * returned. */ -swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { +struct sway_container *workspace_prev_next_impl( + struct sway_container *workspace, bool next) { if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { return NULL; } - swayc_t *current_output = workspace->parent; + struct sway_container *current_output = workspace->parent; int offset = next ? 1 : -1; int start = next ? 0 : 1; int end; @@ -166,54 +172,57 @@ swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) { } } - // Given workspace is the first/last on the output, jump to the previous/next output + // Given workspace is the first/last on the output, jump to the + // previous/next output int num_outputs = root_container.children->length; for (i = 0; i < num_outputs; i++) { if (root_container.children->items[i] == current_output) { - swayc_t *next_output = root_container.children->items[ + struct sway_container *next_output = root_container.children->items[ wrap(i + offset, num_outputs)]; return workspace_output_prev_next_impl(next_output, next); } } - // Doesn't happen, at worst the for loop returns the previously active workspace on the active output + // Doesn't happen, at worst the for loop returns the previously active + // workspace on the active output return NULL; } -swayc_t *workspace_output_next(swayc_t *current) { +struct sway_container *workspace_output_next(struct sway_container *current) { return workspace_output_prev_next_impl(current, true); } -swayc_t *workspace_next(swayc_t *current) { +struct sway_container *workspace_next(struct sway_container *current) { return workspace_prev_next_impl(current, true); } -swayc_t *workspace_output_prev(swayc_t *current) { +struct sway_container *workspace_output_prev(struct sway_container *current) { return workspace_output_prev_next_impl(current, false); } -swayc_t *workspace_prev(swayc_t *current) { +struct sway_container *workspace_prev(struct sway_container *current) { return workspace_prev_next_impl(current, false); } -bool workspace_switch(swayc_t *workspace) { +bool workspace_switch(struct sway_container *workspace) { if (!workspace) { return false; } struct sway_seat *seat = input_manager_current_seat(input_manager); - swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); + struct sway_container *focus = + sway_seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } - swayc_t *active_ws = focus; + struct sway_container *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - swayc_parent_by_type(focus, C_WORKSPACE); + container_parent(focus, C_WORKSPACE); } if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { - swayc_t *new_ws = workspace_by_name(prev_workspace_name); + struct sway_container *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); } @@ -230,13 +239,14 @@ bool workspace_switch(swayc_t *workspace) { // TODO: Deal with sticky containers - wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - swayc_t *next = sway_seat_get_focus_inactive(seat, workspace); + wlr_log(L_DEBUG, "Switching to workspace %p:%s", + workspace, workspace->name); + struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); if (next == NULL) { next = workspace; } sway_seat_set_focus(seat, next); - swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT); + struct sway_container *output = container_parent(workspace, C_OUTPUT); arrange_windows(output, -1, -1); return true; } -- cgit v1.2.3 From e62cc0ac26b20af92ae082b110a3ab77cf0c4e60 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 00:34:24 -0400 Subject: Finish porting over workspace_next_name --- sway/tree/workspace.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 7 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index ba04c55c..5800ea09 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -1,8 +1,11 @@ #define _XOPEN_SOURCE 500 +#include +#include #include #include #include #include +#include "stringop.h" #include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" @@ -22,18 +25,108 @@ void next_name_map(struct sway_container *ws, void *data) { ++count; } +static bool workspace_valid_on_output(const char *output_name, + const char *ws_name) { + int i; + for (i = 0; i < config->workspace_outputs->length; ++i) { + struct workspace_output *wso = config->workspace_outputs->items[i]; + if (strcasecmp(wso->workspace, ws_name) == 0) { + if (strcasecmp(wso->output, output_name) != 0) { + return false; + } + } + } + + return true; +} + char *workspace_next_name(const char *output_name) { wlr_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name); - int count = 0; - next_name_map(&root_container, &count); - ++count; - int len = snprintf(NULL, 0, "%d", count); - char *name = malloc(len + 1); - if (!sway_assert(name, "Failed to allocate workspace name")) { + int l = 1; + // Scan all workspace bindings to find the next available workspace name, + // if none are found/available then default to a number + struct sway_mode *mode = config->current_mode; + + // TODO: iterate over keycode bindings too + int order = INT_MAX; + char *target = NULL; + for (int i = 0; i < mode->keysym_bindings->length; ++i) { + struct sway_binding *binding = mode->keysym_bindings->items[i]; + char *cmdlist = strdup(binding->command); + char *dup = cmdlist; + char *name = NULL; + + // workspace n + char *cmd = argsep(&cmdlist, " "); + if (cmdlist) { + name = argsep(&cmdlist, ",;"); + } + + if (strcmp("workspace", cmd) == 0 && name) { + wlr_log(L_DEBUG, "Got valid workspace command for target: '%s'", name); + char *_target = strdup(name); + strip_quotes(_target); + while (isspace(*_target)) { + memmove(_target, _target+1, strlen(_target+1)); + } + + // 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(_target); + free(dup); + continue; + } + + // Make sure that the workspace doesn't already exist + if (workspace_by_name(_target)) { + free(_target); + free(dup); + continue; + } + + // make sure that the workspace can appear on the given + // output + if (!workspace_valid_on_output(output_name, _target)) { + free(_target); + free(dup); + continue; + } + + if (binding->order < order) { + order = binding->order; + free(target); + target = _target; + wlr_log(L_DEBUG, "Workspace: Found free name %s", _target); + } + } + free(dup); + } + if (target != NULL) { + return target; + } + // As a fall back, get the current number of active workspaces + // and return that + 1 for the next workspace's name + int ws_num = root_container.children->length; + if (ws_num >= 10) { + l = 2; + } else if (ws_num >= 100) { + l = 3; + } + char *name = malloc(l + 1); + if (!name) { + wlr_log(L_ERROR, "Could not allocate workspace name"); return NULL; } - snprintf(name, len + 1, "%d", count); + sprintf(name, "%d", ws_num++); return name; } -- cgit v1.2.3 From 49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 11:58:17 -0400 Subject: Fix workspace deletion edge cases --- sway/tree/workspace.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 5800ea09..c629f1f1 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -6,9 +6,10 @@ #include #include #include "stringop.h" -#include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" +#include "sway/tree/container.h" #include "sway/tree/workspace.h" #include "log.h" #include "util.h" @@ -202,7 +203,48 @@ struct sway_container *workspace_create(const char *name) { sway_seat_get_focus_inactive(seat, &root_container); parent = focus; parent = container_parent(parent, C_OUTPUT); - return container_workspace_create(parent, name); + struct sway_container *new_ws = container_workspace_create(parent, name); + ipc_event_workspace(NULL, new_ws, "init"); + return new_ws; +} + +struct sway_container *container_workspace_destroy( + struct sway_container *workspace) { + if (!sway_assert(workspace, "cannot destroy null workspace")) { + return NULL; + } + + // Do not destroy this if it's the last workspace on this output + struct sway_container *output = container_parent(workspace, C_OUTPUT); + if (output && output->children->length == 1) { + return NULL; + } + + struct sway_container *parent = workspace->parent; + if (workspace->children->length == 0) { + // destroy the WS if there are no children (TODO check for floating) + wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); + ipc_event_workspace(workspace, NULL, "empty"); + } else { + // Move children to a different workspace on this output + struct sway_container *new_workspace = NULL; + // TODO move floating + for (int i = 0; i < output->children->length; i++) { + if (output->children->items[i] != workspace) { + new_workspace = output->children->items[i]; + break; + } + } + + wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", + workspace->name, new_workspace->name); + for (int i = 0; i < workspace->children->length; i++) { + container_move_to(workspace->children->items[i], new_workspace); + } + } + + container_destroy(workspace); + return parent; } /** @@ -343,3 +385,13 @@ bool workspace_switch(struct sway_container *workspace) { arrange_windows(output, -1, -1); return true; } + +bool workspace_is_visible(struct sway_container *ws) { + struct sway_container *output = container_parent(ws, C_OUTPUT); + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + if (focus->type != C_WORKSPACE) { + focus = container_parent(focus, C_WORKSPACE); + } + return focus == ws; +} -- cgit v1.2.3 From c901510e01f7648a549187b128ed9d0f9c5627eb Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Sat, 31 Mar 2018 11:13:20 -0400 Subject: Fixes back-and-forth name saving for non-empty ws --- sway/tree/workspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index c629f1f1..de1bf159 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -351,7 +351,7 @@ bool workspace_switch(struct sway_container *workspace) { } struct sway_container *active_ws = focus; if (active_ws->type != C_WORKSPACE) { - container_parent(focus, C_WORKSPACE); + active_ws = container_parent(focus, C_WORKSPACE); } if (config->auto_back_and_forth -- cgit v1.2.3 From e677c5b204971af00d71f9a50a89206d01b46a36 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 08:45:37 -0400 Subject: rename seat functions --- sway/tree/workspace.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index c629f1f1..c47bab33 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -158,7 +158,7 @@ static bool _workspace_by_name(struct sway_container *view, void *data) { struct sway_container *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *current_workspace = NULL, *current_output = NULL; - struct sway_container *focus = sway_seat_get_focus(seat); + struct sway_container *focus = seat_get_focus(seat); if (focus) { current_workspace = container_parent(focus, C_WORKSPACE); current_output = container_parent(focus, C_OUTPUT); @@ -200,7 +200,7 @@ struct sway_container *workspace_create(const char *name) { // Otherwise create a new one struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = - sway_seat_get_focus_inactive(seat, &root_container); + seat_get_focus_inactive(seat, &root_container); parent = focus; parent = container_parent(parent, C_OUTPUT); struct sway_container *new_ws = container_workspace_create(parent, name); @@ -260,7 +260,7 @@ struct sway_container *workspace_output_prev_next_impl( } struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + struct sway_container *focus = seat_get_focus_inactive(seat, output); struct sway_container *workspace = (focus->type == C_WORKSPACE ? focus : container_parent(focus, C_WORKSPACE)); @@ -345,7 +345,7 @@ bool workspace_switch(struct sway_container *workspace) { } struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = - sway_seat_get_focus_inactive(seat, &root_container); + seat_get_focus_inactive(seat, &root_container); if (!seat || !focus) { return false; } @@ -376,11 +376,11 @@ bool workspace_switch(struct sway_container *workspace) { wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); + struct sway_container *next = seat_get_focus_inactive(seat, workspace); if (next == NULL) { next = workspace; } - sway_seat_set_focus(seat, next); + seat_set_focus(seat, next); struct sway_container *output = container_parent(workspace, C_OUTPUT); arrange_windows(output, -1, -1); return true; @@ -389,7 +389,7 @@ bool workspace_switch(struct sway_container *workspace) { bool workspace_is_visible(struct sway_container *ws) { struct sway_container *output = container_parent(ws, C_OUTPUT); struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + struct sway_container *focus = seat_get_focus_inactive(seat, output); if (focus->type != C_WORKSPACE) { focus = container_parent(focus, C_WORKSPACE); } -- cgit v1.2.3 From b4c5f79725142c78a398a22981392d645bc9d2e9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 12:25:19 -0400 Subject: move view and workspace destructors to container.c --- sway/tree/workspace.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 74330884..7d180009 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -208,45 +208,6 @@ struct sway_container *workspace_create(const char *name) { return new_ws; } -struct sway_container *container_workspace_destroy( - struct sway_container *workspace) { - if (!sway_assert(workspace, "cannot destroy null workspace")) { - return NULL; - } - - // Do not destroy this if it's the last workspace on this output - struct sway_container *output = container_parent(workspace, C_OUTPUT); - if (output && output->children->length == 1) { - return NULL; - } - - struct sway_container *parent = workspace->parent; - if (workspace->children->length == 0) { - // destroy the WS if there are no children (TODO check for floating) - wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); - ipc_event_workspace(workspace, NULL, "empty"); - } else { - // Move children to a different workspace on this output - struct sway_container *new_workspace = NULL; - // TODO move floating - for (int i = 0; i < output->children->length; i++) { - if (output->children->items[i] != workspace) { - new_workspace = output->children->items[i]; - break; - } - } - - wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", - workspace->name, new_workspace->name); - for (int i = 0; i < workspace->children->length; i++) { - container_move_to(workspace->children->items[i], new_workspace); - } - } - - container_destroy(workspace); - return parent; -} - /** * Get the previous or next workspace on the specified output. Wraps around at * the end and beginning. If next is false, the previous workspace is returned, -- cgit v1.2.3 From 5f4761c4f40f5d6ec550ccabaebe0f990b6e8bbc Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:08:45 -0400 Subject: unify workspace create functions --- sway/tree/workspace.c | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 7d180009..d5a16410 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -179,35 +179,6 @@ struct sway_container *workspace_by_name(const char *name) { } } -struct sway_container *workspace_create(const char *name) { - struct sway_container *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 container_workspace_create(parent, name); - } - } - break; - } - } - // Otherwise create a new one - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - seat_get_focus_inactive(seat, &root_container); - parent = focus; - parent = container_parent(parent, C_OUTPUT); - struct sway_container *new_ws = container_workspace_create(parent, name); - ipc_event_workspace(NULL, new_ws, "init"); - return new_ws; -} - /** * Get the previous or next workspace on the specified output. Wraps around at * the end and beginning. If next is false, the previous workspace is returned, @@ -319,7 +290,9 @@ bool workspace_switch(struct sway_container *workspace) { && active_ws == workspace && prev_workspace_name) { struct sway_container *new_ws = workspace_by_name(prev_workspace_name); - workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); + workspace = new_ws ? + new_ws : + container_workspace_create(NULL, prev_workspace_name); } if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) -- cgit v1.2.3 From 1e549230db6b088aae2733e1084c7f953ff88abd Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Tue, 3 Apr 2018 14:37:00 -0400 Subject: Fix name generation for workspace number --- sway/tree/workspace.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index c629f1f1..d6fd7c70 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -87,6 +87,24 @@ char *workspace_next_name(const char *output_name) { continue; } + // If the command is workspace number , isolate the name + if (strncmp(_target, "number ", strlen("number ")) == 0) { + size_t length = strlen(_target) - strlen("number ") + 1; + char *temp = malloc(length); + strncpy(temp, _target + strlen("number "), length - 1); + temp[length - 1] = '\0'; + free(_target); + _target = temp; + wlr_log(L_DEBUG, "Isolated name from workspace number: '%s'", _target); + + // Make sure the workspace number doesn't already exist + if (workspace_by_number(_target)) { + free(_target); + free(dup); + continue; + } + } + // Make sure that the workspace doesn't already exist if (workspace_by_name(_target)) { free(_target); -- cgit v1.2.3 From a001890fb8a9fc8c7f0b8eac03ca5912be2de479 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:52:17 -0400 Subject: move workspace create to workspace.c --- sway/tree/workspace.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index d5a16410..6ba3d973 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -14,6 +14,58 @@ #include "log.h" #include "util.h" +static struct sway_container *get_workspace_initial_output(const char *name) { + struct sway_container *parent; + // Search for workspace<->output pair + int e = config->workspace_outputs->length; + for (int i = 0; i < config->workspace_outputs->length; ++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 parent; + } + } + break; + } + } + // Otherwise put it on the focused output + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = + seat_get_focus_inactive(seat, &root_container); + parent = focus; + parent = container_parent(parent, C_OUTPUT); + return parent; +} + +struct sway_container *workspace_create(struct sway_container *output, + const char *name) { + if (output == NULL) { + output = get_workspace_initial_output(name); + } + + wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); + struct sway_container *workspace = container_create(C_WORKSPACE); + + workspace->x = output->x; + workspace->y = output->y; + workspace->width = output->width; + workspace->height = output->height; + workspace->name = !name ? NULL : strdup(name); + workspace->prev_layout = L_NONE; + workspace->layout = container_get_default_layout(output); + workspace->workspace_layout = workspace->layout; + + container_add_child(output, workspace); + container_sort_workspaces(output); + container_create_notify(workspace); + + return workspace; +} + char *prev_workspace_name = NULL; struct workspace_by_number_data { int len; @@ -292,7 +344,7 @@ bool workspace_switch(struct sway_container *workspace) { struct sway_container *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : - container_workspace_create(NULL, prev_workspace_name); + workspace_create(NULL, prev_workspace_name); } if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) -- cgit v1.2.3 From 764489e73760534d49760af123cae46109564e86 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 6 Apr 2018 15:03:05 -0400 Subject: Break everything^W^WUse wlr_box for sway_container --- sway/tree/workspace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 316f01e4..9e1a8a37 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -50,10 +50,10 @@ struct sway_container *workspace_create(struct sway_container *output, wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); struct sway_container *workspace = container_create(C_WORKSPACE); - workspace->x = output->x; - workspace->y = output->y; - workspace->width = output->width; - workspace->height = output->height; + workspace->box.x = output->box.x; + workspace->box.y = output->box.y; + workspace->box.width = output->box.width; + workspace->box.height = output->box.height; workspace->name = !name ? NULL : strdup(name); workspace->prev_layout = L_NONE; workspace->layout = container_get_default_layout(output); -- cgit v1.2.3 From 640232eb225058a18f20190235f679caf678e1f7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 6 Apr 2018 16:13:26 -0400 Subject: Revert "Break everything^W^WUse wlr_box for sway_container" --- sway/tree/workspace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sway/tree/workspace.c') diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 9e1a8a37..316f01e4 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -50,10 +50,10 @@ struct sway_container *workspace_create(struct sway_container *output, wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); struct sway_container *workspace = container_create(C_WORKSPACE); - workspace->box.x = output->box.x; - workspace->box.y = output->box.y; - workspace->box.width = output->box.width; - workspace->box.height = output->box.height; + workspace->x = output->x; + workspace->y = output->y; + workspace->width = output->width; + workspace->height = output->height; workspace->name = !name ? NULL : strdup(name); workspace->prev_layout = L_NONE; workspace->layout = container_get_default_layout(output); -- cgit v1.2.3