1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#include <stdlib.h>
#include <stdbool.h>
#include <wlc/wlc.h>
#include "list.h"
#include "log.h"
#include "layout.h"
swayc_t root_container;
void arrange_windows() {
// TODO
}
void init_layout() {
root_container.type = C_ROOT;
root_container.layout = L_HORIZ; // TODO: Default layout
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
list_free(container->children);
free(container);
}
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
if (parent->children == NULL) {
return NULL;
}
int i;
for (i = 0; i < parent->children->length; ++i) {
swayc_t *child = parent->children->items[i];
if (child->handle == handle) {
return child;
} else {
swayc_t *res;
if ((res = get_swayc_for_handle(handle, child))) {
return res;
}
}
}
return NULL;
}
swayc_t *get_focused_container(swayc_t *parent) {
if (parent->focused == NULL) {
return parent;
}
return get_focused_container(parent->focused);
}
void add_view(wlc_handle view_handle) {
swayc_t *parent = get_focused_container(&root_container);
sway_log(L_DEBUG, "Adding new view %d under container %d", view_handle, (int)parent->type);
while (parent->type == C_VIEW) {
parent = parent->parent;
}
swayc_t *view = calloc(1, sizeof(swayc_t));
view->layout = L_NONE;
view->handle = view_handle;
view->parent = parent;
view->type = C_VIEW;
list_add(parent->children, view);
wlc_view_focus(view_handle);
arrange_windows();
}
void destroy_view(swayc_t *view) {
sway_log(L_DEBUG, "Destroying container %p", view);
if (!view->parent) {
return;
}
int i;
for (i = 0; i < view->parent->children->length; ++i) {
if (view->parent->children->items[i] == view) {
list_del(view->parent->children, i);
break;
}
}
free_swayc(view);
// TODO: Focus some other window
arrange_windows();
}
void focus_view(swayc_t *view) {
if (view == &root_container) {
return;
}
view->parent->focused = view;
focus_view(view->parent);
}
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 = calloc(1, sizeof(swayc_t));
container->handle = output;
container->type = C_OUTPUT;
container->children = create_list();
container->parent = &root_container;
container->layout = L_NONE;
container->width = size->w;
container->height = size->h;
list_add(root_container.children, container);
swayc_t *workspace = calloc(1, sizeof(swayc_t));
workspace->handle = -1;
workspace->type = C_WORKSPACE;
workspace->parent = container;
workspace->width = size->w; // TODO: gaps
workspace->height = size->h;
workspace->layout = L_HORIZ; // TODO: Get default layout from config
workspace->children = create_list();
list_add(container->children, workspace);
if (root_container.focused == NULL) {
focus_view(workspace);
}
}
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;
}
}
}
|