diff --git a/include/sway/container.h b/include/sway/container.h index 35d1c146..2a96165f 100644 --- a/include/sway/container.h +++ b/include/sway/container.h @@ -126,5 +126,6 @@ struct sway_container { }; swayc_t *new_output(struct sway_output *sway_output); +swayc_t *new_workspace(swayc_t *output, const char *name); #endif diff --git a/include/sway/layout.h b/include/sway/layout.h index 7e7a9c35..6356ad00 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h @@ -5,5 +5,7 @@ struct sway_container; void init_layout(void); void add_child(struct sway_container *parent, struct sway_container *child); +enum swayc_layouts default_layout(struct sway_container *output); +void sort_workspaces(struct sway_container *output); #endif diff --git a/include/sway/workspace.h b/include/sway/workspace.h new file mode 100644 index 00000000..04b2ea4e --- /dev/null +++ b/include/sway/workspace.h @@ -0,0 +1,6 @@ +#ifndef _SWAY_WORKSPACE_H +#define _SWAY_WORKSPACE_H + +char *workspace_next_name(const char *output_name); + +#endif diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt index 9a92466c..6d520e76 100644 --- a/sway/CMakeLists.txt +++ b/sway/CMakeLists.txt @@ -14,8 +14,9 @@ add_executable(sway desktop/output.c desktop/xdg_shell_v6.c - tree/layout.c tree/container.c + tree/layout.c + tree/workspace.c base64.c main.c diff --git a/sway/tree/container.c b/sway/tree/container.c index 54bcf478..ac79356a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -5,6 +5,8 @@ #include "sway/container.h" #include "sway/layout.h" #include "sway/output.h" +#include "sway/workspace.h" +#include "log.h" static swayc_t *new_swayc(enum swayc_types type) { // next id starts at 1 because 0 is assigned to root_container in layout.c @@ -27,8 +29,8 @@ static swayc_t *new_swayc(enum swayc_types type) { swayc_t *new_output(struct sway_output *sway_output) { struct wlr_box size; - wlr_output_effective_resolution(sway_output->wlr_output, - &size.width, &size.height); + wlr_output_effective_resolution( + sway_output->wlr_output, &size.width, &size.height); const char *name = sway_output->wlr_output->name; swayc_t *output = new_swayc(C_OUTPUT); @@ -39,7 +41,31 @@ swayc_t *new_output(struct sway_output *sway_output) { add_child(&root_container, output); - // TODO: Create workspace - + // Create workspace + char *ws_name = workspace_next_name(output->name); + sway_log(L_DEBUG, "Creating default workspace %s", ws_name); + new_workspace(output, ws_name); + free(ws_name); return output; } + +swayc_t *new_workspace(swayc_t *output, const char *name) { + if (!sway_assert(output, "new_workspace called with null output")) { + return NULL; + } + sway_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); + swayc_t *workspace = new_swayc(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 = default_layout(output); + workspace->workspace_layout = default_layout(output); + + add_child(output, workspace); + sort_workspaces(output); + return workspace; +} diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 06200bbf..5a70c570 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -1,5 +1,7 @@ #define _POSIX_C_SOURCE 200809L +#include #include +#include #include #include #include "sway/container.h" @@ -33,3 +35,38 @@ void add_child(swayc_t *parent, swayc_t *child) { } */ } + +enum swayc_layouts default_layout(swayc_t *output) { + /* TODO WLR + if (config->default_layout != L_NONE) { + //return config->default_layout; + } else if (config->default_orientation != L_NONE) { + return config->default_orientation; + } else */if (output->width >= output->height) { + return L_HORIZ; + } else { + return L_VERT; + } +} + +static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { + swayc_t *a = *(void **)_a; + swayc_t *b = *(void **)_b; + int retval = 0; + + if (isdigit(a->name[0]) && isdigit(b->name[0])) { + int a_num = strtol(a->name, NULL, 10); + int b_num = strtol(b->name, NULL, 10); + retval = (a_num < b_num) ? -1 : (a_num > b_num); + } else if (isdigit(a->name[0])) { + retval = -1; + } else if (isdigit(b->name[0])) { + retval = 1; + } + + return retval; +} + +void sort_workspaces(swayc_t *output) { + list_stable_sort(output->children, sort_workspace_cmp_qsort); +} 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; +}