aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-08 17:44:51 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-08 17:44:51 -0400
commit148f59f3a670a7008bc6c2bc07712fd58b1f6e69 (patch)
tree7feeaaac853eb847a49e583882de5be50b1c737b
parentAdd logging and new windows into layout tree (diff)
downloadsway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.tar.gz
sway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.tar.zst
sway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.zip
Refactor in-memory tree
-rw-r--r--sway/handlers.c5
-rw-r--r--sway/layout.c168
-rw-r--r--sway/layout.h47
-rw-r--r--sway/list.c3
4 files changed, 133 insertions, 90 deletions
diff --git a/sway/handlers.c b/sway/handlers.c
index af33f785..27087295 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -22,12 +22,11 @@ bool handle_view_created(wlc_handle view) {
22} 22}
23 23
24void handle_view_destroyed(wlc_handle view) { 24void handle_view_destroyed(wlc_handle view) {
25 destroy_view(view); 25 destroy_view(get_swayc_for_handle(view, &root_container));
26 return true; 26 return true;
27} 27}
28 28
29void handle_view_focus(wlc_handle view, bool focus) { 29void handle_view_focus(wlc_handle view, bool focus) {
30 printf("View focused\n");
31 wlc_view_set_state(view, WLC_BIT_ACTIVATED, focus); 30 wlc_view_set_state(view, WLC_BIT_ACTIVATED, focus);
32 focused_view = view; 31 focus_view(get_swayc_for_handle(view, &root_container));
33} 32}
diff --git a/sway/layout.c b/sway/layout.c
index e95ee423..f2fe4021 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -5,40 +5,37 @@
5#include "log.h" 5#include "log.h"
6#include "layout.h" 6#include "layout.h"
7 7
8list_t *outputs; 8swayc_t root_container;
9wlc_handle focused_view;
10 9
11void arrange_windows() { 10void arrange_windows() {
11 // TODO
12} 12}
13 13
14void init_layout() { 14void init_layout() {
15 outputs = create_list(); 15 root_container.type = C_ROOT;
16 focused_view = -1; 16 root_container.layout = L_HORIZ; // TODO: Default layout
17 root_container.children = create_list();
18 root_container.handle = -1;
17} 19}
18 20
19struct sway_container *get_container(wlc_handle output, int *index) { 21void free_swayc(swayc_t *container) {
20 int i; 22 // NOTE: Does not handle moving children into a different container
21 for (i = 0; i < outputs->length; ++i) { 23 list_free(container->children);
22 struct sway_container *c = outputs->items[i]; 24 free(container);
23 if (c->output == output) {
24 return c;
25 }
26 }
27 return NULL;
28} 25}
29 26
30struct sway_container *get_container_for_view_recurse(wlc_handle handle, int *index, struct sway_container *parent) { 27swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
31 int j; 28 if (parent->children == NULL) {
32 for (j = 0; j < parent->children->length; ++j) { 29 return NULL;
33 struct sway_container *child = parent->children->items[j]; 30 }
34 if (child->layout == LAYOUT_IS_VIEW) { 31 int i;
35 if (child->output == handle) { 32 for (i = 0; i < parent->children->length; ++i) {
36 *index = j; 33 swayc_t *child = parent->children->items[i];
37 return parent; 34 if (child->handle == handle) {
38 } 35 return child;
39 } else { 36 } else {
40 struct sway_container *res; 37 swayc_t *res;
41 if ((res = get_container_for_view_recurse(handle, index, child))) { 38 if ((res = get_swayc_for_handle(handle, child))) {
42 return res; 39 return res;
43 } 40 }
44 } 41 }
@@ -46,77 +43,102 @@ struct sway_container *get_container_for_view_recurse(wlc_handle handle, int *in
46 return NULL; 43 return NULL;
47} 44}
48 45
49struct sway_container *get_container_for_view(wlc_handle handle, int *index) { 46swayc_t *get_focused_container(swayc_t *parent) {
50 int i; 47 if (parent->focused == NULL) {
51 for (i = 0; i < outputs->length; ++i) { 48 return parent;
52 struct sway_container *c = outputs->items[i];
53 struct sway_container *res;
54 if ((res = get_container_for_view_recurse(handle, index, c))) {
55 return res;
56 }
57 } 49 }
58 return NULL; 50 return get_focused_container(parent->focused);
59} 51}
60 52
61void add_view(wlc_handle view_handle) { 53void add_view(wlc_handle view_handle) {
62 struct sway_container *container; 54 swayc_t *parent = get_focused_container(&root_container);
63 int _; 55 sway_log(L_DEBUG, "Adding new view %d under container %d", view_handle, (int)parent->type);
64 56
65 if (focused_view == -1) { // Add it to the output container 57 while (parent->type == C_VIEW) {
66 sway_log(L_DEBUG, "Adding initial view for output", view_handle); 58 parent = parent->parent;
67 wlc_handle output = wlc_get_focused_output();
68 container = get_container(output, &_);
69 } else {
70 sway_log(L_DEBUG, "Adding view %d to output", view_handle);
71 // TODO
72 } 59 }
73 60
74 // Create "container" for this view 61 swayc_t *view = calloc(1, sizeof(swayc_t));
75 struct sway_container *view = malloc(sizeof(struct sway_container)); 62 view->layout = L_NONE;
76 view->layout = LAYOUT_IS_VIEW; 63 view->handle = view_handle;
77 view->children = NULL; 64 view->parent = parent;
78 view->output = view_handle; 65 view->type = C_VIEW;
79 list_add(container->children, view); 66 list_add(parent->children, view);
80 67
81 wlc_view_focus(view_handle); 68 wlc_view_focus(view_handle);
82 69
83 arrange_windows(); 70 arrange_windows();
84} 71}
85 72
86void destroy_view(wlc_handle view) { 73void destroy_view(swayc_t *view) {
87 sway_log(L_DEBUG, "Destroying view %d", view); 74 sway_log(L_DEBUG, "Destroying container %p", view);
75 if (!view->parent) {
76 return;
77 }
78
79 int i;
80 for (i = 0; i < view->parent->children->length; ++i) {
81 if (view->parent->children->items[i] == view) {
82 list_del(view->parent->children, i);
83 break;
84 }
85 }
88 86
89 int index; 87 free_swayc(view);
90 struct sway_container *container = get_container_for_view(view, &index);
91 list_del(container->children, index);
92 88
93 wlc_view_focus(get_topmost(wlc_view_get_output(view), 0)); 89 // TODO: Focus some other window
94 90
95 arrange_windows(); 91 arrange_windows();
96} 92}
97 93
94void focus_view(swayc_t *view) {
95 if (view == &root_container) {
96 return;
97 }
98 view->parent->focused = view;
99 focus_view(view->parent);
100}
101
98void add_output(wlc_handle output) { 102void add_output(wlc_handle output) {
99 struct sway_container *container = malloc(sizeof(struct sway_container)); 103 sway_log(L_DEBUG, "Adding output %d", output);
100 // TODO: Get default layout from config 104 const struct wlc_size* size = wlc_output_get_resolution(output);
101 container->output = output; 105
106 swayc_t *container = calloc(1, sizeof(swayc_t));
107 container->handle = output;
108 container->type = C_OUTPUT;
102 container->children = create_list(); 109 container->children = create_list();
103 container->layout = LAYOUT_TILE_HORIZ; 110 container->parent = &root_container;
104 list_add(outputs, container); 111 container->layout = L_NONE;
112 container->width = size->w;
113 container->height = size->h;
114
115 list_add(root_container.children, container);
116
117 swayc_t *workspace = calloc(1, sizeof(swayc_t));
118 workspace->handle = -1;
119 workspace->type = C_WORKSPACE;
120 workspace->parent = container;
121 workspace->width = size->w; // TODO: gaps
122 workspace->height = size->h;
123 workspace->layout = L_HORIZ; // TODO: Get default layout from config
124 workspace->children = create_list();
125
126 list_add(container->children, workspace);
127
128 if (root_container.focused == NULL) {
129 focus_view(workspace);
130 }
105} 131}
106 132
107void destroy_output(wlc_handle output) { 133void destroy_output(wlc_handle output) {
108 int index; 134 sway_log(L_DEBUG, "Destroying output %d", output);
109 struct sway_container *c = get_container(output, &index); 135 int i;
110 // TODO: Move all windows in this output somewhere else? 136 for (i = 0; i < root_container.children->length; ++i) {
111 // I don't think this will ever be called unless we destroy the output ourselves 137 swayc_t *c = root_container.children->items[i];
112 if (!c) { 138 if (c->handle == output) {
113 return; 139 list_del(root_container.children, i);
140 free_swayc(c);
141 return;
142 }
114 } 143 }
115 list_del(outputs, index);
116}
117
118wlc_handle get_topmost(wlc_handle output, size_t offset) {
119 size_t memb;
120 const wlc_handle *views = wlc_output_get_views(output, &memb);
121 return (memb > 0 ? views[(memb - 1 + offset) % memb] : 0);
122} 144}
diff --git a/sway/layout.h b/sway/layout.h
index 3d14252b..94e78a93 100644
--- a/sway/layout.h
+++ b/sway/layout.h
@@ -4,29 +4,48 @@
4#include <wlc/wlc.h> 4#include <wlc/wlc.h>
5#include "list.h" 5#include "list.h"
6 6
7typedef enum {
8 LAYOUT_IS_VIEW,
9 LAYOUT_TILE_HORIZ,
10 LAYOUT_TILE_VERT,
11 LAYOUT_TABBED,
12 LAYOUT_STACKED
13} container_layout_t;
14
15struct sway_container { 7struct sway_container {
16 wlc_handle output; 8 wlc_handle handle;
9
10 enum {
11 C_ROOT,
12 C_OUTPUT,
13 C_WORKSPACE,
14 C_CONTAINER,
15 C_VIEW
16 } type;
17
18 enum {
19 L_NONE,
20 L_HORIZ,
21 L_VERT,
22 L_STACKED,
23 L_TABBED,
24 L_FLOATING
25 } layout;
26
27 // Not including borders or margins
28 int width, height;
29
30 char *name;
31
17 list_t *children; 32 list_t *children;
18 container_layout_t layout; 33
19 struct sway_container *parent; 34 struct sway_container *parent;
35 struct sway_container *focused;
20}; 36};
21 37
22extern list_t *outputs; 38typedef struct sway_container swayc_t;
23extern wlc_handle focused_view; 39
40extern swayc_t root_container;
24 41
25void init_layout(); 42void init_layout();
26void add_output(wlc_handle output); 43void add_output(wlc_handle output);
27void destroy_output(wlc_handle output); 44void destroy_output(wlc_handle output);
28wlc_handle get_topmost(wlc_handle output, size_t offset); 45void destroy_view(swayc_t *view);
29void destroy_view(wlc_handle view);
30void add_view(wlc_handle view); 46void add_view(wlc_handle view);
47void focus_view(swayc_t *view);
48
49swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
31 50
32#endif 51#endif
diff --git a/sway/list.c b/sway/list.c
index 120cfbcd..82d6c144 100644
--- a/sway/list.c
+++ b/sway/list.c
@@ -12,6 +12,9 @@ list_t *create_list() {
12} 12}
13 13
14void list_free(list_t *list) { 14void list_free(list_t *list) {
15 if (list == NULL) {
16 return;
17 }
15 free(list->items); 18 free(list->items);
16 free(list); 19 free(list);
17} 20}