aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sway/commands.c93
-rw-r--r--sway/container.c205
-rw-r--r--sway/container.h63
-rw-r--r--sway/handlers.c84
-rw-r--r--sway/handlers.h3
-rw-r--r--sway/layout.c273
-rw-r--r--sway/layout.h55
-rw-r--r--sway/movement.c8
-rw-r--r--sway/workspace.c28
-rw-r--r--sway/workspace.h2
10 files changed, 491 insertions, 323 deletions
diff --git a/sway/commands.c b/sway/commands.c
index cae35237..a0a95eef 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -228,33 +228,25 @@ static bool cmd_set(struct sway_config *config, int argc, char **argv) {
}
static bool _do_split(struct sway_config *config, int argc, char **argv, int layout) {
- char *name = layout == L_VERT ? "splitv":
- layout == L_HORIZ ? "splith":"split";
+ char *name = layout == L_VERT ? "splitv" :
+ layout == L_HORIZ ? "splith" : "split";
if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)) {
return false;
}
swayc_t *focused = get_focused_container(&root_container);
+
+ /* Case that focus is on an empty workspace. change its layout */
if (focused->type == C_WORKSPACE) {
- sway_log(L_DEBUG, "Dont split workspaces");
- if (focused->children->length == 0) {
- focused->layout = layout;
- }
+ focused->layout = layout;
+ return true;
+ }
+ /* Case of no siblings. change parent layout */
+ if (focused->parent->children->length == 1) {
+ focused->parent->layout = layout;
return true;
}
- swayc_t *parent = focused->parent;
- sway_log(L_DEBUG, "Splitting %p vertically with %p", parent, focused);
- int index = remove_container_from_parent(parent, focused);
- swayc_t *new_container = create_container(parent, -1);
- new_container->layout = layout;
- new_container->weight = focused->weight;
- new_container->width = focused->width;
- new_container->height = focused->height;
- new_container->x = focused->x;
- new_container->y = focused->y;
- focused->weight = 1;
- focused->parent = new_container;
- list_insert(parent->children, index, new_container);
- list_add(new_container->children, focused);
+ /* regular case where new split container is build around focused container */
+ swayc_t *parent = new_container(focused, layout);
focus_view(focused);
arrange_windows(parent, -1, -1);
return true;
@@ -302,15 +294,72 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
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 true;
}
+/* XXX:DEBUG:XXX */
+static void container_log(const swayc_t *c) {
+ fprintf(stderr, "focus:%c|",
+ c == get_focused_container(&root_container) ? 'F' : //Focused
+ c == active_workspace ? 'W' : //active workspace
+ c == &root_container ? 'R' : //root
+ 'X');//not any others
+ fprintf(stderr,"(%p)",c);
+ fprintf(stderr,"(p:%p)",c->parent);
+ fprintf(stderr,"(f:%p)",c->focused);
+ fprintf(stderr,"Type:");
+ fprintf(stderr,
+ c->type == C_ROOT ? "Root|" :
+ c->type == C_OUTPUT ? "Output|" :
+ c->type == C_WORKSPACE ? "Workspace|" :
+ c->type == C_CONTAINER ? "Container|" :
+ c->type == C_VIEW ? "View|" :
+ "Unknown|");
+ fprintf(stderr,"layout:");
+ fprintf(stderr,
+ c->layout == L_NONE ? "NONE|" :
+ c->layout == L_HORIZ ? "Horiz|":
+ c->layout == L_VERT ? "Vert|":
+ c->layout == L_STACKED ? "Stacked|":
+ c->layout == L_FLOATING ? "Floating|":
+ "Unknown|");
+ fprintf(stderr, "w:%d|h:%d|", c->width, c->height);
+ fprintf(stderr, "x:%d|y:%d|", c->x, c->y);
+ fprintf(stderr, "vis:%c|", c->visible?'t':'f');
+ fprintf(stderr, "wgt:%d|", c->weight);
+ fprintf(stderr, "name:%.16s|", c->name);
+ fprintf(stderr, "children:%d\n",c->children?c->children->length:0);
+}
+void layout_log(const swayc_t *c, int depth) {
+ int i;
+ int e = c->children?c->children->length:0;
+ for (i = 0; i < depth; ++i) fputc(' ', stderr);
+ container_log(c);
+ if (e) {
+ for (i = 0; i < depth; ++i) fputc(' ', stderr);
+ fprintf(stderr,"(\n");
+ for (i = 0; i < e; ++i) {
+ layout_log(c->children->items[i], depth + 1);
+ }
+ for (i = 0; i < depth; ++i) fputc(' ', stderr);
+ fprintf(stderr,")\n");
+ }
+}
+bool cmd_debug_print_layout(struct sway_config *config, int argc, char **argv) {
+ fprintf(stderr,"root:%p\nactive workspace:%p\n",&root_container, active_workspace);
+ layout_log(&root_container, 0);
+ return true;
+}
+/* XXX:DEBUG:XXX */
+
/* Keep alphabetized */
static struct cmd_handler handlers[] = {
{ "bindsym", cmd_bindsym },
+ //DEBUG
+ { "debug_print_layout", cmd_debug_print_layout },
+ //DEBUG
{ "exec", cmd_exec },
{ "exec_always", cmd_exec_always },
{ "exit", cmd_exit },
diff --git a/sway/container.c b/sway/container.c
index c637daca..1c17e92f 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -1,18 +1,213 @@
+#include <stdlib.h>
+#include <stdbool.h>
+#include <strings.h>
#include "container.h"
+#include "workspace.h"
#include "layout.h"
+#include "log.h"
-void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
+
+static swayc_t *new_swayc(enum swayc_types type) {
+ swayc_t *c = calloc(1, sizeof(swayc_t));
+ c->handle = -1;
+ c->layout = L_NONE;
+ c->type = type;
+ c->weight = 1;
+ if (type != C_VIEW) {
+ c->children = create_list();
+ }
+ return c;
+}
+
+static void free_swayc(swayc_t *c) {
+ //TODO does not properly handle containers with children,
+ //TODO but functions that call this usually check for that
+ if (c->children) {
+ list_free(c->children);
+ }
+ if (c->parent) {
+ remove_child(c->parent, c);
+ }
+ free(c);
+}
+
+/* New containers */
+static void add_output_widths(swayc_t *container, void *_width) {
+ int *width = _width;
+ if (container->type == C_OUTPUT) {
+ *width += container->width;
+ }
+}
+
+swayc_t *new_output(wlc_handle handle) {
+ sway_log(L_DEBUG, "Added output %d", handle);
+ const struct wlc_size* size = wlc_output_get_resolution(handle);
+
+ swayc_t *output = new_swayc(C_OUTPUT);
+ output->width = size->w;
+ output->height = size->h;
+ output->handle = handle;
+
+ add_child(&root_container, output);
+
+ //TODO something with this
+ int total_width = 0;
+ container_map(&root_container, add_output_widths, &total_width);
+
+ //Create workspace
+ char *ws_name = workspace_next_name();
+ new_workspace(output, ws_name);
+ free(ws_name);
+
+ return output;
+}
+
+swayc_t *new_workspace(swayc_t * output, const char *name) {
+ sway_log(L_DEBUG, "Added workspace %s for output %d", name, output->handle);
+ swayc_t *workspace = new_swayc(C_WORKSPACE);
+
+ workspace->layout = L_HORIZ; // TODO:default layout
+ workspace->width = output->width;
+ workspace->height = output->height;
+ workspace->name = strdup(name);
+ workspace->visible = true;
+
+ add_child(output, workspace);
+ return workspace;
+}
+
+swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
+ swayc_t *cont = new_swayc(C_CONTAINER);
+
+ sway_log(L_DEBUG, "creating container %p around %p", cont, child);
+
+ cont->layout = layout;
+ cont->width = child->width;
+ cont->height = child->height;
+ cont->x = child->x;
+ cont->y = child->y;
+ cont->visible = child->visible;
+
+ swayc_t *parent = replace_child(child, cont);
+ if (parent) {
+ add_child(cont, child);
+ }
+ return cont;
+}
+
+swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
+ const uint32_t type = wlc_view_get_type(handle);
+ const char *title = wlc_view_get_title(handle);
+ /* Skip if unmanaged window */
+ if ((type & WLC_BIT_OVERRIDE_REDIRECT) || (type & WLC_BIT_UNMANAGED) ||
+ (type & WLC_BIT_POPUP) || (type & WLC_BIT_MODAL) || (type & WLC_BIT_SPLASH)) {
+ sway_log(L_DEBUG, "Leaving view %d:%s alone (unmanaged)", handle, title);
+ return NULL;
+ }
+
+ swayc_t *view = new_swayc(C_VIEW);
+ sway_log(L_DEBUG, "Adding new view %d:%s:%d to container %p %d",
+ handle, title, type, sibling, sibling?sibling->type:0);
+ //Setup values
+ view->handle = handle;
+ view->name = strdup(title);
+ view->visible = true;
+
+ //Case of focused workspace, just create as child of it
+ if (sibling->type == C_WORKSPACE) {
+ add_child(sibling, view);
+ }
+ //Regular case, create as sibling of current container
+ else {
+ add_sibling(sibling, view);
+ }
+ return view;
+}
+
+
+swayc_t *destroy_output(swayc_t *output) {
+ if (output->children->length == 0) {
+ //TODO move workspaces to other outputs
+ }
+ sway_log(L_DEBUG, "OUTPUT: Destroying output '%d'", output->handle);
+ free_swayc(output);
+ return &root_container;
+}
+
+swayc_t *destroy_workspace(swayc_t *workspace) {
+ //TODO move containers to other workspaces?
+ //for now just dont delete
+ if (workspace->children->length == 0) {
+ sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name);
+ swayc_t *parent = workspace->parent;
+ free_swayc(workspace);
+ return parent;
+ }
+ return NULL;
+}
+
+swayc_t *destroy_container(swayc_t *container) {
+ while (container->children->length == 0 && container->type == C_CONTAINER) {
+ sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
+ swayc_t *parent = container->parent;
+ free_swayc(container);
+
+ if (parent->focused == container) {
+ parent->focused = NULL;
+ }
+ container = parent;
+ }
+ return container;
+}
+
+swayc_t *destroy_view(swayc_t *view) {
+ if (view == NULL) {
+ sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
+ return NULL;
+ }
+ sway_log(L_DEBUG, "Destroying view '%p'", view);
+ swayc_t *parent = view->parent;
+ free_swayc(view);
+
+ if (parent->focused == view) {
+ parent->focused = NULL;
+ }
+ //Destroy empty containers
+ if (parent->type == C_CONTAINER) {
+ return destroy_container(parent);
+ }
+ return parent;
+}
+
+
+swayc_t *find_container(swayc_t *container, bool (*test)(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];
+ if (test(child, data)) {
+ return child;
+ } else {
+ swayc_t *_ = find_container(child, test, data);
+ if (_) {
+ return _;
+ }
+ }
+ }
+ return NULL;
+}
+
+void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
+ if (!container->children || !container->children->length) {
return;
}
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);
- }
+ container_map(child, f, data);
}
}
diff --git a/sway/container.h b/sway/container.h
index d853661c..a54e016a 100644
--- a/sway/container.h
+++ b/sway/container.h
@@ -1,8 +1,71 @@
#ifndef _SWAY_CONTAINER_H
#define _SWAY_CONTAINER_H
+#include <wlc/wlc.h>
+typedef struct sway_container swayc_t;
#include "layout.h"
+enum swayc_types{
+ C_ROOT,
+ C_OUTPUT,
+ C_WORKSPACE,
+ C_CONTAINER,
+ C_VIEW,
+ //Keep last
+ C_TYPES,
+};
+
+enum swayc_layouts{
+ L_NONE,
+ L_HORIZ,
+ L_VERT,
+ L_STACKED,
+ L_TABBED,
+ L_FLOATING,
+ //Keep last
+ L_LAYOUTS,
+};
+
+struct sway_container {
+ wlc_handle handle;
+
+ enum swayc_types type;
+
+ enum swayc_layouts layout;
+
+ // Not including borders or margins
+ int width, height;
+
+ int x, y;
+
+ bool visible;
+
+ int weight;
+
+ char *name;
+
+ list_t *children;
+
+ struct sway_container *parent;
+ struct sway_container *focused;
+};
+
+
+swayc_t *new_output(wlc_handle handle);
+swayc_t *new_workspace(swayc_t * output, const char *name);
+//Creates container Around child (parent child) -> (parent (container child))
+swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
+//Creates view as a sibling of current focused container, or as child of a workspace
+swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
+
+
+swayc_t *destroy_output(swayc_t *output);
+//destroys workspace if empty and returns parent pointer, else returns NULL
+swayc_t *destroy_workspace(swayc_t *workspace);
+swayc_t *destroy_container(swayc_t *container);
+swayc_t *destroy_view(swayc_t *view);
+
+swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
#endif
diff --git a/sway/handlers.c b/sway/handlers.c
index 48c6cbf7..393a2181 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -9,14 +9,53 @@
#include "commands.h"
#include "handlers.h"
#include "stringop.h"
+#include "workspace.h"
+
+static struct wlc_origin mouse_origin;
+
+static bool pointer_test(swayc_t *view, void *_origin) {
+ const struct wlc_origin *origin = _origin;
+ if (view->type == C_VIEW && origin->x >= view->x && origin->y >= view->y
+ && origin->x < view->x + view->width && origin->y < view->y + view->height
+ && view->visible) {
+ return true;
+ }
+ return false;
+}
+
+void focus_pointer(void) {
+ swayc_t *focused = find_container(&root_container, pointer_test, &mouse_origin);
+ if (focused) {
+ sway_log(L_DEBUG, "Switching focus to %p", focused);
+ unfocus_all(&root_container);
+ focus_view(focused);
+ } else {
+ focus_view(active_workspace);
+ }
+}
static bool handle_output_created(wlc_handle output) {
- add_output(output);
+ swayc_t *op = new_output(output);
+
+ //Switch to workspace if we need to
+ if (active_workspace == NULL) {
+ swayc_t *ws = op->children->items[0];
+ workspace_switch(ws);
+ }
return true;
}
static void handle_output_destroyed(wlc_handle output) {
- destroy_output(output);
+ int i;
+ list_t *list = root_container.children;
+ for (i = 0; i < list->length; ++i) {
+ if (((swayc_t *)list->items[i])->handle == output) {
+ break;
+ }
+ }
+ if (i < list->length) {
+ destroy_output(list->items[i]);
+ }
}
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
@@ -37,14 +76,33 @@ static void handle_output_focused(wlc_handle output, bool focus) {
}
}
-static bool handle_view_created(wlc_handle view) {
- add_view(view);
+static bool handle_view_created(wlc_handle handle) {
+ swayc_t *container = get_focused_container(&root_container);
+ swayc_t *view = new_view(container, handle);
+ unfocus_all(&root_container);
+ if (view) {
+ focus_view(view);
+ arrange_windows(view->parent, -1, -1);
+ } else { //Unmanaged view
+ wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
+ wlc_view_focus(handle);
+ }
return true;
}
-static void handle_view_destroyed(wlc_handle view) {
- sway_log(L_DEBUG, "Destroying window %d", view);
- destroy_view(get_swayc_for_handle(view, &root_container));
+static void handle_view_destroyed(wlc_handle handle) {
+ sway_log(L_DEBUG, "Destroying window %d", handle);
+ swayc_t *view = get_swayc_for_handle(handle, &root_container);
+ swayc_t *parent;
+ swayc_t *focused = get_focused_container(&root_container);
+
+ if (view) {
+ parent = destroy_view(view);
+ arrange_windows(parent, -1, -1);
+ }
+ if (!focused || focused == view) {
+ focus_pointer();
+ }
}
static void handle_view_focus(wlc_handle view, bool focus) {
@@ -121,18 +179,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
return cmd_success;
}
-bool pointer_test(swayc_t *view, void *_origin) {
- const struct wlc_origin *origin = _origin;
- if (view->type == C_VIEW && origin->x >= view->x && origin->y >= view->y
- && origin->x < view->x + view->width && origin->y < view->y + view->height
- && view->visible) {
- return true;
- }
- return false;
-}
-
-struct wlc_origin mouse_origin;
-
static bool handle_pointer_motion(wlc_handle view, uint32_t time, const struct wlc_origin *origin) {
mouse_origin = *origin;
if (!config->focus_follows_mouse) {
diff --git a/sway/handlers.h b/sway/handlers.h
index 798b3b50..b8b171c3 100644
--- a/sway/handlers.h
+++ b/sway/handlers.h
@@ -6,4 +6,7 @@
extern struct wlc_interface interface;
+//set focus to current pointer location
+void focus_pointer(void);
+
#endif
diff --git a/sway/layout.c b/sway/layout.c
index ccf29f34..0db4dc4d 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -9,25 +9,75 @@
swayc_t root_container;
-swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
- if (!container->children) {
+void init_layout(void) {
+ root_container.type = C_ROOT;
+ root_container.layout = L_NONE;
+ root_container.children = create_list();
+ root_container.handle = -1;
+}
+
+static int index_child(swayc_t *parent, swayc_t *child) {
+ int i;
+ for (i = 0; i < parent->children->length; ++i) {
+ if (parent->children->items[i] == child) {
+ break;
+ }
+ }
+ return i;
+}
+
+void add_child(swayc_t *parent, swayc_t *child) {
+ sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
+ child->width, child->height, parent, parent->type, parent->width, parent->height);
+ list_add(parent->children, child);
+ child->parent = parent;
+ if(parent->focused == NULL) {
+ parent->focused = child;
+ }
+}
+
+swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) {
+ swayc_t *parent = sibling->parent;
+ int i = index_child(parent, sibling);
+ if (i == parent->children->length) {
+ --i;
+ }
+ list_insert(parent->children, i+1, child);
+ child->parent = parent;
+ return child->parent;
+}
+
+swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
+ swayc_t *parent = child->parent;
+ if (parent == NULL) {
return NULL;
}
+ int i = index_child(parent, child);
+ parent->children->items[i] = new_child;
+ new_child->parent = child->parent;
+
+ if (child->parent->focused == child) {
+ child->parent->focused = new_child;
+ }
+ child->parent = NULL;
+ return parent;
+}
+
+swayc_t *remove_child(swayc_t *parent, swayc_t *child) {
int i;
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- if (test(child, data)) {
- return child;
- } else {
- swayc_t *_ = find_container(child, test, data);
- if (_) {
- return _;
- }
+ for (i = 0; i < parent->children->length; ++i) {
+ if (parent->children->items[i] == child) {
+ list_del(parent->children, i);
+ break;
}
}
- return NULL;
+ if (parent->focused == child) {
+ parent->focused = NULL;
+ }
+ return parent;
}
+
void arrange_windows(swayc_t *container, int width, int height) {
int i;
if (width == -1 || height == -1) {
@@ -131,25 +181,6 @@ void arrange_windows(swayc_t *container, int width, int height) {
}
}
-void init_layout(void) {
- root_container.type = C_ROOT;
- root_container.layout = L_NONE;
- root_container.children = create_list();
- root_container.handle = -1;
-}
-
-void free_swayc(swayc_t *container) {
- // NOTE: Does not handle moving children into a different container
- if (container->parent) {
- remove_container_from_parent(container->parent, container);
- }
- list_free(container->children);
- if (container->name) {
- free(container->name);
- }
- free(container);
-}
-
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
if (parent->children == NULL) {
return NULL;
@@ -176,99 +207,6 @@ swayc_t *get_focused_container(swayc_t *parent) {
return get_focused_container(parent->focused);
}
-void add_view(wlc_handle view_handle) {
- const uint32_t type = wlc_view_get_type(view_handle);
- const char *title = wlc_view_get_title(view_handle);
- if ((type & WLC_BIT_OVERRIDE_REDIRECT) || (type & WLC_BIT_UNMANAGED) || (type &
- WLC_BIT_POPUP) || (type & WLC_BIT_MODAL) || (type & WLC_BIT_SPLASH)) {
- sway_log(L_DEBUG, "Leaving view %d:%s alone (unmanaged)", view_handle, title);
- unfocus_all(&root_container);
- wlc_view_set_state(view_handle, WLC_BIT_ACTIVATED, true);
- wlc_view_focus(view_handle);
- return;
- }
-
- swayc_t *parent = get_focused_container(&root_container);
- sway_log(L_DEBUG, "Adding new view %d:%s:%d under container %p %d", view_handle, title, type, parent, parent->type);
-
- while (parent->type == C_VIEW) {
- parent = parent->parent;
- }
-
- swayc_t *view = calloc(1, sizeof(swayc_t));
- view->weight = 1;
- view->layout = L_NONE;
- view->handle = view_handle;
- view->parent = parent;
- view->type = C_VIEW;
- view->visible = true;
- if (title) {
- view->name = malloc(strlen(title) + 1);
- strcpy(view->name, title);
- }
- add_child(parent, view);
-
- unfocus_all(&root_container);
- focus_view(view);
-
- arrange_windows(parent, -1, -1);
-}
-
-int remove_container_from_parent(swayc_t *parent, swayc_t *container) {
- int i;
- for (i = 0; i < parent->children->length; ++i) {
- if (parent->children->items[i] == container) {
- list_del(parent->children, i);
- break;
- }
- }
-
- if (parent->focused == container) {
- parent->focused = NULL;
- }
-
- return i;
-}
-
-void destroy_view(swayc_t *view) {
- if (view == NULL) {
- sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
- return;
- }
- sway_log(L_DEBUG, "Destroying container %p", view);
- swayc_t *parent = view->parent;
- if (!parent) {
- return;
- }
-
- int i;
- for (i = 0; i < parent->children->length; ++i) {
- if (parent->children->items[i] == view) {
- list_del(parent->children, i);
- break;
- }
- }
-
- free_swayc(view);
-
- if (parent->focused == view) {
- parent->focused = NULL;
- }
-
- unfocus_all(&root_container);
- if (parent->children->length != 0) {
- focus_view(parent->children->items[0]);
- } else {
- focus_view(parent);
- }
-
- arrange_windows(parent, -1, -1);
-
- if (parent->children->length == 0 && parent->type == C_CONTAINER) {
- destroy_view(parent);
- }
-}
-
void unfocus_all(swayc_t *container) {
if (container->children == NULL) {
return;
@@ -285,85 +223,16 @@ void unfocus_all(swayc_t *container) {
}
void focus_view(swayc_t *view) {
- sway_log(L_DEBUG, "Setting focus for %p", view);
- if (view == &root_container) {
- // Propegate wayland focus down
- swayc_t *child = view->focused;
- while (child && child->type != C_VIEW) {
- child = child->focused;
- }
- if (child) {
- wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, true);
- wlc_view_focus(child->handle);
- }
- return;
- }
- view->parent->focused = view;
- focus_view(view->parent);
-}
-
-void add_child(swayc_t *parent, swayc_t *child) {
- sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
- child->width, child->height, parent, parent->type, parent->width, parent->height);
- list_add(parent->children, child);
-}
-
-swayc_t *create_container(swayc_t *parent, wlc_handle handle) {
- swayc_t *c = calloc(1, sizeof(swayc_t));
- c->weight = 1;
- c->handle = handle;
- c->parent = parent;
- c->layout = L_NONE;
- c->type = C_CONTAINER;
- c->children = create_list();
- return c;
-}
-
-void add_output_widths(swayc_t *container, void *_width) {
- int *width = _width;
- if (container->type == C_OUTPUT) {
- *width += container->width;
+ sway_log(L_DEBUG, "Setting focus to %p", view);
+ if (view->type == C_VIEW) {
+ wlc_view_set_state(view->handle, WLC_BIT_ACTIVATED, true);
+ wlc_view_bring_to_front(view->handle);
+ wlc_view_focus(view->handle);
}
-}
-
-void add_output(wlc_handle output) {
- sway_log(L_DEBUG, "Adding output %d", output);
- const struct wlc_size* size = wlc_output_get_resolution(output);
-
- swayc_t *container = create_container(&root_container, output);
- container->type = C_OUTPUT;
- container->width = size->w;
- container->height = size->h;
- add_child(&root_container, container);
-
- int total_width = 0;
- container_map(&root_container, add_output_widths, &total_width);
-
- 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);
- sway_log(L_DEBUG, "Added workspace %s for output %d", workspace->name, output);
-
- if (root_container.focused == NULL) {
- workspace_switch(workspace);
- unfocus_all(&root_container);
- focus_view(workspace);
+ // Propagete focus up
+ while (view != &root_container) {
+ view->parent->focused = view;
+ view = view->parent;
}
}
-void destroy_output(wlc_handle output) {
- sway_log(L_DEBUG, "Destroying output %d", output);
- int i;
- for (i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (c->handle == output) {
- list_del(root_container.children, i);
- free_swayc(c);
- return;
- }
- }
-}
diff --git a/sway/layout.h b/sway/layout.h
index b4769e08..a136f917 100644
--- a/sway/layout.h
+++ b/sway/layout.h
@@ -3,62 +3,23 @@
#include <wlc/wlc.h>
#include "list.h"
-
-struct sway_container {
- wlc_handle handle;
-
- enum {
- C_ROOT,
- C_OUTPUT,
- C_WORKSPACE,
- C_CONTAINER,
- C_VIEW
- } type;
-
- enum {
- L_NONE,
- L_HORIZ,
- L_VERT,
- L_STACKED,
- L_TABBED,
- L_FLOATING
- } layout;
-
- // Not including borders or margins
- int width, height;
-
- int x, y;
-
- bool visible;
-
- int weight;
-
- char *name;
-
- list_t *children;
-
- struct sway_container *parent;
- struct sway_container *focused;
-};
-
-typedef struct sway_container swayc_t;
+#include "container.h"
extern swayc_t root_container;
void init_layout(void);
+
void add_child(swayc_t *parent, swayc_t *child);
-void add_output(wlc_handle output);
-void destroy_output(wlc_handle output);
-void destroy_view(swayc_t *view);
-void add_view(wlc_handle view);
+//Returns parent container wihch needs to be rearranged.
+swayc_t *add_sibling(swayc_t *sibling, swayc_t *child);
+swayc_t *replace_child(swayc_t *child, swayc_t *new_child);
+swayc_t *remove_child(swayc_t *parent, swayc_t *child);
+
void unfocus_all(swayc_t *container);
void focus_view(swayc_t *view);
void arrange_windows(swayc_t *container, int width, int height);
-swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
swayc_t *get_focused_container(swayc_t *parent);
-int remove_container_from_parent(swayc_t *parent, swayc_t *container);
-swayc_t *create_container(swayc_t *parent, wlc_handle handle);
-void free_swayc(swayc_t *container);
+
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
#endif
diff --git a/sway/movement.c b/sway/movement.c
index 166e6508..de987679 100644
--- a/sway/movement.c
+++ b/sway/movement.c
@@ -10,14 +10,12 @@ bool move_focus(enum movement_direction direction) {
swayc_t *parent = current->parent;
if (direction == MOVE_PARENT) {
- current = parent;
- parent = parent->parent;
- if (parent->type == C_ROOT) {
+ if (parent->type == C_OUTPUT) {
sway_log(L_DEBUG, "Focus cannot move to parent");
return false;
} else {
- sway_log(L_DEBUG, "Moving focus away from %p", current);
- unfocus_all(parent);
+ sway_log(L_DEBUG, "Moving focus away from %p to %p", current, parent);
+ unfocus_all(parent->parent);
focus_view(parent);
return true;
}
diff --git a/sway/workspace.c b/sway/workspace.c
index 906d0c5d..88596dfe 100644
--- a/sway/workspace.c
+++ b/sway/workspace.c
@@ -6,6 +6,7 @@
#include "list.h"
#include "log.h"
#include "container.h"
+#include "handlers.h"
#include "config.h"
#include "stringop.h"
@@ -71,16 +72,7 @@ swayc_t *workspace_create(const char* name) {
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;
+ return new_workspace(parent, name);
}
bool workspace_by_name(swayc_t *view, void *data) {
@@ -88,23 +80,13 @@ bool workspace_by_name(swayc_t *view, void *data) {
(strcasecmp(view->name, (char *) data) == 0);
}
-bool workspace_destroy(swayc_t *workspace) {
- //Dont destroy if there are children
- if (workspace->children->length) {
- return false;
- }
- sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name);
- free_swayc(workspace);
- return true;
-}
-
void set_mask(swayc_t *view, void *data) {
uint32_t *p = data;
if(view->type == C_VIEW) {
wlc_view_set_mask(view->handle, *p);
- view->visible = (*p == 2);
}
+ view->visible = (*p == 2);
}
swayc_t *workspace_find_by_name(const char* name) {
@@ -123,9 +105,9 @@ void workspace_switch(swayc_t *workspace) {
container_map(workspace, set_mask, &mask);
wlc_output_set_mask(wlc_get_focused_output(), 2);
- unfocus_all(active_workspace);
+ unfocus_all(&root_container);
focus_view(workspace);
- workspace_destroy(active_workspace);
+ destroy_workspace(active_workspace);
}
active_workspace = workspace;
}
diff --git a/sway/workspace.h b/sway/workspace.h
index 19f0d4c1..523ce633 100644
--- a/sway/workspace.h
+++ b/sway/workspace.h
@@ -5,6 +5,8 @@
#include "list.h"
#include "layout.h"
+extern swayc_t *active_workspace;
+
char *workspace_next_name(void);
swayc_t *workspace_create(const char*);
swayc_t *workspace_find_by_name(const char*);