aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sway/commands.c19
-rw-r--r--sway/container.c18
-rw-r--r--sway/container.h8
-rw-r--r--sway/layout.c4
-rw-r--r--sway/workspace.c67
-rw-r--r--sway/workspace.h13
6 files changed, 128 insertions, 1 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 2ce24fa4..94d5a7ff 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -10,6 +10,7 @@
#include "layout.h"
#include "movement.h"
#include "log.h"
+#include "workspace.h"
#include "commands.h"
struct modifier_key {
@@ -262,6 +263,21 @@ int cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
return 1;
}
+int cmd_workspace(struct sway_config *config, int argc, char **argv) {
+ if (argc != 1) {
+ sway_log(L_ERROR, "Invalid workspace command (expected 1 arguments, got %d)", argc);
+ return 1;
+ }
+
+ swayc_t *workspace = workspace_find_by_name(argv[0]);
+ if (!workspace) {
+ workspace = workspace_create(argv[0]);
+ } else sway_log(L_DEBUG, "workspace exists, all ok");
+
+ workspace_switch(workspace);
+ return 1;
+}
+
/* Keep alphabetized */
struct cmd_handler handlers[] = {
{ "bindsym", cmd_bindsym },
@@ -276,7 +292,8 @@ struct cmd_handler handlers[] = {
{ "reload", cmd_reload },
{ "set", cmd_set },
{ "splith", cmd_splith },
- { "splitv", cmd_splitv }
+ { "splitv", cmd_splitv },
+ { "workspace", cmd_workspace }
};
char **split_directive(char *line, int *argc) {
diff --git a/sway/container.c b/sway/container.c
new file mode 100644
index 00000000..8ceb6a30
--- /dev/null
+++ b/sway/container.c
@@ -0,0 +1,18 @@
+#include "container.h"
+#include "layout.h"
+
+void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
+ if (!container->children) {
+ return NULL;
+ }
+ int i;
+ for (i = 0; i < container->children->length; ++i) {
+ swayc_t *child = container->children->items[i];
+ f(child, data);
+
+ if(child->children)
+ container_map(child, f, data);
+ }
+ return NULL;
+}
+
diff --git a/sway/container.h b/sway/container.h
new file mode 100644
index 00000000..d853661c
--- /dev/null
+++ b/sway/container.h
@@ -0,0 +1,8 @@
+#ifndef _SWAY_CONTAINER_H
+#define _SWAY_CONTAINER_H
+
+#include "layout.h"
+
+void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
+
+#endif
diff --git a/sway/layout.c b/sway/layout.c
index 4b156add..28fe33de 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -4,6 +4,7 @@
#include "list.h"
#include "log.h"
#include "layout.h"
+#include "workspace.h"
swayc_t root_container;
@@ -314,11 +315,14 @@ void add_output(wlc_handle output) {
swayc_t *workspace = create_container(container, -1);
workspace->type = C_WORKSPACE;
+ workspace->name = workspace_next_name();
workspace->width = size->w; // TODO: gaps
workspace->height = size->h;
workspace->layout = L_HORIZ; // TODO: Get default layout from config
add_child(container, workspace);
+ workspace_switch(workspace);
+
if (root_container.focused == NULL) {
unfocus_all(&root_container);
focus_view(workspace);
diff --git a/sway/workspace.c b/sway/workspace.c
new file mode 100644
index 00000000..1c8cef2c
--- /dev/null
+++ b/sway/workspace.c
@@ -0,0 +1,67 @@
+#include <stdlib.h>
+#include <stdbool.h>
+#include <wlc/wlc.h>
+#include "workspace.h"
+#include "layout.h"
+#include "list.h"
+#include "log.h"
+#include "container.h"
+
+swayc_t *active_workspace = NULL;
+
+char *workspace_next_name() {
+ return "1";
+}
+
+swayc_t *workspace_create(const char* name) {
+ swayc_t *parent = get_focused_container(&root_container);
+ while(parent->type != C_OUTPUT) {
+ parent = parent->parent;
+ }
+
+ swayc_t *workspace = create_container(parent, -1);
+ workspace->type = C_WORKSPACE;
+ workspace->name = strdup(name);
+ workspace->width = parent->width;
+ workspace->height = parent->height;
+ workspace->layout = L_HORIZ; // todo: thing
+
+ add_child(parent, workspace);
+ return workspace;
+}
+
+bool workspace_by_name(swayc_t *view, void *data) {
+ return (view->type == C_WORKSPACE) &&
+ (strcasecmp(view->name, (char *) data) == 0);
+}
+
+void set_mask(swayc_t *view, void *data) {
+ uint32_t *p = data;
+
+ if(view->type == C_VIEW) {
+ wlc_view_set_mask(view->handle, *p);
+ }
+}
+
+swayc_t *workspace_find_by_name(const char* name) {
+ return find_container(&root_container, workspace_by_name, (void *) name);
+}
+
+void workspace_switch(swayc_t *workspace) {
+ if(active_workspace) {
+ sway_log(L_DEBUG, "workspace: changing from %s to %s", active_workspace->name, workspace->name);
+
+ uint32_t mask = 1;
+ // set all c_views in the old workspace to the invisible mask
+ container_map(active_workspace, set_mask, &mask);
+ // and c_views in the new workspace to the visible mask
+ mask = 2;
+ container_map(workspace, set_mask, &mask);
+
+ wlc_output_set_mask(wlc_get_focused_output(), 2);
+ unfocus_all(active_workspace);
+ focus_view(workspace);
+ }
+
+ active_workspace = workspace;
+}
diff --git a/sway/workspace.h b/sway/workspace.h
new file mode 100644
index 00000000..bc7eed55
--- /dev/null
+++ b/sway/workspace.h
@@ -0,0 +1,13 @@
+#ifndef _SWAY_WORKSPACE_H
+#define _SWAY_WORKSPACE_H
+
+#include <wlc/wlc.h>
+#include "list.h"
+#include "layout.h"
+
+char *workspace_next_name();
+swayc_t *workspace_create(const char*);
+swayc_t *workspace_find_by_name(const char*);
+void workspace_switch(swayc_t*);
+
+#endif