summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-14 16:59:38 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-14 16:59:38 -0400
commit5a8f464bc199f94a0a2ee848d249fe9d57b539c6 (patch)
tree91b25c94711e87e08b94bc8de30984bc403470ab
parentMerge pull request #26 from Luminarys/master (diff)
parentremoved debug (diff)
downloadsway-5a8f464bc199f94a0a2ee848d249fe9d57b539c6.tar.gz
sway-5a8f464bc199f94a0a2ee848d249fe9d57b539c6.tar.zst
sway-5a8f464bc199f94a0a2ee848d249fe9d57b539c6.zip
Merge pull request #27 from taiyu-len/master
rewrote and grouped swayc related functions together.
-rw-r--r--sway/commands.c35
-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.c275
-rw-r--r--sway/layout.h55
-rw-r--r--sway/movement.c8
-rw-r--r--sway/workspace.c32
-rw-r--r--sway/workspace.h2
10 files changed, 436 insertions, 326 deletions
diff --git a/sway/commands.c b/sway/commands.c
index cae35237..5f378a98 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) {
228} 228}
229 229
230static bool _do_split(struct sway_config *config, int argc, char **argv, int layout) { 230static bool _do_split(struct sway_config *config, int argc, char **argv, int layout) {
231 char *name = layout == L_VERT ? "splitv": 231 char *name = layout == L_VERT ? "splitv" :
232 layout == L_HORIZ ? "splith":"split"; 232 layout == L_HORIZ ? "splith" : "split";
233 if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)) { 233 if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)) {
234 return false; 234 return false;
235 } 235 }
236 swayc_t *focused = get_focused_container(&root_container); 236 swayc_t *focused = get_focused_container(&root_container);
237
238 /* Case that focus is on an empty workspace. change its layout */
237 if (focused->type == C_WORKSPACE) { 239 if (focused->type == C_WORKSPACE) {
238 sway_log(L_DEBUG, "Dont split workspaces"); 240 focused->layout = layout;
239 if (focused->children->length == 0) { 241 return true;
240 focused->layout = layout; 242 }
241 } 243 /* Case of no siblings. change parent layout */
244 if (focused->parent->children->length == 1) {
245 focused->parent->layout = layout;
242 return true; 246 return true;
243 } 247 }
244 swayc_t *parent = focused->parent; 248 /* regular case where new split container is build around focused container */
245 sway_log(L_DEBUG, "Splitting %p vertically with %p", parent, focused); 249 swayc_t *parent = new_container(focused, layout);
246 int index = remove_container_from_parent(parent, focused);
247 swayc_t *new_container = create_container(parent, -1);
248 new_container->layout = layout;
249 new_container->weight = focused->weight;
250 new_container->width = focused->width;
251 new_container->height = focused->height;
252 new_container->x = focused->x;
253 new_container->y = focused->y;
254 focused->weight = 1;
255 focused->parent = new_container;
256 list_insert(parent->children, index, new_container);
257 list_add(new_container->children, focused);
258 focus_view(focused); 250 focus_view(focused);
259 arrange_windows(parent, -1, -1); 251 arrange_windows(parent, -1, -1);
260 return true; 252 return true;
@@ -302,8 +294,7 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
302 swayc_t *workspace = workspace_find_by_name(argv[0]); 294 swayc_t *workspace = workspace_find_by_name(argv[0]);
303 if (!workspace) { 295 if (!workspace) {
304 workspace = workspace_create(argv[0]); 296 workspace = workspace_create(argv[0]);
305 } else sway_log(L_DEBUG, "workspace exists, all ok"); 297 }
306
307 workspace_switch(workspace); 298 workspace_switch(workspace);
308 return true; 299 return true;
309} 300}
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 @@
1#include <stdlib.h>
2#include <stdbool.h>
3#include <strings.h>
1#include "container.h" 4#include "container.h"
5#include "workspace.h"
2#include "layout.h" 6#include "layout.h"
7#include "log.h"
3 8
4void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 9
10static swayc_t *new_swayc(enum swayc_types type) {
11 swayc_t *c = calloc(1, sizeof(swayc_t));
12 c->handle = -1;
13 c->layout = L_NONE;
14 c->type = type;
15 c->weight = 1;
16 if (type != C_VIEW) {
17 c->children = create_list();
18 }
19 return c;
20}
21
22static void free_swayc(swayc_t *c) {
23 //TODO does not properly handle containers with children,
24 //TODO but functions that call this usually check for that
25 if (c->children) {
26 list_free(c->children);
27 }
28 if (c->parent) {
29 remove_child(c->parent, c);
30 }
31 free(c);
32}
33
34/* New containers */
35static void add_output_widths(swayc_t *container, void *_width) {
36 int *width = _width;
37 if (container->type == C_OUTPUT) {
38 *width += container->width;
39 }
40}
41
42swayc_t *new_output(wlc_handle handle) {
43 sway_log(L_DEBUG, "Added output %d", handle);
44 const struct wlc_size* size = wlc_output_get_resolution(handle);
45
46 swayc_t *output = new_swayc(C_OUTPUT);
47 output->width = size->w;
48 output->height = size->h;
49 output->handle = handle;
50
51 add_child(&root_container, output);
52
53 //TODO something with this
54 int total_width = 0;
55 container_map(&root_container, add_output_widths, &total_width);
56
57 //Create workspace
58 char *ws_name = workspace_next_name();
59 new_workspace(output, ws_name);
60 free(ws_name);
61
62 return output;
63}
64
65swayc_t *new_workspace(swayc_t * output, const char *name) {
66 sway_log(L_DEBUG, "Added workspace %s for output %d", name, output->handle);
67 swayc_t *workspace = new_swayc(C_WORKSPACE);
68
69 workspace->layout = L_HORIZ; // TODO:default layout
70 workspace->width = output->width;
71 workspace->height = output->height;
72 workspace->name = strdup(name);
73 workspace->visible = true;
74
75 add_child(output, workspace);
76 return workspace;
77}
78
79swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
80 swayc_t *cont = new_swayc(C_CONTAINER);
81
82 sway_log(L_DEBUG, "creating container %p around %p", cont, child);
83
84 cont->layout = layout;
85 cont->width = child->width;
86 cont->height = child->height;
87 cont->x = child->x;
88 cont->y = child->y;
89 cont->visible = child->visible;
90
91 swayc_t *parent = replace_child(child, cont);
92 if (parent) {
93 add_child(cont, child);
94 }
95 return cont;
96}
97
98swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
99 const uint32_t type = wlc_view_get_type(handle);
100 const char *title = wlc_view_get_title(handle);
101 /* Skip if unmanaged window */
102 if ((type & WLC_BIT_OVERRIDE_REDIRECT) || (type & WLC_BIT_UNMANAGED) ||
103 (type & WLC_BIT_POPUP) || (type & WLC_BIT_MODAL) || (type & WLC_BIT_SPLASH)) {
104 sway_log(L_DEBUG, "Leaving view %d:%s alone (unmanaged)", handle, title);
105 return NULL;
106 }
107
108 swayc_t *view = new_swayc(C_VIEW);
109 sway_log(L_DEBUG, "Adding new view %d:%s:%d to container %p %d",
110 handle, title, type, sibling, sibling?sibling->type:0);
111 //Setup values
112 view->handle = handle;
113 view->name = strdup(title);
114 view->visible = true;
115
116 //Case of focused workspace, just create as child of it
117 if (sibling->type == C_WORKSPACE) {
118 add_child(sibling, view);
119 }
120 //Regular case, create as sibling of current container
121 else {
122 add_sibling(sibling, view);
123 }
124 return view;
125}
126
127
128swayc_t *destroy_output(swayc_t *output) {
129 if (output->children->length == 0) {
130 //TODO move workspaces to other outputs
131 }
132 sway_log(L_DEBUG, "OUTPUT: Destroying output '%d'", output->handle);
133 free_swayc(output);
134 return &root_container;
135}
136
137swayc_t *destroy_workspace(swayc_t *workspace) {
138 //TODO move containers to other workspaces?
139 //for now just dont delete
140 if (workspace->children->length == 0) {
141 sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name);
142 swayc_t *parent = workspace->parent;
143 free_swayc(workspace);
144 return parent;
145 }
146 return NULL;
147}
148
149swayc_t *destroy_container(swayc_t *container) {
150 while (container->children->length == 0 && container->type == C_CONTAINER) {
151 sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
152 swayc_t *parent = container->parent;
153 free_swayc(container);
154
155 if (parent->focused == container) {
156 parent->focused = NULL;
157 }
158 container = parent;
159 }
160 return container;
161}
162
163swayc_t *destroy_view(swayc_t *view) {
164 if (view == NULL) {
165 sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
166 return NULL;
167 }
168 sway_log(L_DEBUG, "Destroying view '%p'", view);
169 swayc_t *parent = view->parent;
170 free_swayc(view);
171
172 if (parent->focused == view) {
173 parent->focused = NULL;
174 }
175 //Destroy empty containers
176 if (parent->type == C_CONTAINER) {
177 return destroy_container(parent);
178 }
179 return parent;
180}
181
182
183swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
5 if (!container->children) { 184 if (!container->children) {
185 return NULL;
186 }
187 int i;
188 for (i = 0; i < container->children->length; ++i) {
189 swayc_t *child = container->children->items[i];
190 if (test(child, data)) {
191 return child;
192 } else {
193 swayc_t *_ = find_container(child, test, data);
194 if (_) {
195 return _;
196 }
197 }
198 }
199 return NULL;
200}
201
202void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
203 if (!container->children || !container->children->length) {
6 return; 204 return;
7 } 205 }
8 int i; 206 int i;
9 for (i = 0; i < container->children->length; ++i) { 207 for (i = 0; i < container->children->length; ++i) {
10 swayc_t *child = container->children->items[i]; 208 swayc_t *child = container->children->items[i];
11 f(child, data); 209 f(child, data);
12 210 container_map(child, f, data);
13 if (child->children) {
14 container_map(child, f, data);
15 }
16 } 211 }
17} 212}
18 213
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 @@
1#ifndef _SWAY_CONTAINER_H 1#ifndef _SWAY_CONTAINER_H
2#define _SWAY_CONTAINER_H 2#define _SWAY_CONTAINER_H
3#include <wlc/wlc.h>
4typedef struct sway_container swayc_t;
3 5
4#include "layout.h" 6#include "layout.h"
5 7
8enum swayc_types{
9 C_ROOT,
10 C_OUTPUT,
11 C_WORKSPACE,
12 C_CONTAINER,
13 C_VIEW,
14 //Keep last
15 C_TYPES,
16};
17
18enum swayc_layouts{
19 L_NONE,
20 L_HORIZ,
21 L_VERT,
22 L_STACKED,
23 L_TABBED,
24 L_FLOATING,
25 //Keep last
26 L_LAYOUTS,
27};
28
29struct sway_container {
30 wlc_handle handle;
31
32 enum swayc_types type;
33
34 enum swayc_layouts layout;
35
36 // Not including borders or margins
37 int width, height;
38
39 int x, y;
40
41 bool visible;
42
43 int weight;
44
45 char *name;
46
47 list_t *children;
48
49 struct sway_container *parent;
50 struct sway_container *focused;
51};
52
53
54swayc_t *new_output(wlc_handle handle);
55swayc_t *new_workspace(swayc_t * output, const char *name);
56//Creates container Around child (parent child) -> (parent (container child))
57swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
58//Creates view as a sibling of current focused container, or as child of a workspace
59swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
60
61
62swayc_t *destroy_output(swayc_t *output);
63//destroys workspace if empty and returns parent pointer, else returns NULL
64swayc_t *destroy_workspace(swayc_t *workspace);
65swayc_t *destroy_container(swayc_t *container);
66swayc_t *destroy_view(swayc_t *view);
67
68swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
6void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *); 69void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
7 70
8#endif 71#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 @@
9#include "commands.h" 9#include "commands.h"
10#include "handlers.h" 10#include "handlers.h"
11#include "stringop.h" 11#include "stringop.h"
12#include "workspace.h"
13
14static struct wlc_origin mouse_origin;
15
16static bool pointer_test(swayc_t *view, void *_origin) {
17 const struct wlc_origin *origin = _origin;
18 if (view->type == C_VIEW && origin->x >= view->x && origin->y >= view->y
19 && origin->x < view->x + view->width && origin->y < view->y + view->height
20 && view->visible) {
21 return true;
22 }
23 return false;
24}
25
26void focus_pointer(void) {
27 swayc_t *focused = find_container(&root_container, pointer_test, &mouse_origin);
28 if (focused) {
29 sway_log(L_DEBUG, "Switching focus to %p", focused);
30 unfocus_all(&root_container);
31 focus_view(focused);
32 } else {
33 focus_view(active_workspace);
34 }
35}
12 36
13static bool handle_output_created(wlc_handle output) { 37static bool handle_output_created(wlc_handle output) {
14 add_output(output); 38 swayc_t *op = new_output(output);
39
40 //Switch to workspace if we need to
41 if (active_workspace == NULL) {
42 swayc_t *ws = op->children->items[0];
43 workspace_switch(ws);
44 }
15 return true; 45 return true;
16} 46}
17 47
18static void handle_output_destroyed(wlc_handle output) { 48static void handle_output_destroyed(wlc_handle output) {
19 destroy_output(output); 49 int i;
50 list_t *list = root_container.children;
51 for (i = 0; i < list->length; ++i) {
52 if (((swayc_t *)list->items[i])->handle == output) {
53 break;
54 }
55 }
56 if (i < list->length) {
57 destroy_output(list->items[i]);
58 }
20} 59}
21 60
22static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { 61static 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) {
37 } 76 }
38} 77}
39 78
40static bool handle_view_created(wlc_handle view) { 79static bool handle_view_created(wlc_handle handle) {
41 add_view(view); 80 swayc_t *container = get_focused_container(&root_container);
81 swayc_t *view = new_view(container, handle);
82 unfocus_all(&root_container);
83 if (view) {
84 focus_view(view);
85 arrange_windows(view->parent, -1, -1);
86 } else { //Unmanaged view
87 wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
88 wlc_view_focus(handle);
89 }
42 return true; 90 return true;
43} 91}
44 92
45static void handle_view_destroyed(wlc_handle view) { 93static void handle_view_destroyed(wlc_handle handle) {
46 sway_log(L_DEBUG, "Destroying window %d", view); 94 sway_log(L_DEBUG, "Destroying window %d", handle);
47 destroy_view(get_swayc_for_handle(view, &root_container)); 95 swayc_t *view = get_swayc_for_handle(handle, &root_container);
96 swayc_t *parent;
97 swayc_t *focused = get_focused_container(&root_container);
98
99 if (view) {
100 parent = destroy_view(view);
101 arrange_windows(parent, -1, -1);
102 }
103 if (!focused || focused == view) {
104 focus_pointer();
105 }
48} 106}
49 107
50static void handle_view_focus(wlc_handle view, bool focus) { 108static 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
121 return cmd_success; 179 return cmd_success;
122} 180}
123 181
124bool pointer_test(swayc_t *view, void *_origin) {
125 const struct wlc_origin *origin = _origin;
126 if (view->type == C_VIEW && origin->x >= view->x && origin->y >= view->y
127 && origin->x < view->x + view->width && origin->y < view->y + view->height
128 && view->visible) {
129 return true;
130 }
131 return false;
132}
133
134struct wlc_origin mouse_origin;
135
136static bool handle_pointer_motion(wlc_handle view, uint32_t time, const struct wlc_origin *origin) { 182static bool handle_pointer_motion(wlc_handle view, uint32_t time, const struct wlc_origin *origin) {
137 mouse_origin = *origin; 183 mouse_origin = *origin;
138 if (!config->focus_follows_mouse) { 184 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 @@
6 6
7extern struct wlc_interface interface; 7extern struct wlc_interface interface;
8 8
9//set focus to current pointer location
10void focus_pointer(void);
11
9#endif 12#endif
diff --git a/sway/layout.c b/sway/layout.c
index ccf29f34..8b9315b4 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -9,25 +9,75 @@
9 9
10swayc_t root_container; 10swayc_t root_container;
11 11
12swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { 12void init_layout(void) {
13 if (!container->children) { 13 root_container.type = C_ROOT;
14 root_container.layout = L_NONE;
15 root_container.children = create_list();
16 root_container.handle = -1;
17}
18
19static int index_child(swayc_t *parent, swayc_t *child) {
20 int i;
21 for (i = 0; i < parent->children->length; ++i) {
22 if (parent->children->items[i] == child) {
23 break;
24 }
25 }
26 return i;
27}
28
29void add_child(swayc_t *parent, swayc_t *child) {
30 sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
31 child->width, child->height, parent, parent->type, parent->width, parent->height);
32 list_add(parent->children, child);
33 child->parent = parent;
34 if (parent->focused == NULL) {
35 parent->focused = child;
36 }
37}
38
39swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) {
40 swayc_t *parent = sibling->parent;
41 int i = index_child(parent, sibling);
42 if (i == parent->children->length) {
43 --i;
44 }
45 list_insert(parent->children, i+1, child);
46 child->parent = parent;
47 return child->parent;
48}
49
50swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
51 swayc_t *parent = child->parent;
52 if (parent == NULL) {
14 return NULL; 53 return NULL;
15 } 54 }
55 int i = index_child(parent, child);
56 parent->children->items[i] = new_child;
57 new_child->parent = child->parent;
58
59 if (child->parent->focused == child) {
60 child->parent->focused = new_child;
61 }
62 child->parent = NULL;
63 return parent;
64}
65
66swayc_t *remove_child(swayc_t *parent, swayc_t *child) {
16 int i; 67 int i;
17 for (i = 0; i < container->children->length; ++i) { 68 for (i = 0; i < parent->children->length; ++i) {
18 swayc_t *child = container->children->items[i]; 69 if (parent->children->items[i] == child) {
19 if (test(child, data)) { 70 list_del(parent->children, i);
20 return child; 71 break;
21 } else {
22 swayc_t *_ = find_container(child, test, data);
23 if (_) {
24 return _;
25 }
26 } 72 }
27 } 73 }
28 return NULL; 74 if (parent->focused == child) {
75 parent->focused = NULL;
76 }
77 return parent;
29} 78}
30 79
80
31void arrange_windows(swayc_t *container, int width, int height) { 81void arrange_windows(swayc_t *container, int width, int height) {
32 int i; 82 int i;
33 if (width == -1 || height == -1) { 83 if (width == -1 || height == -1) {
@@ -68,7 +118,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
68 }; 118 };
69 if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) { 119 if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
70 swayc_t *parent = container; 120 swayc_t *parent = container;
71 while(parent->type != C_OUTPUT) { 121 while (parent->type != C_OUTPUT) {
72 parent = parent->parent; 122 parent = parent->parent;
73 } 123 }
74 geometry.origin.x = 0; 124 geometry.origin.x = 0;
@@ -131,25 +181,6 @@ void arrange_windows(swayc_t *container, int width, int height) {
131 } 181 }
132} 182}
133 183
134void init_layout(void) {
135 root_container.type = C_ROOT;
136 root_container.layout = L_NONE;
137 root_container.children = create_list();
138 root_container.handle = -1;
139}
140
141void free_swayc(swayc_t *container) {
142 // NOTE: Does not handle moving children into a different container
143 if (container->parent) {
144 remove_container_from_parent(container->parent, container);
145 }
146 list_free(container->children);
147 if (container->name) {
148 free(container->name);
149 }
150 free(container);
151}
152
153swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) { 184swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
154 if (parent->children == NULL) { 185 if (parent->children == NULL) {
155 return NULL; 186 return NULL;
@@ -176,99 +207,6 @@ swayc_t *get_focused_container(swayc_t *parent) {
176 return get_focused_container(parent->focused); 207 return get_focused_container(parent->focused);
177} 208}
178 209
179void add_view(wlc_handle view_handle) {
180 const uint32_t type = wlc_view_get_type(view_handle);
181 const char *title = wlc_view_get_title(view_handle);
182 if ((type & WLC_BIT_OVERRIDE_REDIRECT) || (type & WLC_BIT_UNMANAGED) || (type &
183 WLC_BIT_POPUP) || (type & WLC_BIT_MODAL) || (type & WLC_BIT_SPLASH)) {
184 sway_log(L_DEBUG, "Leaving view %d:%s alone (unmanaged)", view_handle, title);
185 unfocus_all(&root_container);
186 wlc_view_set_state(view_handle, WLC_BIT_ACTIVATED, true);
187 wlc_view_focus(view_handle);
188 return;
189 }
190
191 swayc_t *parent = get_focused_container(&root_container);
192 sway_log(L_DEBUG, "Adding new view %d:%s:%d under container %p %d", view_handle, title, type, parent, parent->type);
193
194 while (parent->type == C_VIEW) {
195 parent = parent->parent;
196 }
197
198 swayc_t *view = calloc(1, sizeof(swayc_t));
199 view->weight = 1;
200 view->layout = L_NONE;
201 view->handle = view_handle;
202 view->parent = parent;
203 view->type = C_VIEW;
204 view->visible = true;
205 if (title) {
206 view->name = malloc(strlen(title) + 1);
207 strcpy(view->name, title);
208 }
209 add_child(parent, view);
210
211 unfocus_all(&root_container);
212 focus_view(view);
213
214 arrange_windows(parent, -1, -1);
215}
216
217int remove_container_from_parent(swayc_t *parent, swayc_t *container) {
218 int i;
219 for (i = 0; i < parent->children->length; ++i) {
220 if (parent->children->items[i] == container) {
221 list_del(parent->children, i);
222 break;
223 }
224 }
225
226 if (parent->focused == container) {
227 parent->focused = NULL;
228 }
229
230 return i;
231}
232
233void destroy_view(swayc_t *view) {
234 if (view == NULL) {
235 sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
236 return;
237 }
238 sway_log(L_DEBUG, "Destroying container %p", view);
239 swayc_t *parent = view->parent;
240 if (!parent) {
241 return;
242 }
243
244 int i;
245 for (i = 0; i < parent->children->length; ++i) {
246 if (parent->children->items[i] == view) {
247 list_del(parent->children, i);
248 break;
249 }
250 }
251
252 free_swayc(view);
253
254 if (parent->focused == view) {
255 parent->focused = NULL;
256 }
257
258 unfocus_all(&root_container);
259 if (parent->children->length != 0) {
260 focus_view(parent->children->items[0]);
261 } else {
262 focus_view(parent);
263 }
264
265 arrange_windows(parent, -1, -1);
266
267 if (parent->children->length == 0 && parent->type == C_CONTAINER) {
268 destroy_view(parent);
269 }
270}
271
272void unfocus_all(swayc_t *container) { 210void unfocus_all(swayc_t *container) {
273 if (container->children == NULL) { 211 if (container->children == NULL) {
274 return; 212 return;
@@ -285,85 +223,16 @@ void unfocus_all(swayc_t *container) {
285} 223}
286 224
287void focus_view(swayc_t *view) { 225void focus_view(swayc_t *view) {
288 sway_log(L_DEBUG, "Setting focus for %p", view); 226 sway_log(L_DEBUG, "Setting focus to %p", view);
289 if (view == &root_container) { 227 if (view->type == C_VIEW) {
290 // Propegate wayland focus down 228 wlc_view_set_state(view->handle, WLC_BIT_ACTIVATED, true);
291 swayc_t *child = view->focused; 229 wlc_view_bring_to_front(view->handle);
292 while (child && child->type != C_VIEW) { 230 wlc_view_focus(view->handle);
293 child = child->focused;
294 }
295 if (child) {
296 wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, true);
297 wlc_view_focus(child->handle);
298 }
299 return;
300 }
301 view->parent->focused = view;
302 focus_view(view->parent);
303}
304
305void add_child(swayc_t *parent, swayc_t *child) {
306 sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
307 child->width, child->height, parent, parent->type, parent->width, parent->height);
308 list_add(parent->children, child);
309}
310
311swayc_t *create_container(swayc_t *parent, wlc_handle handle) {
312 swayc_t *c = calloc(1, sizeof(swayc_t));
313 c->weight = 1;
314 c->handle = handle;
315 c->parent = parent;
316 c->layout = L_NONE;
317 c->type = C_CONTAINER;
318 c->children = create_list();
319 return c;
320}
321
322void add_output_widths(swayc_t *container, void *_width) {
323 int *width = _width;
324 if (container->type == C_OUTPUT) {
325 *width += container->width;
326 } 231 }
327} 232 // Propagete focus up
328 233 while (view != &root_container) {
329void add_output(wlc_handle output) { 234 view->parent->focused = view;
330 sway_log(L_DEBUG, "Adding output %d", output); 235 view = view->parent;
331 const struct wlc_size* size = wlc_output_get_resolution(output);
332
333 swayc_t *container = create_container(&root_container, output);
334 container->type = C_OUTPUT;
335 container->width = size->w;
336 container->height = size->h;
337 add_child(&root_container, container);
338
339 int total_width = 0;
340 container_map(&root_container, add_output_widths, &total_width);
341
342 swayc_t *workspace = create_container(container, -1);
343 workspace->type = C_WORKSPACE;
344 workspace->name = workspace_next_name();
345 workspace->width = size->w; // TODO: gaps
346 workspace->height = size->h;
347 workspace->layout = L_HORIZ; // TODO: Get default layout from config
348 add_child(container, workspace);
349 sway_log(L_DEBUG, "Added workspace %s for output %d", workspace->name, output);
350
351 if (root_container.focused == NULL) {
352 workspace_switch(workspace);
353 unfocus_all(&root_container);
354 focus_view(workspace);
355 } 236 }
356} 237}
357 238
358void destroy_output(wlc_handle output) {
359 sway_log(L_DEBUG, "Destroying output %d", output);
360 int i;
361 for (i = 0; i < root_container.children->length; ++i) {
362 swayc_t *c = root_container.children->items[i];
363 if (c->handle == output) {
364 list_del(root_container.children, i);
365 free_swayc(c);
366 return;
367 }
368 }
369}
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 @@
3 3
4#include <wlc/wlc.h> 4#include <wlc/wlc.h>
5#include "list.h" 5#include "list.h"
6 6#include "container.h"
7struct sway_container {
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 int x, y;
31
32 bool visible;
33
34 int weight;
35
36 char *name;
37
38 list_t *children;
39
40 struct sway_container *parent;
41 struct sway_container *focused;
42};
43
44typedef struct sway_container swayc_t;
45 7
46extern swayc_t root_container; 8extern swayc_t root_container;
47 9
48void init_layout(void); 10void init_layout(void);
11
49void add_child(swayc_t *parent, swayc_t *child); 12void add_child(swayc_t *parent, swayc_t *child);
50void add_output(wlc_handle output); 13//Returns parent container wihch needs to be rearranged.
51void destroy_output(wlc_handle output); 14swayc_t *add_sibling(swayc_t *sibling, swayc_t *child);
52void destroy_view(swayc_t *view); 15swayc_t *replace_child(swayc_t *child, swayc_t *new_child);
53void add_view(wlc_handle view); 16swayc_t *remove_child(swayc_t *parent, swayc_t *child);
17
54void unfocus_all(swayc_t *container); 18void unfocus_all(swayc_t *container);
55void focus_view(swayc_t *view); 19void focus_view(swayc_t *view);
56void arrange_windows(swayc_t *container, int width, int height); 20void arrange_windows(swayc_t *container, int width, int height);
57swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
58swayc_t *get_focused_container(swayc_t *parent); 21swayc_t *get_focused_container(swayc_t *parent);
59int remove_container_from_parent(swayc_t *parent, swayc_t *container); 22
60swayc_t *create_container(swayc_t *parent, wlc_handle handle);
61void free_swayc(swayc_t *container);
62swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); 23swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
63 24
64#endif 25#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) {
10 swayc_t *parent = current->parent; 10 swayc_t *parent = current->parent;
11 11
12 if (direction == MOVE_PARENT) { 12 if (direction == MOVE_PARENT) {
13 current = parent; 13 if (parent->type == C_OUTPUT) {
14 parent = parent->parent;
15 if (parent->type == C_ROOT) {
16 sway_log(L_DEBUG, "Focus cannot move to parent"); 14 sway_log(L_DEBUG, "Focus cannot move to parent");
17 return false; 15 return false;
18 } else { 16 } else {
19 sway_log(L_DEBUG, "Moving focus away from %p", current); 17 sway_log(L_DEBUG, "Moving focus away from %p to %p", current, parent);
20 unfocus_all(parent); 18 unfocus_all(parent->parent);
21 focus_view(parent); 19 focus_view(parent);
22 return true; 20 return true;
23 } 21 }
diff --git a/sway/workspace.c b/sway/workspace.c
index 906d0c5d..cd5472e3 100644
--- a/sway/workspace.c
+++ b/sway/workspace.c
@@ -6,6 +6,7 @@
6#include "list.h" 6#include "list.h"
7#include "log.h" 7#include "log.h"
8#include "container.h" 8#include "container.h"
9#include "handlers.h"
9#include "config.h" 10#include "config.h"
10#include "stringop.h" 11#include "stringop.h"
11 12
@@ -68,19 +69,10 @@ char *workspace_next_name(void) {
68 69
69swayc_t *workspace_create(const char* name) { 70swayc_t *workspace_create(const char* name) {
70 swayc_t *parent = get_focused_container(&root_container); 71 swayc_t *parent = get_focused_container(&root_container);
71 while(parent->type != C_OUTPUT) { 72 while (parent->type != C_OUTPUT) {
72 parent = parent->parent; 73 parent = parent->parent;
73 } 74 }
74 75 return new_workspace(parent, name);
75 swayc_t *workspace = create_container(parent, -1);
76 workspace->type = C_WORKSPACE;
77 workspace->name = strdup(name);
78 workspace->width = parent->width;
79 workspace->height = parent->height;
80 workspace->layout = L_HORIZ; // todo: thing
81
82 add_child(parent, workspace);
83 return workspace;
84} 76}
85 77
86bool workspace_by_name(swayc_t *view, void *data) { 78bool workspace_by_name(swayc_t *view, void *data) {
@@ -88,23 +80,13 @@ bool workspace_by_name(swayc_t *view, void *data) {
88 (strcasecmp(view->name, (char *) data) == 0); 80 (strcasecmp(view->name, (char *) data) == 0);
89} 81}
90 82
91bool workspace_destroy(swayc_t *workspace) {
92 //Dont destroy if there are children
93 if (workspace->children->length) {
94 return false;
95 }
96 sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name);
97 free_swayc(workspace);
98 return true;
99}
100
101void set_mask(swayc_t *view, void *data) { 83void set_mask(swayc_t *view, void *data) {
102 uint32_t *p = data; 84 uint32_t *p = data;
103 85
104 if(view->type == C_VIEW) { 86 if (view->type == C_VIEW) {
105 wlc_view_set_mask(view->handle, *p); 87 wlc_view_set_mask(view->handle, *p);
106 view->visible = (*p == 2);
107 } 88 }
89 view->visible = (*p == 2);
108} 90}
109 91
110swayc_t *workspace_find_by_name(const char* name) { 92swayc_t *workspace_find_by_name(const char* name) {
@@ -123,9 +105,9 @@ void workspace_switch(swayc_t *workspace) {
123 container_map(workspace, set_mask, &mask); 105 container_map(workspace, set_mask, &mask);
124 106
125 wlc_output_set_mask(wlc_get_focused_output(), 2); 107 wlc_output_set_mask(wlc_get_focused_output(), 2);
126 unfocus_all(active_workspace); 108 unfocus_all(&root_container);
127 focus_view(workspace); 109 focus_view(workspace);
128 workspace_destroy(active_workspace); 110 destroy_workspace(active_workspace);
129 } 111 }
130 active_workspace = workspace; 112 active_workspace = workspace;
131} 113}
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 @@
5#include "list.h" 5#include "list.h"
6#include "layout.h" 6#include "layout.h"
7 7
8extern swayc_t *active_workspace;
9
8char *workspace_next_name(void); 10char *workspace_next_name(void);
9swayc_t *workspace_create(const char*); 11swayc_t *workspace_create(const char*);
10swayc_t *workspace_find_by_name(const char*); 12swayc_t *workspace_find_by_name(const char*);