1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <wayland-server-core.h>
5 #include <wlr/types/wlr_box.h>
6 #include <wlr/types/wlr_layer_shell_v1.h>
7 #include <wlr/types/wlr_output_damage.h>
8 #include <wlr/types/wlr_output.h>
9 #include "log.h"
10 #include "sway/desktop/transaction.h"
11 #include "sway/input/cursor.h"
12 #include "sway/input/input-manager.h"
13 #include "sway/input/seat.h"
14 #include "sway/layers.h"
15 #include "sway/output.h"
16 #include "sway/server.h"
17 #include "sway/tree/arrange.h"
18 #include "sway/tree/workspace.h"
19 
apply_exclusive(struct wlr_box * usable_area,uint32_t anchor,int32_t exclusive,int32_t margin_top,int32_t margin_right,int32_t margin_bottom,int32_t margin_left)20 static void apply_exclusive(struct wlr_box *usable_area,
21 		uint32_t anchor, int32_t exclusive,
22 		int32_t margin_top, int32_t margin_right,
23 		int32_t margin_bottom, int32_t margin_left) {
24 	if (exclusive <= 0) {
25 		return;
26 	}
27 	struct {
28 		uint32_t singular_anchor;
29 		uint32_t anchor_triplet;
30 		int *positive_axis;
31 		int *negative_axis;
32 		int margin;
33 	} edges[] = {
34 		// Top
35 		{
36 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
37 			.anchor_triplet =
38 				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
39 				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
40 				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
41 			.positive_axis = &usable_area->y,
42 			.negative_axis = &usable_area->height,
43 			.margin = margin_top,
44 		},
45 		// Bottom
46 		{
47 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
48 			.anchor_triplet =
49 				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
50 				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
51 				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
52 			.positive_axis = NULL,
53 			.negative_axis = &usable_area->height,
54 			.margin = margin_bottom,
55 		},
56 		// Left
57 		{
58 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT,
59 			.anchor_triplet =
60 				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
61 				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
62 				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
63 			.positive_axis = &usable_area->x,
64 			.negative_axis = &usable_area->width,
65 			.margin = margin_left,
66 		},
67 		// Right
68 		{
69 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
70 			.anchor_triplet =
71 				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
72 				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
73 				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
74 			.positive_axis = NULL,
75 			.negative_axis = &usable_area->width,
76 			.margin = margin_right,
77 		},
78 	};
79 	for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) {
80 		if ((anchor  == edges[i].singular_anchor || anchor == edges[i].anchor_triplet)
81 				&& exclusive + edges[i].margin > 0) {
82 			if (edges[i].positive_axis) {
83 				*edges[i].positive_axis += exclusive + edges[i].margin;
84 			}
85 			if (edges[i].negative_axis) {
86 				*edges[i].negative_axis -= exclusive + edges[i].margin;
87 			}
88 			break;
89 		}
90 	}
91 }
92 
arrange_layer(struct sway_output * output,struct wl_list * list,struct wlr_box * usable_area,bool exclusive)93 static void arrange_layer(struct sway_output *output, struct wl_list *list,
94 		struct wlr_box *usable_area, bool exclusive) {
95 	struct sway_layer_surface *sway_layer;
96 	struct wlr_box full_area = { 0 };
97 	wlr_output_effective_resolution(output->wlr_output,
98 			&full_area.width, &full_area.height);
99 	wl_list_for_each(sway_layer, list, link) {
100 		struct wlr_layer_surface_v1 *layer = sway_layer->layer_surface;
101 		struct wlr_layer_surface_v1_state *state = &layer->current;
102 		if (exclusive != (state->exclusive_zone > 0)) {
103 			continue;
104 		}
105 		struct wlr_box bounds;
106 		if (state->exclusive_zone == -1) {
107 			bounds = full_area;
108 		} else {
109 			bounds = *usable_area;
110 		}
111 		struct wlr_box box = {
112 			.width = state->desired_width,
113 			.height = state->desired_height
114 		};
115 		// Horizontal axis
116 		const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
117 			| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
118 		if ((state->anchor & both_horiz) && box.width == 0) {
119 			box.x = bounds.x;
120 			box.width = bounds.width;
121 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
122 			box.x = bounds.x;
123 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
124 			box.x = bounds.x + (bounds.width - box.width);
125 		} else {
126 			box.x = bounds.x + ((bounds.width / 2) - (box.width / 2));
127 		}
128 		// Vertical axis
129 		const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
130 			| ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
131 		if ((state->anchor & both_vert) && box.height == 0) {
132 			box.y = bounds.y;
133 			box.height = bounds.height;
134 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
135 			box.y = bounds.y;
136 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
137 			box.y = bounds.y + (bounds.height - box.height);
138 		} else {
139 			box.y = bounds.y + ((bounds.height / 2) - (box.height / 2));
140 		}
141 		// Margin
142 		if ((state->anchor & both_horiz) == both_horiz) {
143 			box.x += state->margin.left;
144 			box.width -= state->margin.left + state->margin.right;
145 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
146 			box.x += state->margin.left;
147 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
148 			box.x -= state->margin.right;
149 		}
150 		if ((state->anchor & both_vert) == both_vert) {
151 			box.y += state->margin.top;
152 			box.height -= state->margin.top + state->margin.bottom;
153 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
154 			box.y += state->margin.top;
155 		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
156 			box.y -= state->margin.bottom;
157 		}
158 		if (box.width < 0 || box.height < 0) {
159 			// TODO: Bubble up a protocol error?
160 			wlr_layer_surface_v1_close(layer);
161 			continue;
162 		}
163 		// Apply
164 		sway_layer->geo = box;
165 		apply_exclusive(usable_area, state->anchor, state->exclusive_zone,
166 				state->margin.top, state->margin.right,
167 				state->margin.bottom, state->margin.left);
168 		wlr_layer_surface_v1_configure(layer, box.width, box.height);
169 	}
170 }
171 
arrange_layers(struct sway_output * output)172 void arrange_layers(struct sway_output *output) {
173 	struct wlr_box usable_area = { 0 };
174 	wlr_output_effective_resolution(output->wlr_output,
175 			&usable_area.width, &usable_area.height);
176 
177 	// Arrange exclusive surfaces from top->bottom
178 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
179 			&usable_area, true);
180 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
181 			&usable_area, true);
182 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
183 			&usable_area, true);
184 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
185 			&usable_area, true);
186 
187 	if (memcmp(&usable_area, &output->usable_area,
188 				sizeof(struct wlr_box)) != 0) {
189 		sway_log(SWAY_DEBUG, "Usable area changed, rearranging output");
190 		memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box));
191 		arrange_output(output);
192 	}
193 
194 	// Arrange non-exlusive surfaces from top->bottom
195 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
196 			&usable_area, false);
197 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
198 			&usable_area, false);
199 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
200 			&usable_area, false);
201 	arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
202 			&usable_area, false);
203 
204 	// Find topmost keyboard interactive layer, if such a layer exists
205 	uint32_t layers_above_shell[] = {
206 		ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
207 		ZWLR_LAYER_SHELL_V1_LAYER_TOP,
208 	};
209 	size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
210 	struct sway_layer_surface *layer, *topmost = NULL;
211 	for (size_t i = 0; i < nlayers; ++i) {
212 		wl_list_for_each_reverse(layer,
213 				&output->layers[layers_above_shell[i]], link) {
214 			if (layer->layer_surface->current.keyboard_interactive &&
215 					layer->layer_surface->mapped) {
216 				topmost = layer;
217 				break;
218 			}
219 		}
220 		if (topmost != NULL) {
221 			break;
222 		}
223 	}
224 
225 	struct sway_seat *seat;
226 	wl_list_for_each(seat, &server.input->seats, link) {
227 		if (topmost != NULL) {
228 			seat_set_focus_layer(seat, topmost->layer_surface);
229 		} else if (seat->focused_layer &&
230 				!seat->focused_layer->current.keyboard_interactive) {
231 			seat_set_focus_layer(seat, NULL);
232 		}
233 	}
234 }
235 
find_mapped_layer_by_client(struct wl_client * client,struct wlr_output * ignore_output)236 static struct sway_layer_surface *find_mapped_layer_by_client(
237 		struct wl_client *client, struct wlr_output *ignore_output) {
238 	for (int i = 0; i < root->outputs->length; ++i) {
239 		struct sway_output *output = root->outputs->items[i];
240 		if (output->wlr_output == ignore_output) {
241 			continue;
242 		}
243 		// For now we'll only check the overlay layer
244 		struct sway_layer_surface *lsurface;
245 		wl_list_for_each(lsurface,
246 				&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
247 			struct wl_resource *resource = lsurface->layer_surface->resource;
248 			if (wl_resource_get_client(resource) == client
249 					&& lsurface->layer_surface->mapped) {
250 				return lsurface;
251 			}
252 		}
253 	}
254 	return NULL;
255 }
256 
handle_output_destroy(struct wl_listener * listener,void * data)257 static void handle_output_destroy(struct wl_listener *listener, void *data) {
258 	struct sway_layer_surface *sway_layer =
259 		wl_container_of(listener, sway_layer, output_destroy);
260 	// Determine if this layer is being used by an exclusive client. If it is,
261 	// try and find another layer owned by this client to pass focus to.
262 	struct sway_seat *seat = input_manager_get_default_seat();
263 	struct wl_client *client =
264 		wl_resource_get_client(sway_layer->layer_surface->resource);
265 	bool set_focus = seat->exclusive_client == client;
266 
267 	wl_list_remove(&sway_layer->output_destroy.link);
268 	wl_list_remove(&sway_layer->link);
269 	wl_list_init(&sway_layer->link);
270 
271 	if (set_focus) {
272 		struct sway_layer_surface *layer =
273 			find_mapped_layer_by_client(client, sway_layer->layer_surface->output);
274 		if (layer) {
275 			seat_set_focus_layer(seat, layer->layer_surface);
276 		}
277 	}
278 
279 	sway_layer->layer_surface->output = NULL;
280 	wlr_layer_surface_v1_close(sway_layer->layer_surface);
281 }
282 
handle_surface_commit(struct wl_listener * listener,void * data)283 static void handle_surface_commit(struct wl_listener *listener, void *data) {
284 	struct sway_layer_surface *layer =
285 		wl_container_of(listener, layer, surface_commit);
286 	struct wlr_layer_surface_v1 *layer_surface = layer->layer_surface;
287 	struct wlr_output *wlr_output = layer_surface->output;
288 	if (wlr_output == NULL) {
289 		return;
290 	}
291 
292 	struct sway_output *output = wlr_output->data;
293 	struct wlr_box old_geo = layer->geo;
294 	arrange_layers(output);
295 
296 	bool geo_changed =
297 		memcmp(&old_geo, &layer->geo, sizeof(struct wlr_box)) != 0;
298 	bool layer_changed = layer->layer != layer_surface->current.layer;
299 	if (layer_changed) {
300 		wl_list_remove(&layer->link);
301 		wl_list_insert(&output->layers[layer_surface->current.layer],
302 			&layer->link);
303 		layer->layer = layer_surface->current.layer;
304 	}
305 	if (geo_changed || layer_changed) {
306 		output_damage_surface(output, old_geo.x, old_geo.y,
307 			layer_surface->surface, true);
308 		output_damage_surface(output, layer->geo.x, layer->geo.y,
309 			layer_surface->surface, true);
310 	} else {
311 		output_damage_surface(output, layer->geo.x, layer->geo.y,
312 			layer_surface->surface, false);
313 	}
314 
315 	transaction_commit_dirty();
316 }
317 
unmap(struct sway_layer_surface * sway_layer)318 static void unmap(struct sway_layer_surface *sway_layer) {
319 	struct sway_seat *seat;
320 	wl_list_for_each(seat, &server.input->seats, link) {
321 		if (seat->focused_layer == sway_layer->layer_surface) {
322 			seat_set_focus_layer(seat, NULL);
323 		}
324 	}
325 
326 	cursor_rebase_all();
327 
328 	struct wlr_output *wlr_output = sway_layer->layer_surface->output;
329 	if (wlr_output == NULL) {
330 		return;
331 	}
332 	struct sway_output *output = wlr_output->data;
333 	if (output == NULL) {
334 		return;
335 	}
336 	output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y,
337 		sway_layer->layer_surface->surface, true);
338 }
339 
handle_destroy(struct wl_listener * listener,void * data)340 static void handle_destroy(struct wl_listener *listener, void *data) {
341 	struct sway_layer_surface *sway_layer =
342 		wl_container_of(listener, sway_layer, destroy);
343 	sway_log(SWAY_DEBUG, "Layer surface destroyed (%s)",
344 		sway_layer->layer_surface->namespace);
345 	if (sway_layer->layer_surface->mapped) {
346 		unmap(sway_layer);
347 	}
348 	wl_list_remove(&sway_layer->link);
349 	wl_list_remove(&sway_layer->destroy.link);
350 	wl_list_remove(&sway_layer->map.link);
351 	wl_list_remove(&sway_layer->unmap.link);
352 	wl_list_remove(&sway_layer->surface_commit.link);
353 	wl_list_remove(&sway_layer->new_popup.link);
354 	if (sway_layer->layer_surface->output != NULL) {
355 		struct sway_output *output = sway_layer->layer_surface->output->data;
356 		if (output != NULL) {
357 			arrange_layers(output);
358 			transaction_commit_dirty();
359 		}
360 		wl_list_remove(&sway_layer->output_destroy.link);
361 		sway_layer->layer_surface->output = NULL;
362 	}
363 	free(sway_layer);
364 }
365 
handle_map(struct wl_listener * listener,void * data)366 static void handle_map(struct wl_listener *listener, void *data) {
367 	struct sway_layer_surface *sway_layer = wl_container_of(listener,
368 			sway_layer, map);
369 	struct sway_output *output = sway_layer->layer_surface->output->data;
370 	output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y,
371 		sway_layer->layer_surface->surface, true);
372 	wlr_surface_send_enter(sway_layer->layer_surface->surface,
373 		sway_layer->layer_surface->output);
374 	cursor_rebase_all();
375 }
376 
handle_unmap(struct wl_listener * listener,void * data)377 static void handle_unmap(struct wl_listener *listener, void *data) {
378 	struct sway_layer_surface *sway_layer = wl_container_of(
379 			listener, sway_layer, unmap);
380 	unmap(sway_layer);
381 }
382 
popup_get_layer(struct sway_layer_popup * popup)383 static struct sway_layer_surface *popup_get_layer(
384 		struct sway_layer_popup *popup) {
385 	while (popup->parent_type == LAYER_PARENT_POPUP) {
386 		popup = popup->parent_popup;
387 	}
388 	return popup->parent_layer;
389 }
390 
popup_damage(struct sway_layer_popup * layer_popup,bool whole)391 static void popup_damage(struct sway_layer_popup *layer_popup, bool whole) {
392 	struct wlr_xdg_popup *popup = layer_popup->wlr_popup;
393 	struct wlr_surface *surface = popup->base->surface;
394 	int popup_sx = popup->geometry.x - popup->base->geometry.x;
395 	int popup_sy = popup->geometry.y - popup->base->geometry.y;
396 	int ox = popup_sx, oy = popup_sy;
397 	struct sway_layer_surface *layer;
398 	while (true) {
399 		if (layer_popup->parent_type == LAYER_PARENT_POPUP) {
400 			layer_popup = layer_popup->parent_popup;
401 			ox += layer_popup->wlr_popup->geometry.x;
402 			oy += layer_popup->wlr_popup->geometry.y;
403 		} else {
404 			layer = layer_popup->parent_layer;
405 			ox += layer->geo.x;
406 			oy += layer->geo.y;
407 			break;
408 		}
409 	}
410 	struct wlr_output *wlr_output = layer->layer_surface->output;
411 	struct sway_output *output = wlr_output->data;
412 	output_damage_surface(output, ox, oy, surface, whole);
413 }
414 
popup_handle_map(struct wl_listener * listener,void * data)415 static void popup_handle_map(struct wl_listener *listener, void *data) {
416 	struct sway_layer_popup *popup = wl_container_of(listener, popup, map);
417 	struct sway_layer_surface *layer = popup_get_layer(popup);
418 	struct wlr_output *wlr_output = layer->layer_surface->output;
419 	wlr_surface_send_enter(popup->wlr_popup->base->surface, wlr_output);
420 	popup_damage(popup, true);
421 }
422 
popup_handle_unmap(struct wl_listener * listener,void * data)423 static void popup_handle_unmap(struct wl_listener *listener, void *data) {
424 	struct sway_layer_popup *popup = wl_container_of(listener, popup, unmap);
425 	popup_damage(popup, true);
426 }
427 
popup_handle_commit(struct wl_listener * listener,void * data)428 static void popup_handle_commit(struct wl_listener *listener, void *data) {
429 	struct sway_layer_popup *popup = wl_container_of(listener, popup, commit);
430 	popup_damage(popup, false);
431 }
432 
popup_handle_destroy(struct wl_listener * listener,void * data)433 static void popup_handle_destroy(struct wl_listener *listener, void *data) {
434 	struct sway_layer_popup *popup =
435 		wl_container_of(listener, popup, destroy);
436 
437 	wl_list_remove(&popup->map.link);
438 	wl_list_remove(&popup->unmap.link);
439 	wl_list_remove(&popup->destroy.link);
440 	wl_list_remove(&popup->commit.link);
441 	free(popup);
442 }
443 
popup_unconstrain(struct sway_layer_popup * popup)444 static void popup_unconstrain(struct sway_layer_popup *popup) {
445 	struct sway_layer_surface *layer = popup_get_layer(popup);
446 	struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
447 
448 	struct sway_output *output = layer->layer_surface->output->data;
449 
450 	// the output box expressed in the coordinate system of the toplevel parent
451 	// of the popup
452 	struct wlr_box output_toplevel_sx_box = {
453 		.x = -layer->geo.x,
454 		.y = -layer->geo.y,
455 		.width = output->width,
456 		.height = output->height,
457 	};
458 
459 	wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
460 }
461 
462 static void popup_handle_new_popup(struct wl_listener *listener, void *data);
463 
create_popup(struct wlr_xdg_popup * wlr_popup,enum layer_parent parent_type,void * parent)464 static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
465 		enum layer_parent parent_type, void *parent) {
466 	struct sway_layer_popup *popup =
467 		calloc(1, sizeof(struct sway_layer_popup));
468 	if (popup == NULL) {
469 		return NULL;
470 	}
471 
472 	popup->wlr_popup = wlr_popup;
473 	popup->parent_type = parent_type;
474 	popup->parent_layer = parent;
475 
476 	popup->map.notify = popup_handle_map;
477 	wl_signal_add(&wlr_popup->base->events.map, &popup->map);
478 	popup->unmap.notify = popup_handle_unmap;
479 	wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
480 	popup->destroy.notify = popup_handle_destroy;
481 	wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
482 	popup->commit.notify = popup_handle_commit;
483 	wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
484 	popup->new_popup.notify = popup_handle_new_popup;
485 	wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
486 
487 	popup_unconstrain(popup);
488 
489 	return popup;
490 }
491 
popup_handle_new_popup(struct wl_listener * listener,void * data)492 static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
493 	struct sway_layer_popup *sway_layer_popup =
494 		wl_container_of(listener, sway_layer_popup, new_popup);
495 	struct wlr_xdg_popup *wlr_popup = data;
496 	create_popup(wlr_popup, LAYER_PARENT_POPUP, sway_layer_popup);
497 }
498 
handle_new_popup(struct wl_listener * listener,void * data)499 static void handle_new_popup(struct wl_listener *listener, void *data) {
500 	struct sway_layer_surface *sway_layer_surface =
501 		wl_container_of(listener, sway_layer_surface, new_popup);
502 	struct wlr_xdg_popup *wlr_popup = data;
503 	create_popup(wlr_popup, LAYER_PARENT_LAYER, sway_layer_surface);
504 }
505 
layer_from_wlr_layer_surface_v1(struct wlr_layer_surface_v1 * layer_surface)506 struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
507 		struct wlr_layer_surface_v1 *layer_surface) {
508 	return layer_surface->data;
509 }
510 
handle_layer_shell_surface(struct wl_listener * listener,void * data)511 void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
512 	struct wlr_layer_surface_v1 *layer_surface = data;
513 	sway_log(SWAY_DEBUG, "new layer surface: namespace %s layer %d anchor %d "
514 			"size %dx%d margin %d,%d,%d,%d",
515 		layer_surface->namespace,
516 		layer_surface->client_pending.layer,
517 		layer_surface->client_pending.layer,
518 		layer_surface->client_pending.desired_width,
519 		layer_surface->client_pending.desired_height,
520 		layer_surface->client_pending.margin.top,
521 		layer_surface->client_pending.margin.right,
522 		layer_surface->client_pending.margin.bottom,
523 		layer_surface->client_pending.margin.left);
524 
525 	if (!layer_surface->output) {
526 		// Assign last active output
527 		struct sway_output *output = NULL;
528 		struct sway_seat *seat = input_manager_get_default_seat();
529 		if (seat) {
530 			struct sway_workspace *ws = seat_get_focused_workspace(seat);
531 			if (ws != NULL) {
532 				output = ws->output;
533 			}
534 		}
535 		if (!output || output == root->noop_output) {
536 			if (!root->outputs->length) {
537 				sway_log(SWAY_ERROR,
538 						"no output to auto-assign layer surface '%s' to",
539 						layer_surface->namespace);
540 				wlr_layer_surface_v1_close(layer_surface);
541 				return;
542 			}
543 			output = root->outputs->items[0];
544 		}
545 		layer_surface->output = output->wlr_output;
546 	}
547 
548 	struct sway_layer_surface *sway_layer =
549 		calloc(1, sizeof(struct sway_layer_surface));
550 	if (!sway_layer) {
551 		return;
552 	}
553 
554 	sway_layer->surface_commit.notify = handle_surface_commit;
555 	wl_signal_add(&layer_surface->surface->events.commit,
556 		&sway_layer->surface_commit);
557 
558 	sway_layer->destroy.notify = handle_destroy;
559 	wl_signal_add(&layer_surface->events.destroy, &sway_layer->destroy);
560 	sway_layer->map.notify = handle_map;
561 	wl_signal_add(&layer_surface->events.map, &sway_layer->map);
562 	sway_layer->unmap.notify = handle_unmap;
563 	wl_signal_add(&layer_surface->events.unmap, &sway_layer->unmap);
564 	sway_layer->new_popup.notify = handle_new_popup;
565 	wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup);
566 
567 	sway_layer->layer_surface = layer_surface;
568 	layer_surface->data = sway_layer;
569 
570 	struct sway_output *output = layer_surface->output->data;
571 	sway_layer->output_destroy.notify = handle_output_destroy;
572 	wl_signal_add(&output->events.destroy, &sway_layer->output_destroy);
573 
574 	wl_list_insert(&output->layers[layer_surface->client_pending.layer],
575 			&sway_layer->link);
576 
577 	// Temporarily set the layer's current state to client_pending
578 	// So that we can easily arrange it
579 	struct wlr_layer_surface_v1_state old_state = layer_surface->current;
580 	layer_surface->current = layer_surface->client_pending;
581 	arrange_layers(output);
582 	layer_surface->current = old_state;
583 }
584