diff options
author | 2015-08-08 17:44:51 -0400 | |
---|---|---|
committer | 2015-08-08 17:44:51 -0400 | |
commit | 148f59f3a670a7008bc6c2bc07712fd58b1f6e69 (patch) | |
tree | 7feeaaac853eb847a49e583882de5be50b1c737b | |
parent | Add logging and new windows into layout tree (diff) | |
download | sway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.tar.gz sway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.tar.zst sway-148f59f3a670a7008bc6c2bc07712fd58b1f6e69.zip |
Refactor in-memory tree
-rw-r--r-- | sway/handlers.c | 5 | ||||
-rw-r--r-- | sway/layout.c | 168 | ||||
-rw-r--r-- | sway/layout.h | 47 | ||||
-rw-r--r-- | sway/list.c | 3 |
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 | ||
24 | void handle_view_destroyed(wlc_handle view) { | 24 | void 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 | ||
29 | void handle_view_focus(wlc_handle view, bool focus) { | 29 | void 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 | ||
8 | list_t *outputs; | 8 | swayc_t root_container; |
9 | wlc_handle focused_view; | ||
10 | 9 | ||
11 | void arrange_windows() { | 10 | void arrange_windows() { |
11 | // TODO | ||
12 | } | 12 | } |
13 | 13 | ||
14 | void init_layout() { | 14 | void 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 | ||
19 | struct sway_container *get_container(wlc_handle output, int *index) { | 21 | void 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 | ||
30 | struct sway_container *get_container_for_view_recurse(wlc_handle handle, int *index, struct sway_container *parent) { | 27 | swayc_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 | ||
49 | struct sway_container *get_container_for_view(wlc_handle handle, int *index) { | 46 | swayc_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 | ||
61 | void add_view(wlc_handle view_handle) { | 53 | void 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 | ||
86 | void destroy_view(wlc_handle view) { | 73 | void 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 | ||
94 | void 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 | |||
98 | void add_output(wlc_handle output) { | 102 | void 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 | ||
107 | void destroy_output(wlc_handle output) { | 133 | void 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 | |||
118 | wlc_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 | ||
7 | typedef enum { | ||
8 | LAYOUT_IS_VIEW, | ||
9 | LAYOUT_TILE_HORIZ, | ||
10 | LAYOUT_TILE_VERT, | ||
11 | LAYOUT_TABBED, | ||
12 | LAYOUT_STACKED | ||
13 | } container_layout_t; | ||
14 | |||
15 | struct sway_container { | 7 | struct 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 | ||
22 | extern list_t *outputs; | 38 | typedef struct sway_container swayc_t; |
23 | extern wlc_handle focused_view; | 39 | |
40 | extern swayc_t root_container; | ||
24 | 41 | ||
25 | void init_layout(); | 42 | void init_layout(); |
26 | void add_output(wlc_handle output); | 43 | void add_output(wlc_handle output); |
27 | void destroy_output(wlc_handle output); | 44 | void destroy_output(wlc_handle output); |
28 | wlc_handle get_topmost(wlc_handle output, size_t offset); | 45 | void destroy_view(swayc_t *view); |
29 | void destroy_view(wlc_handle view); | ||
30 | void add_view(wlc_handle view); | 46 | void add_view(wlc_handle view); |
47 | void focus_view(swayc_t *view); | ||
48 | |||
49 | swayc_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 | ||
14 | void list_free(list_t *list) { | 14 | void 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 | } |