diff options
Diffstat (limited to 'sway/tree/root.c')
-rw-r--r-- | sway/tree/root.c | 186 |
1 files changed, 89 insertions, 97 deletions
diff --git a/sway/tree/root.c b/sway/tree/root.c index b42371de..ecc04ddb 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c | |||
@@ -14,54 +14,45 @@ | |||
14 | #include "log.h" | 14 | #include "log.h" |
15 | #include "util.h" | 15 | #include "util.h" |
16 | 16 | ||
17 | struct sway_container root_container; | 17 | struct sway_root *root; |
18 | 18 | ||
19 | static void output_layout_handle_change(struct wl_listener *listener, | 19 | static void output_layout_handle_change(struct wl_listener *listener, |
20 | void *data) { | 20 | void *data) { |
21 | arrange_windows(&root_container); | 21 | arrange_root(); |
22 | transaction_commit_dirty(); | 22 | transaction_commit_dirty(); |
23 | } | 23 | } |
24 | 24 | ||
25 | void root_create(void) { | 25 | struct sway_root *root_create(void) { |
26 | root_container.id = 0; // normally assigned in new_swayc() | 26 | struct sway_root *root = calloc(1, sizeof(struct sway_root)); |
27 | root_container.type = C_ROOT; | 27 | if (!root) { |
28 | root_container.layout = L_NONE; | 28 | wlr_log(WLR_ERROR, "Unable to allocate sway_root"); |
29 | root_container.name = strdup("root"); | 29 | return NULL; |
30 | root_container.children = create_list(); | 30 | } |
31 | root_container.current.children = create_list(); | 31 | node_init(&root->node, N_ROOT, root); |
32 | wl_signal_init(&root_container.events.destroy); | 32 | root->output_layout = wlr_output_layout_create(); |
33 | 33 | wl_list_init(&root->all_outputs); | |
34 | root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); | ||
35 | root_container.sway_root->output_layout = wlr_output_layout_create(); | ||
36 | wl_list_init(&root_container.sway_root->all_outputs); | ||
37 | #ifdef HAVE_XWAYLAND | 34 | #ifdef HAVE_XWAYLAND |
38 | wl_list_init(&root_container.sway_root->xwayland_unmanaged); | 35 | wl_list_init(&root->xwayland_unmanaged); |
39 | #endif | 36 | #endif |
40 | wl_list_init(&root_container.sway_root->drag_icons); | 37 | wl_list_init(&root->drag_icons); |
41 | wl_signal_init(&root_container.sway_root->events.new_container); | 38 | wl_signal_init(&root->events.new_node); |
42 | root_container.sway_root->scratchpad = create_list(); | 39 | root->outputs = create_list(); |
43 | root_container.sway_root->saved_workspaces = create_list(); | 40 | root->scratchpad = create_list(); |
44 | 41 | root->saved_workspaces = create_list(); | |
45 | root_container.sway_root->output_layout_change.notify = | 42 | |
46 | output_layout_handle_change; | 43 | root->output_layout_change.notify = output_layout_handle_change; |
47 | wl_signal_add(&root_container.sway_root->output_layout->events.change, | 44 | wl_signal_add(&root->output_layout->events.change, |
48 | &root_container.sway_root->output_layout_change); | 45 | &root->output_layout_change); |
46 | return root; | ||
49 | } | 47 | } |
50 | 48 | ||
51 | void root_destroy(void) { | 49 | void root_destroy(struct sway_root *root) { |
52 | // sway_root | 50 | wl_list_remove(&root->output_layout_change.link); |
53 | wl_list_remove(&root_container.sway_root->output_layout_change.link); | 51 | list_free(root->scratchpad); |
54 | list_free(root_container.sway_root->scratchpad); | 52 | list_free(root->saved_workspaces); |
55 | list_free(root_container.sway_root->saved_workspaces); | 53 | list_free(root->outputs); |
56 | wlr_output_layout_destroy(root_container.sway_root->output_layout); | 54 | wlr_output_layout_destroy(root->output_layout); |
57 | free(root_container.sway_root); | 55 | free(root); |
58 | |||
59 | // root_container | ||
60 | list_free(root_container.children); | ||
61 | list_free(root_container.current.children); | ||
62 | free(root_container.name); | ||
63 | |||
64 | memset(&root_container, 0, sizeof(root_container)); | ||
65 | } | 56 | } |
66 | 57 | ||
67 | void root_scratchpad_add_container(struct sway_container *con) { | 58 | void root_scratchpad_add_container(struct sway_container *con) { |
@@ -69,15 +60,21 @@ void root_scratchpad_add_container(struct sway_container *con) { | |||
69 | return; | 60 | return; |
70 | } | 61 | } |
71 | con->scratchpad = true; | 62 | con->scratchpad = true; |
72 | list_add(root_container.sway_root->scratchpad, con); | 63 | list_add(root->scratchpad, con); |
73 | 64 | ||
74 | struct sway_container *parent = con->parent; | 65 | struct sway_container *parent = con->parent; |
66 | struct sway_workspace *workspace = con->workspace; | ||
75 | container_set_floating(con, true); | 67 | container_set_floating(con, true); |
76 | container_remove_child(con); | 68 | container_detach(con); |
77 | arrange_windows(parent); | ||
78 | 69 | ||
79 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 70 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
80 | seat_set_focus(seat, seat_get_focus_inactive(seat, parent)); | 71 | if (parent) { |
72 | arrange_container(parent); | ||
73 | seat_set_focus(seat, seat_get_focus_inactive(seat, &parent->node)); | ||
74 | } else { | ||
75 | arrange_workspace(workspace); | ||
76 | seat_set_focus(seat, seat_get_focus_inactive(seat, &workspace->node)); | ||
77 | } | ||
81 | } | 78 | } |
82 | 79 | ||
83 | void root_scratchpad_remove_container(struct sway_container *con) { | 80 | void root_scratchpad_remove_container(struct sway_container *con) { |
@@ -85,28 +82,25 @@ void root_scratchpad_remove_container(struct sway_container *con) { | |||
85 | return; | 82 | return; |
86 | } | 83 | } |
87 | con->scratchpad = false; | 84 | con->scratchpad = false; |
88 | int index = list_find(root_container.sway_root->scratchpad, con); | 85 | int index = list_find(root->scratchpad, con); |
89 | if (index != -1) { | 86 | if (index != -1) { |
90 | list_del(root_container.sway_root->scratchpad, index); | 87 | list_del(root->scratchpad, index); |
91 | } | 88 | } |
92 | } | 89 | } |
93 | 90 | ||
94 | void root_scratchpad_show(struct sway_container *con) { | 91 | void root_scratchpad_show(struct sway_container *con) { |
95 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 92 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
96 | struct sway_container *ws = seat_get_focus(seat); | 93 | struct sway_workspace *ws = seat_get_focused_workspace(seat); |
97 | if (ws->type != C_WORKSPACE) { | ||
98 | ws = container_parent(ws, C_WORKSPACE); | ||
99 | } | ||
100 | 94 | ||
101 | // If the current con or any of its parents are in fullscreen mode, we | 95 | // If the current con or any of its parents are in fullscreen mode, we |
102 | // first need to disable it before showing the scratchpad con. | 96 | // first need to disable it before showing the scratchpad con. |
103 | if (ws->sway_workspace->fullscreen) { | 97 | if (ws->fullscreen) { |
104 | container_set_fullscreen(ws->sway_workspace->fullscreen, false); | 98 | container_set_fullscreen(ws->fullscreen, false); |
105 | } | 99 | } |
106 | 100 | ||
107 | // Show the container | 101 | // Show the container |
108 | if (con->parent) { | 102 | if (con->workspace) { |
109 | container_remove_child(con); | 103 | container_detach(con); |
110 | } | 104 | } |
111 | workspace_add_floating(ws, con); | 105 | workspace_add_floating(ws, con); |
112 | 106 | ||
@@ -115,7 +109,7 @@ void root_scratchpad_show(struct sway_container *con) { | |||
115 | double center_ly = con->y + con->height / 2; | 109 | double center_ly = con->y + con->height / 2; |
116 | 110 | ||
117 | struct wlr_box workspace_box; | 111 | struct wlr_box workspace_box; |
118 | container_get_box(ws, &workspace_box); | 112 | workspace_get_box(ws, &workspace_box); |
119 | if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { | 113 | if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { |
120 | // Maybe resize it | 114 | // Maybe resize it |
121 | if (con->width > ws->width || con->height > ws->height) { | 115 | if (con->width > ws->width || con->height > ws->height) { |
@@ -128,23 +122,21 @@ void root_scratchpad_show(struct sway_container *con) { | |||
128 | container_floating_move_to(con, new_lx, new_ly); | 122 | container_floating_move_to(con, new_lx, new_ly); |
129 | } | 123 | } |
130 | 124 | ||
131 | arrange_windows(ws); | 125 | arrange_workspace(ws); |
132 | seat_set_focus(seat, seat_get_focus_inactive(seat, con)); | 126 | seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node)); |
133 | |||
134 | container_set_dirty(con->parent); | ||
135 | } | 127 | } |
136 | 128 | ||
137 | void root_scratchpad_hide(struct sway_container *con) { | 129 | void root_scratchpad_hide(struct sway_container *con) { |
138 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 130 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
139 | struct sway_container *focus = seat_get_focus(seat); | 131 | struct sway_node *focus = seat_get_focus(seat); |
140 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | 132 | struct sway_workspace *ws = con->workspace; |
141 | 133 | ||
142 | container_remove_child(con); | 134 | container_detach(con); |
143 | arrange_windows(ws); | 135 | arrange_workspace(ws); |
144 | if (con == focus) { | 136 | if (&con->node == focus) { |
145 | seat_set_focus(seat, seat_get_focus_inactive(seat, ws)); | 137 | seat_set_focus(seat, seat_get_focus_inactive(seat, &ws->node)); |
146 | } | 138 | } |
147 | list_move_to_end(root_container.sway_root->scratchpad, con); | 139 | list_move_to_end(root->scratchpad, con); |
148 | } | 140 | } |
149 | 141 | ||
150 | struct pid_workspace { | 142 | struct pid_workspace { |
@@ -152,7 +144,7 @@ struct pid_workspace { | |||
152 | char *workspace; | 144 | char *workspace; |
153 | struct timespec time_added; | 145 | struct timespec time_added; |
154 | 146 | ||
155 | struct sway_container *output; | 147 | struct sway_output *output; |
156 | struct wl_listener output_destroy; | 148 | struct wl_listener output_destroy; |
157 | 149 | ||
158 | struct wl_list link; | 150 | struct wl_list link; |
@@ -160,13 +152,13 @@ struct pid_workspace { | |||
160 | 152 | ||
161 | static struct wl_list pid_workspaces; | 153 | static struct wl_list pid_workspaces; |
162 | 154 | ||
163 | struct sway_container *root_workspace_for_pid(pid_t pid) { | 155 | struct sway_workspace *root_workspace_for_pid(pid_t pid) { |
164 | if (!pid_workspaces.prev && !pid_workspaces.next) { | 156 | if (!pid_workspaces.prev && !pid_workspaces.next) { |
165 | wl_list_init(&pid_workspaces); | 157 | wl_list_init(&pid_workspaces); |
166 | return NULL; | 158 | return NULL; |
167 | } | 159 | } |
168 | 160 | ||
169 | struct sway_container *ws = NULL; | 161 | struct sway_workspace *ws = NULL; |
170 | struct pid_workspace *pw = NULL; | 162 | struct pid_workspace *pw = NULL; |
171 | 163 | ||
172 | wlr_log(WLR_DEBUG, "Looking up workspace for pid %d", pid); | 164 | wlr_log(WLR_DEBUG, "Looking up workspace for pid %d", pid); |
@@ -219,16 +211,12 @@ void root_record_workspace_pid(pid_t pid) { | |||
219 | } | 211 | } |
220 | 212 | ||
221 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 213 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
222 | struct sway_container *ws = | 214 | struct sway_workspace *ws = seat_get_focused_workspace(seat); |
223 | seat_get_focus_inactive(seat, &root_container); | ||
224 | if (ws && ws->type != C_WORKSPACE) { | ||
225 | ws = container_parent(ws, C_WORKSPACE); | ||
226 | } | ||
227 | if (!ws) { | 215 | if (!ws) { |
228 | wlr_log(WLR_DEBUG, "Bailing out, no workspace"); | 216 | wlr_log(WLR_DEBUG, "Bailing out, no workspace"); |
229 | return; | 217 | return; |
230 | } | 218 | } |
231 | struct sway_container *output = ws->parent; | 219 | struct sway_output *output = ws->output; |
232 | if (!output) { | 220 | if (!output) { |
233 | wlr_log(WLR_DEBUG, "Bailing out, no output"); | 221 | wlr_log(WLR_DEBUG, "Bailing out, no output"); |
234 | return; | 222 | return; |
@@ -255,30 +243,28 @@ void root_record_workspace_pid(pid_t pid) { | |||
255 | pw->pid = pid; | 243 | pw->pid = pid; |
256 | memcpy(&pw->time_added, &now, sizeof(struct timespec)); | 244 | memcpy(&pw->time_added, &now, sizeof(struct timespec)); |
257 | pw->output_destroy.notify = pw_handle_output_destroy; | 245 | pw->output_destroy.notify = pw_handle_output_destroy; |
258 | wl_signal_add(&output->sway_output->wlr_output->events.destroy, | 246 | wl_signal_add(&output->wlr_output->events.destroy, &pw->output_destroy); |
259 | &pw->output_destroy); | ||
260 | wl_list_insert(&pid_workspaces, &pw->link); | 247 | wl_list_insert(&pid_workspaces, &pw->link); |
261 | } | 248 | } |
262 | 249 | ||
263 | void root_for_each_workspace(void (*f)(struct sway_container *con, void *data), | 250 | void root_for_each_workspace(void (*f)(struct sway_workspace *ws, void *data), |
264 | void *data) { | 251 | void *data) { |
265 | for (int i = 0; i < root_container.children->length; ++i) { | 252 | for (int i = 0; i < root->outputs->length; ++i) { |
266 | struct sway_container *output = root_container.children->items[i]; | 253 | struct sway_output *output = root->outputs->items[i]; |
267 | output_for_each_workspace(output, f, data); | 254 | output_for_each_workspace(output, f, data); |
268 | } | 255 | } |
269 | } | 256 | } |
270 | 257 | ||
271 | void root_for_each_container(void (*f)(struct sway_container *con, void *data), | 258 | void root_for_each_container(void (*f)(struct sway_container *con, void *data), |
272 | void *data) { | 259 | void *data) { |
273 | for (int i = 0; i < root_container.children->length; ++i) { | 260 | for (int i = 0; i < root->outputs->length; ++i) { |
274 | struct sway_container *output = root_container.children->items[i]; | 261 | struct sway_output *output = root->outputs->items[i]; |
275 | output_for_each_container(output, f, data); | 262 | output_for_each_container(output, f, data); |
276 | } | 263 | } |
277 | 264 | ||
278 | // Scratchpad | 265 | // Scratchpad |
279 | for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) { | 266 | for (int i = 0; i < root->scratchpad->length; ++i) { |
280 | struct sway_container *container = | 267 | struct sway_container *container = root->scratchpad->items[i]; |
281 | root_container.sway_root->scratchpad->items[i]; | ||
282 | // If the container has a parent then it's visible on a workspace | 268 | // If the container has a parent then it's visible on a workspace |
283 | // and will have been iterated in the previous for loop. So we only | 269 | // and will have been iterated in the previous for loop. So we only |
284 | // iterate the hidden scratchpad containers here. | 270 | // iterate the hidden scratchpad containers here. |
@@ -289,10 +275,10 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data), | |||
289 | } | 275 | } |
290 | } | 276 | } |
291 | 277 | ||
292 | struct sway_container *root_find_output( | 278 | struct sway_output *root_find_output( |
293 | bool (*test)(struct sway_container *con, void *data), void *data) { | 279 | bool (*test)(struct sway_output *output, void *data), void *data) { |
294 | for (int i = 0; i < root_container.children->length; ++i) { | 280 | for (int i = 0; i < root->outputs->length; ++i) { |
295 | struct sway_container *output = root_container.children->items[i]; | 281 | struct sway_output *output = root->outputs->items[i]; |
296 | if (test(output, data)) { | 282 | if (test(output, data)) { |
297 | return output; | 283 | return output; |
298 | } | 284 | } |
@@ -300,11 +286,11 @@ struct sway_container *root_find_output( | |||
300 | return NULL; | 286 | return NULL; |
301 | } | 287 | } |
302 | 288 | ||
303 | struct sway_container *root_find_workspace( | 289 | struct sway_workspace *root_find_workspace( |
304 | bool (*test)(struct sway_container *con, void *data), void *data) { | 290 | bool (*test)(struct sway_workspace *ws, void *data), void *data) { |
305 | struct sway_container *result = NULL; | 291 | struct sway_workspace *result = NULL; |
306 | for (int i = 0; i < root_container.children->length; ++i) { | 292 | for (int i = 0; i < root->outputs->length; ++i) { |
307 | struct sway_container *output = root_container.children->items[i]; | 293 | struct sway_output *output = root->outputs->items[i]; |
308 | if ((result = output_find_workspace(output, test, data))) { | 294 | if ((result = output_find_workspace(output, test, data))) { |
309 | return result; | 295 | return result; |
310 | } | 296 | } |
@@ -315,17 +301,16 @@ struct sway_container *root_find_workspace( | |||
315 | struct sway_container *root_find_container( | 301 | struct sway_container *root_find_container( |
316 | bool (*test)(struct sway_container *con, void *data), void *data) { | 302 | bool (*test)(struct sway_container *con, void *data), void *data) { |
317 | struct sway_container *result = NULL; | 303 | struct sway_container *result = NULL; |
318 | for (int i = 0; i < root_container.children->length; ++i) { | 304 | for (int i = 0; i < root->outputs->length; ++i) { |
319 | struct sway_container *output = root_container.children->items[i]; | 305 | struct sway_output *output = root->outputs->items[i]; |
320 | if ((result = output_find_container(output, test, data))) { | 306 | if ((result = output_find_container(output, test, data))) { |
321 | return result; | 307 | return result; |
322 | } | 308 | } |
323 | } | 309 | } |
324 | 310 | ||
325 | // Scratchpad | 311 | // Scratchpad |
326 | for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) { | 312 | for (int i = 0; i < root->scratchpad->length; ++i) { |
327 | struct sway_container *container = | 313 | struct sway_container *container = root->scratchpad->items[i]; |
328 | root_container.sway_root->scratchpad->items[i]; | ||
329 | if (!container->parent) { | 314 | if (!container->parent) { |
330 | if (test(container, data)) { | 315 | if (test(container, data)) { |
331 | return container; | 316 | return container; |
@@ -337,3 +322,10 @@ struct sway_container *root_find_container( | |||
337 | } | 322 | } |
338 | return NULL; | 323 | return NULL; |
339 | } | 324 | } |
325 | |||
326 | void root_get_box(struct sway_root *root, struct wlr_box *box) { | ||
327 | box->x = root->x; | ||
328 | box->y = root->y; | ||
329 | box->width = root->width; | ||
330 | box->height = root->height; | ||
331 | } | ||