commit 8a2d575

shrub  ·  2026-03-19 20:39:24 +0000 UTC
parent a77b61b
feat: implement wlr-layer-shell
14 files changed,  +1178, -26
+1, -0
1@@ -47,6 +47,7 @@ struct swc {
2 	struct swc_drm *const drm;
3 	struct wl_global *data_device_manager;
4 	struct wl_global *kde_decoration_manager;
5+	struct wl_global *layer_shell;
6 	struct wl_global *panel_manager;
7 	struct wl_global *shell;
8 	struct wl_global *snap_manager;
+624, -0
  1@@ -0,0 +1,624 @@
  2+#include "layer_shell.h"
  3+
  4+#include "compositor.h"
  5+#include "internal.h"
  6+#include "keyboard.h"
  7+#include "output.h"
  8+#include "screen.h"
  9+#include "seat.h"
 10+#include "surface.h"
 11+#include "util.h"
 12+#include "view.h"
 13+
 14+#include "wlr-layer-shell-unstable-v1-server-protocol.h"
 15+#include <assert.h>
 16+#include <inttypes.h>
 17+#include <stdlib.h>
 18+
 19+struct layer_surface {
 20+	struct wl_resource *resource;
 21+	struct wl_listener surface_destroy_listener;
 22+	struct wl_listener surface_commit_listener;
 23+	struct compositor_view *view;
 24+	struct view_handler view_handler;
 25+	struct screen *screen;
 26+	struct screen_modifier modifier;
 27+	struct layer_surface_state {
 28+		uint32_t layer;
 29+		uint32_t anchor;
 30+		int32_t exclusive_zone;
 31+		uint32_t exclusive_edge;
 32+		uint32_t keyboard_interactivity;
 33+		struct {
 34+			int32_t top, right, bottom, left;
 35+		} margin;
 36+		uint32_t desired_width, desired_height;
 37+	} current, pending;
 38+	uint32_t configure_serial;
 39+	bool configured;
 40+	bool mapped;
 41+};
 42+
 43+static bool
 44+state_equal(const struct layer_surface_state *a,
 45+            const struct layer_surface_state *b)
 46+{
 47+	return a->layer == b->layer && a->anchor == b->anchor &&
 48+	       a->exclusive_zone == b->exclusive_zone &&
 49+	       a->exclusive_edge == b->exclusive_edge &&
 50+	       a->keyboard_interactivity == b->keyboard_interactivity &&
 51+	       a->margin.top == b->margin.top &&
 52+	       a->margin.right == b->margin.right &&
 53+	       a->margin.bottom == b->margin.bottom &&
 54+	       a->margin.left == b->margin.left &&
 55+	       a->desired_width == b->desired_width &&
 56+	       a->desired_height == b->desired_height;
 57+}
 58+
 59+static int32_t
 60+available_size(uint32_t size, int32_t start_margin, int32_t end_margin)
 61+{
 62+	int32_t available = (int32_t)size - start_margin - end_margin;
 63+
 64+	return MAX(available, 0);
 65+}
 66+
 67+static uint32_t
 68+configure_size(uint32_t desired, uint32_t anchor, uint32_t first_anchor,
 69+               uint32_t second_anchor, uint32_t total_size, int32_t start_margin,
 70+               int32_t end_margin)
 71+{
 72+	if (desired != 0) {
 73+		return desired;
 74+	}
 75+
 76+	if ((anchor & first_anchor) && (anchor & second_anchor)) {
 77+		return available_size(total_size, start_margin, end_margin);
 78+	}
 79+
 80+	return 0;
 81+}
 82+
 83+static uint32_t
 84+exclusive_edge(struct layer_surface *surface)
 85+{
 86+	if (surface->current.exclusive_edge != 0) {
 87+		return surface->current.exclusive_edge;
 88+	}
 89+
 90+	switch (surface->current.anchor) {
 91+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
 92+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 93+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
 94+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP:
 95+		return ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
 96+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
 97+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 98+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
 99+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
100+		return ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
101+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
102+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
103+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
104+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT:
105+		return ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
106+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
107+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
108+	    ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
109+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
110+		return ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
111+	default:
112+		return 0;
113+	}
114+}
115+
116+static int32_t
117+exclusive_size(struct layer_surface *surface)
118+{
119+	switch (surface->current.exclusive_zone) {
120+	case 0:
121+		return 0;
122+	case -1:
123+		switch (exclusive_edge(surface)) {
124+		case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP:
125+			return (int32_t)surface->view->base.geometry.height +
126+			       surface->current.margin.top;
127+		case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
128+			return (int32_t)surface->view->base.geometry.height +
129+			       surface->current.margin.bottom;
130+		case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT:
131+			return (int32_t)surface->view->base.geometry.width +
132+			       surface->current.margin.left;
133+		case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
134+			return (int32_t)surface->view->base.geometry.width +
135+			       surface->current.margin.right;
136+		default:
137+			return 0;
138+		}
139+	default:
140+			return MAX(surface->current.exclusive_zone, 0);
141+	}
142+}
143+
144+static void
145+update_usable_geometry(struct layer_surface *surface)
146+{
147+	if (!surface->screen) {
148+		return;
149+	}
150+
151+	screen_update_usable_geometry(surface->screen);
152+}
153+
154+static void
155+restack_layer(struct layer_surface *surface)
156+{
157+	bool always_top = surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP ||
158+	                  surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
159+
160+	surface->view->always_top = always_top;
161+	if (always_top) {
162+		raise_window_top(surface->view);
163+	}
164+}
165+
166+static void
167+update_position(struct layer_surface *surface)
168+{
169+	struct swc_rectangle *screen = &surface->screen->base.geometry;
170+	struct swc_rectangle *view = &surface->view->base.geometry;
171+	int32_t x, y;
172+
173+	if ((surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) &&
174+	    !(surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
175+		x = screen->x + surface->current.margin.left;
176+	} else if ((surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT) &&
177+	           !(surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
178+		x = screen->x + (int32_t)screen->width - (int32_t)view->width -
179+		    surface->current.margin.right;
180+	} else {
181+		x = screen->x + ((int32_t)screen->width - (int32_t)view->width +
182+		                 surface->current.margin.left -
183+		                 surface->current.margin.right) /
184+		                2;
185+	}
186+
187+	if ((surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) &&
188+	    !(surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
189+		y = screen->y + surface->current.margin.top;
190+	} else if ((surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) &&
191+	           !(surface->current.anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
192+		y = screen->y + (int32_t)screen->height - (int32_t)view->height -
193+		    surface->current.margin.bottom;
194+	} else {
195+		y = screen->y + ((int32_t)screen->height - (int32_t)view->height +
196+		                 surface->current.margin.top -
197+		                 surface->current.margin.bottom) /
198+		                2;
199+	}
200+
201+	view_move(&surface->view->base, x, y);
202+}
203+
204+static void
205+send_configure(struct layer_surface *surface)
206+{
207+	uint32_t width, height;
208+
209+	if (!surface->screen) {
210+		return;
211+	}
212+
213+	width = configure_size(surface->current.desired_width, surface->current.anchor,
214+	                       ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT,
215+	                       ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
216+	                       surface->screen->base.geometry.width,
217+	                       surface->current.margin.left,
218+	                       surface->current.margin.right);
219+	height =
220+	    configure_size(surface->current.desired_height, surface->current.anchor,
221+	                   ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
222+	                   ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
223+	                   surface->screen->base.geometry.height,
224+	                   surface->current.margin.top,
225+	                   surface->current.margin.bottom);
226+	surface->configure_serial = wl_display_next_serial(swc.display);
227+	zwlr_layer_surface_v1_send_configure(surface->resource,
228+	                                     surface->configure_serial, width,
229+	                                     height);
230+}
231+
232+static void
233+set_size(struct wl_client *client, struct wl_resource *resource, uint32_t width,
234+         uint32_t height)
235+{
236+	struct layer_surface *surface = wl_resource_get_user_data(resource);
237+
238+	(void)client;
239+
240+	surface->pending.desired_width = width;
241+	surface->pending.desired_height = height;
242+}
243+
244+static void
245+set_anchor(struct wl_client *client, struct wl_resource *resource,
246+           uint32_t anchor)
247+{
248+	struct layer_surface *surface = wl_resource_get_user_data(resource);
249+
250+	(void)client;
251+
252+	surface->pending.anchor = anchor;
253+}
254+
255+static void
256+set_exclusive_zone(struct wl_client *client, struct wl_resource *resource,
257+                   int32_t zone)
258+{
259+	struct layer_surface *surface = wl_resource_get_user_data(resource);
260+
261+	(void)client;
262+
263+	surface->pending.exclusive_zone = zone;
264+}
265+
266+static void
267+set_margin(struct wl_client *client, struct wl_resource *resource, int32_t top,
268+           int32_t right, int32_t bottom, int32_t left)
269+{
270+	struct layer_surface *surface = wl_resource_get_user_data(resource);
271+
272+	(void)client;
273+
274+	surface->pending.margin.top = top;
275+	surface->pending.margin.right = right;
276+	surface->pending.margin.bottom = bottom;
277+	surface->pending.margin.left = left;
278+}
279+
280+static void
281+set_keyboard_interactivity(struct wl_client *client, struct wl_resource *resource,
282+                           uint32_t keyboard_interactivity)
283+{
284+	struct layer_surface *surface = wl_resource_get_user_data(resource);
285+
286+	(void)client;
287+
288+	surface->pending.keyboard_interactivity = keyboard_interactivity;
289+}
290+
291+static void
292+get_popup(struct wl_client *client, struct wl_resource *resource,
293+          struct wl_resource *popup)
294+{
295+	(void)client;
296+	(void)resource;
297+	(void)popup;
298+}
299+
300+static void
301+ack_configure(struct wl_client *client, struct wl_resource *resource,
302+              uint32_t serial)
303+{
304+	struct layer_surface *surface = wl_resource_get_user_data(resource);
305+
306+	(void)client;
307+
308+	if (serial == surface->configure_serial) {
309+		update_position(surface);
310+	}
311+}
312+
313+static void
314+set_layer(struct wl_client *client, struct wl_resource *resource, uint32_t layer)
315+{
316+	struct layer_surface *surface = wl_resource_get_user_data(resource);
317+
318+	(void)client;
319+
320+	if (layer > ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) {
321+		wl_resource_post_error(resource,
322+		                       ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER,
323+		                       "invalid layer %" PRIu32, layer);
324+		return;
325+	}
326+
327+	surface->pending.layer = layer;
328+}
329+
330+static void
331+set_exclusive_edge(struct wl_client *client, struct wl_resource *resource,
332+                   uint32_t edge)
333+{
334+	struct layer_surface *surface = wl_resource_get_user_data(resource);
335+
336+	(void)client;
337+
338+	surface->pending.exclusive_edge = edge;
339+}
340+
341+static const struct zwlr_layer_surface_v1_interface layer_surface_impl = {
342+    .set_size = set_size,
343+    .set_anchor = set_anchor,
344+    .set_exclusive_zone = set_exclusive_zone,
345+    .set_margin = set_margin,
346+    .set_keyboard_interactivity = set_keyboard_interactivity,
347+    .get_popup = get_popup,
348+    .ack_configure = ack_configure,
349+    .destroy = destroy_resource,
350+    .set_layer = set_layer,
351+    .set_exclusive_edge = set_exclusive_edge,
352+};
353+
354+static void
355+handle_attach(struct view_handler *handler)
356+{
357+	struct layer_surface *surface = wl_container_of(handler, surface, view_handler);
358+	bool mapped = surface->view->base.buffer != NULL;
359+
360+	if (mapped) {
361+		update_position(surface);
362+		restack_layer(surface);
363+		if (!surface->mapped) {
364+			compositor_view_show(surface->view);
365+			if (surface->current.keyboard_interactivity !=
366+			    ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
367+				keyboard_set_focus(swc.seat->keyboard, surface->view);
368+			}
369+		}
370+	} else if (surface->mapped) {
371+		compositor_view_hide(surface->view);
372+	}
373+
374+	surface->mapped = mapped;
375+	update_usable_geometry(surface);
376+}
377+
378+static void
379+handle_resize(struct view_handler *handler, uint32_t old_width,
380+              uint32_t old_height)
381+{
382+	struct layer_surface *surface = wl_container_of(handler, surface, view_handler);
383+
384+	(void)old_width;
385+	(void)old_height;
386+
387+	update_position(surface);
388+	update_usable_geometry(surface);
389+}
390+
391+static const struct view_handler_impl view_handler_impl = {
392+    .attach = handle_attach,
393+    .resize = handle_resize,
394+};
395+
396+static void
397+handle_surface_commit(struct wl_listener *listener, void *data)
398+{
399+	struct layer_surface *surface =
400+	    wl_container_of(listener, surface, surface_commit_listener);
401+	bool state_changed = !state_equal(&surface->current, &surface->pending);
402+
403+	(void)data;
404+
405+	if (state_changed) {
406+		surface->current = surface->pending;
407+		restack_layer(surface);
408+		update_usable_geometry(surface);
409+	}
410+
411+	/* mke sure that the inital commit and also any later state change gets a fresh
412+	 * configure  */
413+	if (!surface->configured || state_changed) {
414+		send_configure(surface);
415+		surface->configured = true;
416+	}
417+}
418+
419+static void
420+modify(struct screen_modifier *modifier, const struct swc_rectangle *geom,
421+       pixman_region32_t *usable)
422+{
423+	struct layer_surface *surface = wl_container_of(modifier, surface, modifier);
424+	pixman_box32_t box = {.x1 = geom->x,
425+	                      .y1 = geom->y,
426+	                      .x2 = geom->x + geom->width,
427+	                      .y2 = geom->y + geom->height};
428+	int32_t size;
429+
430+	if (!surface->mapped) {
431+		pixman_region32_reset(usable, &box);
432+		return;
433+	}
434+
435+	size = exclusive_size(surface);
436+	if (size <= 0) {
437+		pixman_region32_reset(usable, &box);
438+		return;
439+	}
440+
441+	/* shrink usuable area*/
442+	switch (exclusive_edge(surface)) {
443+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP:
444+		box.y1 = MAX(box.y1, geom->y + size);
445+		break;
446+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
447+		box.y2 = MIN(box.y2, geom->y + geom->height - size);
448+		break;
449+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT:
450+		box.x1 = MAX(box.x1, geom->x + size);
451+		break;
452+	case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
453+		box.x2 = MIN(box.x2, geom->x + geom->width - size);
454+		break;
455+	default:
456+		break;
457+	}
458+
459+	pixman_region32_reset(usable, &box);
460+}
461+
462+static void
463+destroy_layer_surface(struct wl_resource *resource)
464+{
465+	struct layer_surface *surface = wl_resource_get_user_data(resource);
466+	bool had_screen = surface->screen != NULL;
467+
468+	wl_list_remove(&surface->surface_destroy_listener.link);
469+	wl_list_remove(&surface->surface_commit_listener.link);
470+	wl_list_remove(&surface->modifier.link);
471+	compositor_view_destroy(surface->view);
472+	if (had_screen) {
473+		screen_update_usable_geometry(surface->screen);
474+	}
475+	free(surface);
476+}
477+
478+static void
479+handle_surface_destroy(struct wl_listener *listener, void *data)
480+{
481+	struct layer_surface *surface =
482+	    wl_container_of(listener, surface, surface_destroy_listener);
483+
484+	(void)data;
485+
486+	wl_resource_destroy(surface->resource);
487+}
488+
489+static struct layer_surface *
490+layer_surface_new(struct wl_client *client, uint32_t version, uint32_t id,
491+                  struct surface *surface, struct screen *screen, uint32_t layer)
492+{
493+	struct layer_surface *layer_surface;
494+
495+	layer_surface = calloc(1, sizeof(*layer_surface));
496+	if (!layer_surface) {
497+		goto error0;
498+	}
499+
500+	layer_surface->resource =
501+	    wl_resource_create(client, &zwlr_layer_surface_v1_interface, version, id);
502+	if (!layer_surface->resource) {
503+		goto error1;
504+	}
505+
506+	if (!(layer_surface->view = compositor_create_view(surface))) {
507+		goto error2;
508+	}
509+
510+	if (!surface_set_role(surface, layer_surface->resource)) {
511+		goto error3;
512+	}
513+
514+	layer_surface->screen = screen;
515+	layer_surface->current.layer = layer;
516+	layer_surface->pending = layer_surface->current;
517+	layer_surface->current.exclusive_zone = 0;
518+	layer_surface->current.exclusive_edge = 0;
519+	layer_surface->current.keyboard_interactivity =
520+	    ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
521+	layer_surface->pending = layer_surface->current;
522+	layer_surface->surface_destroy_listener.notify = handle_surface_destroy;
523+	layer_surface->surface_commit_listener.notify = handle_surface_commit;
524+	layer_surface->view_handler.impl = &view_handler_impl;
525+	layer_surface->modifier.modify = modify;
526+	wl_list_init(&layer_surface->modifier.link);
527+	wl_resource_set_implementation(layer_surface->resource, &layer_surface_impl,
528+	                               layer_surface, destroy_layer_surface);
529+	wl_resource_add_destroy_listener(surface->resource,
530+	                                 &layer_surface->surface_destroy_listener);
531+	wl_signal_add(&surface->signal.commit, &layer_surface->surface_commit_listener);
532+	wl_list_insert(&layer_surface->view->base.handlers,
533+	               &layer_surface->view_handler.link);
534+	wl_list_insert(&screen->modifiers, &layer_surface->modifier.link);
535+	restack_layer(layer_surface);
536+
537+	return layer_surface;
538+
539+error3:
540+	compositor_view_destroy(layer_surface->view);
541+error2:
542+	wl_resource_destroy(layer_surface->resource);
543+error1:
544+	free(layer_surface);
545+error0:
546+	return NULL;
547+}
548+
549+static void
550+get_layer_surface(struct wl_client *client, struct wl_resource *resource,
551+                  uint32_t id, struct wl_resource *surface_resource,
552+                  struct wl_resource *output_resource, uint32_t layer,
553+                  const char *namespace_)
554+{
555+	struct surface *surface = wl_resource_get_user_data(surface_resource);
556+	struct output *output;
557+	struct screen *screen;
558+
559+	(void)namespace_;
560+
561+	if (layer > ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) {
562+		wl_resource_post_error(resource,
563+		                       ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER,
564+		                       "invalid layer %" PRIu32, layer);
565+		return;
566+	}
567+
568+	if (surface->role) {
569+		wl_resource_post_error(resource, ZWLR_LAYER_SHELL_V1_ERROR_ROLE,
570+		                       "surface already has a role");
571+		return;
572+	}
573+
574+	if (surface_has_buffer(surface)) {
575+		wl_resource_post_error(resource,
576+		                       ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED,
577+		                       "surface already has a buffer");
578+		return;
579+	}
580+
581+	if (output_resource) {
582+		output = wl_resource_get_user_data(output_resource);
583+		screen = output ? output->screen : NULL;
584+	} else if (!wl_list_empty(&swc.screens)) {
585+		screen = wl_container_of(swc.screens.next, screen, link);
586+	} else {
587+		screen = NULL;
588+	}
589+
590+	if (!screen ||
591+	    !layer_surface_new(client, wl_resource_get_version(resource), id, surface,
592+	                       screen, layer)) {
593+		wl_client_post_no_memory(client);
594+	}
595+}
596+
597+static const struct zwlr_layer_shell_v1_interface layer_shell_impl = {
598+    .get_layer_surface = get_layer_surface,
599+    .destroy = destroy_resource,
600+};
601+
602+static void
603+bind_layer_shell(struct wl_client *client, void *data, uint32_t version,
604+                 uint32_t id)
605+{
606+	struct wl_resource *resource;
607+
608+	(void)data;
609+
610+	resource =
611+	    wl_resource_create(client, &zwlr_layer_shell_v1_interface, version, id);
612+	if (!resource) {
613+		wl_client_post_no_memory(client);
614+		return;
615+	}
616+
617+	wl_resource_set_implementation(resource, &layer_shell_impl, NULL, NULL);
618+}
619+
620+struct wl_global *
621+layer_shell_create(struct wl_display *display)
622+{
623+	return wl_global_create(display, &zwlr_layer_shell_v1_interface, 5, NULL,
624+	                        bind_layer_shell);
625+}
+10, -0
 1@@ -0,0 +1,10 @@
 2+#ifndef SWC_LAYER_SHELL_H
 3+#define SWC_LAYER_SHELL_H
 4+
 5+struct wl_display;
 6+struct wl_global;
 7+
 8+struct wl_global *
 9+layer_shell_create(struct wl_display *display);
10+
11+#endif
+1, -0
1@@ -11,6 +11,7 @@ libswc_src = files(
2   'input.c',
3   'kde_decoration.c',
4   'keyboard.c',
5+  'layer_shell.c',
6   'launch.c',
7   'mode.c',
8   'output.c',
+8, -4
 1@@ -258,13 +258,17 @@ panel_new(struct wl_client *client, uint32_t version, uint32_t id,
 2 	    wl_resource_create(client, &swc_panel_interface, version, id);
 3 
 4 	if (!panel->resource) {
 5-		goto error1;
 6+		goto error0;
 7 	}
 8 
 9-	if (!(panel->view = compositor_create_view(surface))) {
10+	if (!surface_set_role(surface, panel->resource)) {
11 		goto error2;
12 	}
13 
14+	if (!(panel->view = compositor_create_view(surface))) {
15+		goto error3;
16+	}
17+
18 	wl_resource_set_implementation(panel->resource, &panel_impl, panel,
19 	                               &destroy_panel);
20 	panel->surface_destroy_listener.notify = &handle_surface_destroy;
21@@ -282,9 +286,9 @@ panel_new(struct wl_client *client, uint32_t version, uint32_t id,
22 
23 	return panel;
24 
25-error2:
26+error3:
27 	wl_resource_destroy(panel->resource);
28-error1:
29+error2:
30 	free(panel);
31 error0:
32 	return NULL;
+7, -0
 1@@ -23,6 +23,7 @@
 2 
 3 #include "shell.h"
 4 #include "internal.h"
 5+#include "surface.h"
 6 #include "shell_surface.h"
 7 
 8 #include <wayland-server.h>
 9@@ -34,6 +35,12 @@ get_shell_surface(struct wl_client *client, struct wl_resource *resource,
10 	struct surface *surface = wl_resource_get_user_data(surface_resource);
11 	struct shell_surface *shell_surface;
12 
13+	if (surface->role) {
14+		wl_resource_post_error(resource, WL_SHELL_ERROR_ROLE,
15+		                       "surface already has a role");
16+		return;
17+	}
18+
19 	shell_surface = shell_surface_new(client, wl_resource_get_version(resource),
20 	                                  id, surface);
21 
+9, -2
 1@@ -249,19 +249,26 @@ shell_surface_new(struct wl_client *client, uint32_t version, uint32_t id,
 2 	if (!shell_surface->resource) {
 3 		goto error1;
 4 	}
 5+	if (!surface_set_role(surface, shell_surface->resource)) {
 6+		goto error2;
 7+	}
 8 
 9+	if (!window_initialize(&shell_surface->window, &window_impl, surface)) {
10+		goto error2;
11+	}
12 	wl_resource_set_implementation(shell_surface->resource,
13 	                               &shell_surface_implementation, shell_surface,
14 	                               &destroy_shell_surface);
15-	window_initialize(&shell_surface->window, &window_impl, surface);
16 	shell_surface->surface_destroy_listener.notify = &handle_surface_destroy;
17 	wl_resource_add_destroy_listener(surface->resource,
18 	                                 &shell_surface->surface_destroy_listener);
19 
20 	return shell_surface;
21 
22-error1:
23+error2:
24+	wl_resource_destroy(shell_surface->resource);
25 	free(shell_surface);
26+error1:
27 error0:
28 	return NULL;
29 }
+40, -0
 1@@ -46,12 +46,25 @@ handle_buffer_destroy(struct wl_listener *listener, void *data)
 2 
 3 	state = wl_container_of(listener, state, buffer_destroy_listener);
 4 	state->buffer = NULL;
 5+	state->buffer_resource = NULL;
 6+}
 7+
 8+static void
 9+handle_role_destroy(struct wl_listener *listener, void *data)
10+{
11+	struct surface *surface = wl_container_of(listener, surface, role_destroy_listener);
12+
13+	(void)data;
14+
15+	surface->role = NULL;
16 }
17 
18 static void
19 state_initialize(struct surface_state *state)
20 {
21 	state->buffer = NULL;
22+	/*layer-shell rejects surfaces with a pre-existing buffer */
23+	state->buffer_resource = NULL;
24 	state->buffer_destroy_listener.notify = &handle_buffer_destroy;
25 
26 	pixman_region32_init(&state->damage);
27@@ -304,6 +317,7 @@ surface_apply_pending(struct surface *surface, bool flush_children)
28 	}
29 
30 	subsurface_parent_commit(surface);
31+	wl_signal_emit(&surface->signal.commit, surface);
32 
33 	if (flush_children) {
34 		struct subsurface *child;
35@@ -385,6 +399,9 @@ surface_destroy(struct wl_resource *resource)
36 	if (surface->view) {
37 		wl_list_remove(&surface->view_handler.link);
38 	}
39+	if (surface->role) {
40+		wl_list_remove(&surface->role_destroy_listener.link);
41+	}
42 
43 	free(surface);
44 }
45@@ -416,8 +433,11 @@ surface_new(struct wl_client *client, uint32_t version, uint32_t id)
46 
47 	/* Initialize the surface. */
48 	surface->pending.commit = 0;
49+	wl_signal_init(&surface->signal.commit);
50 	surface->view = NULL;
51 	surface->view_handler.impl = &view_handler_impl;
52+	surface->role = NULL;
53+	surface->role_destroy_listener.notify = handle_role_destroy;
54 	surface->subsurface = NULL;
55 	wl_list_init(&surface->subsurfaces);
56 	surface->has_window_geometry = false;
57@@ -458,6 +478,26 @@ surface_set_view(struct surface *surface, struct view *view)
58 	}
59 }
60 
61+bool
62+surface_set_role(struct surface *surface, struct wl_resource *role)
63+{
64+	if (surface->role) {
65+		return false;
66+	}
67+
68+	surface->role = role;
69+	wl_resource_add_destroy_listener(role, &surface->role_destroy_listener);
70+	return true;
71+}
72+
73+bool
74+surface_has_buffer(struct surface *surface)
75+{
76+	return surface->state.buffer_resource ||
77+	       ((surface->pending.commit & SURFACE_COMMIT_ATTACH) &&
78+	        surface->pending.state.buffer_resource);
79+}
80+
81 void
82 surface_commit_pending(struct surface *surface)
83 {
+9, -0
 1@@ -62,6 +62,9 @@ struct surface_state {
 2 
 3 struct surface {
 4 	struct wl_resource *resource;
 5+	struct {
 6+		struct wl_signal commit;
 7+	} signal;
 8 
 9 	struct surface_state state;
10 
11@@ -73,6 +76,8 @@ struct surface {
12 
13 	struct view *view;
14 	struct view_handler view_handler;
15+	struct wl_resource *role;
16+	struct wl_listener role_destroy_listener;
17 
18 	struct subsurface *subsurface;
19 	struct wl_list subsurfaces;
20@@ -86,6 +91,10 @@ struct surface *
21 surface_new(struct wl_client *client, uint32_t version, uint32_t id);
22 void
23 surface_set_view(struct surface *surface, struct view *view);
24+bool
25+surface_set_role(struct surface *surface, struct wl_resource *role);
26+bool
27+surface_has_buffer(struct surface *surface);
28 void
29 surface_commit_pending(struct surface *surface);
30 
+20, -10
 1@@ -31,6 +31,7 @@
 2 #include "kde_decoration.h"
 3 #include "keyboard.h"
 4 #include "launch.h"
 5+#include "layer_shell.h"
 6 #include "panel_manager.h"
 7 #include "pointer.h"
 8 #include "screen.h"
 9@@ -228,57 +229,65 @@ swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop,
10 		goto error12;
11 	}
12 
13+	swc.layer_shell = layer_shell_create(display);
14+	if (!swc.layer_shell) {
15+		ERROR("Could not initialize layer shell\n");
16+		goto error13;
17+	}
18+
19 	swc.panel_manager = panel_manager_create(display);
20 	if (!swc.panel_manager) {
21 		ERROR("Could not initialize panel manager\n");
22-		goto error13;
23+		goto error14;
24 	}
25 
26 	swc.snap_manager = snap_manager_create(display);
27 	if (!swc.snap_manager) {
28 		ERROR("Could not initialize snap manager\n");
29-		goto error14;
30+		goto error15;
31 	}
32 
33 	swc.wallpaper_manager = swc_wallpaper_manager_create(display);
34 	if (!swc.wallpaper_manager) {
35 		ERROR("Could not initialize wallpaper manager\n");
36-		goto error15;
37+		goto error16;
38 	}
39 
40 #ifdef ENABLE_XWAYLAND
41 	if (!xserver_initialize()) {
42 		ERROR("Could not initialize xwayland\n");
43-		goto error16;
44+		goto error17;
45 	}
46 #endif
47 
48 	swc.select_manager = select_manager_create(display);
49 	if (!swc.select_manager) {
50 		ERROR("Could not initialize select manager\n");
51-		goto error17;
52+		goto error18;
53 	}
54 
55 	swc.xdg_output_manager = xdg_output_manager_create(display);
56 	if (!swc.xdg_output_manager) {
57 		ERROR("Could not initialize XDG output manager\n");
58-		goto error17;
59+		goto error18;
60 	}
61 
62 	setup_compositor();
63 
64 	return true;
65 
66-error17:
67+error18:
68 	wl_global_destroy(swc.select_manager);
69 #ifdef ENABLE_XWAYLAND
70-error16:
71+error17:
72 	wl_global_destroy(swc.wallpaper_manager);
73 #endif
74-error15:
75+error16:
76 	wl_global_destroy(swc.snap_manager);
77-error14:
78+error15:
79 	wl_global_destroy(swc.panel_manager);
80+error14:
81+	wl_global_destroy(swc.layer_shell);
82 error13:
83 	wl_global_destroy(swc.kde_decoration_manager);
84 error12:
85@@ -320,6 +329,7 @@ swc_finalize(void)
86 	wl_global_destroy(swc.snap_manager);
87 	wl_global_destroy(swc.select_manager);
88 	wl_global_destroy(swc.panel_manager);
89+	wl_global_destroy(swc.layer_shell);
90 	wl_global_destroy(swc.xdg_decoration_manager);
91 	wl_global_destroy(swc.xdg_shell);
92 	wl_global_destroy(swc.shell);
+12, -2
 1@@ -38,6 +38,7 @@ get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id,
 2 	struct output *output =
 3 	    wl_resource_get_user_data(output_resource);
 4 	struct swc_rectangle *geom = &output->screen->base.geometry;
 5+	struct wl_resource *wl_output_resource;
 6 
 7 	resource = wl_resource_create(client, &zxdg_output_v1_interface, wl_resource_get_version(resource), id);
 8 	if (!resource) {
 9@@ -48,8 +49,17 @@ get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id,
10 	wl_resource_set_implementation(resource, &output_impl, NULL, NULL);
11 	zxdg_output_v1_send_logical_position(resource, geom->x, geom->y);
12 	zxdg_output_v1_send_logical_size(resource, geom->width, geom->height);
13-	zxdg_output_v1_send_name(resource, output->name);
14-	wl_output_send_done(output->resource);
15+	if (wl_resource_get_version(resource) >= 2) {
16+		zxdg_output_v1_send_name(resource, output->name);
17+		zxdg_output_v1_send_description(resource, output->name);
18+	}
19+	zxdg_output_v1_send_done(resource);
20+
21+	wl_output_resource =
22+	    wl_resource_find_for_client(&output->resources, client);
23+	if (wl_output_resource && wl_resource_get_version(wl_output_resource) >= 2) {
24+		wl_output_send_done(wl_output_resource);
25+	}
26 }
27 
28 static const struct zxdg_output_manager_v1_interface output_manager_impl = {
+29, -8
 1@@ -498,8 +498,13 @@ xdg_toplevel_new(struct wl_client *client, uint32_t version, uint32_t id,
 2 	if (!toplevel->resource) {
 3 		goto error1;
 4 	}
 5-	window_initialize(&toplevel->window, &toplevel_window_impl,
 6-	                  xdg_surface->surface);
 7+	if (!surface_set_role(xdg_surface->surface, toplevel->resource)) {
 8+		goto error2;
 9+	}
10+	if (!window_initialize(&toplevel->window, &toplevel_window_impl,
11+	                       xdg_surface->surface)) {
12+		goto error2;
13+	}
14 	wl_array_init(&toplevel->states);
15 	wl_resource_set_implementation(toplevel->resource, &toplevel_impl, toplevel,
16 	                               &destroy_toplevel);
17@@ -507,8 +512,10 @@ xdg_toplevel_new(struct wl_client *client, uint32_t version, uint32_t id,
18 
19 	return toplevel;
20 
21-error1:
22+error2:
23+	wl_resource_destroy(toplevel->resource);
24 	free(toplevel);
25+error1:
26 error0:
27 	return NULL;
28 }
29@@ -559,12 +566,15 @@ xdg_popup_new(struct wl_client *client, uint32_t version, uint32_t id,
30 	if (!popup->resource) {
31 		goto error1;
32 	}
33-	wl_resource_set_implementation(popup->resource, &popup_impl, popup,
34-	                               &destroy_popup);
35+	if (!surface_set_role(xdg_surface->surface, popup->resource)) {
36+		goto error2;
37+	}
38 	popup->view = compositor_create_view(xdg_surface->surface);
39 	if (!popup->view) {
40-		goto error2;
41+		goto error3;
42 	}
43+	wl_resource_set_implementation(popup->resource, &popup_impl, popup,
44+	                               &destroy_popup);
45 
46 	rect = calculate_position(positioner);
47 	compositor_view_set_parent(popup->view, parent_view);
48@@ -576,10 +586,11 @@ xdg_popup_new(struct wl_client *client, uint32_t version, uint32_t id,
49 
50 	return popup;
51 
52-error2:
53+error3:
54 	wl_resource_destroy(popup->resource);
55-error1:
56+error2:
57 	free(popup);
58+error1:
59 error0:
60 	return NULL;
61 }
62@@ -597,6 +608,11 @@ get_toplevel(struct wl_client *client, struct wl_resource *resource,
63 		                       "surface already has a role");
64 		return;
65 	}
66+	if (xdg_surface->surface->role) {
67+		wl_resource_post_error(resource, XDG_WM_BASE_ERROR_ROLE,
68+		                       "surface already has a role");
69+		return;
70+	}
71 	toplevel = xdg_toplevel_new(client, wl_resource_get_version(resource), id,
72 	                            xdg_surface);
73 	if (!toplevel) {
74@@ -624,6 +640,11 @@ get_popup(struct wl_client *client, struct wl_resource *resource, uint32_t id,
75 		                       "surface already has a role");
76 		return;
77 	}
78+	if (xdg_surface->surface->role) {
79+		wl_resource_post_error(resource, XDG_WM_BASE_ERROR_ROLE,
80+		                       "surface already has a role");
81+		return;
82+	}
83 	popup = xdg_popup_new(client, wl_resource_get_version(resource), id,
84 	                      xdg_surface, parent, positioner);
85 	if (!popup) {
+1, -0
1@@ -8,6 +8,7 @@ foreach proto : [
2   'swc_snap.xml',
3   'swc_select.xml',
4   'swc_wallpaper.xml',
5+  'wlr-layer-shell-unstable-v1.xml',
6   'wayland-drm.xml',
7   wl.find_protocol('xdg-shell', state: 'stable'),
8   wl.find_protocol('linux-dmabuf', state: 'unstable', version: 1),
+407, -0
  1@@ -0,0 +1,407 @@
  2+<?xml version="1.0" encoding="UTF-8"?>
  3+<protocol name="wlr_layer_shell_unstable_v1">
  4+  <copyright>
  5+    Copyright © 2017 Drew DeVault
  6+
  7+    Permission to use, copy, modify, distribute, and sell this
  8+    software and its documentation for any purpose is hereby granted
  9+    without fee, provided that the above copyright notice appear in
 10+    all copies and that both that copyright notice and this permission
 11+    notice appear in supporting documentation, and that the name of
 12+    the copyright holders not be used in advertising or publicity
 13+    pertaining to distribution of the software without specific,
 14+    written prior permission.  The copyright holders make no
 15+    representations about the suitability of this software for any
 16+    purpose.  It is provided "as is" without express or implied
 17+    warranty.
 18+
 19+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 20+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 21+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 22+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 23+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 24+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 25+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 26+    THIS SOFTWARE.
 27+  </copyright>
 28+
 29+  <interface name="zwlr_layer_shell_v1" version="5">
 30+    <description summary="create surfaces that are layers of the desktop">
 31+      Clients can use this interface to assign the surface_layer role to
 32+      wl_surfaces. Such surfaces are assigned to a "layer" of the output and
 33+      rendered with a defined z-depth respective to each other. They may also be
 34+      anchored to the edges and corners of a screen and specify input handling
 35+      semantics. This interface should be suitable for the implementation of
 36+      many desktop shell components, and a broad number of other applications
 37+      that interact with the desktop.
 38+    </description>
 39+
 40+    <request name="get_layer_surface">
 41+      <description summary="create a layer_surface from a surface">
 42+        Create a layer surface for an existing surface. This assigns the role of
 43+        layer_surface, or raises a protocol error if another role is already
 44+        assigned.
 45+
 46+        Creating a layer surface from a wl_surface which has a buffer attached
 47+        or committed is a client error, and any attempts by a client to attach
 48+        or manipulate a buffer prior to the first layer_surface.configure call
 49+        must also be treated as errors.
 50+
 51+        After creating a layer_surface object and setting it up, the client
 52+        must perform an initial commit without any buffer attached.
 53+        The compositor will reply with a layer_surface.configure event.
 54+        The client must acknowledge it and is then allowed to attach a buffer
 55+        to map the surface.
 56+
 57+        You may pass NULL for output to allow the compositor to decide which
 58+        output to use. Generally this will be the one that the user most
 59+        recently interacted with.
 60+
 61+        Clients can specify a namespace that defines the purpose of the layer
 62+        surface.
 63+      </description>
 64+      <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
 65+      <arg name="surface" type="object" interface="wl_surface"/>
 66+      <arg name="output" type="object" interface="wl_output" allow-null="true"/>
 67+      <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
 68+      <arg name="namespace" type="string" summary="namespace for the layer surface"/>
 69+    </request>
 70+
 71+    <enum name="error">
 72+      <entry name="role" value="0" summary="wl_surface has another role"/>
 73+      <entry name="invalid_layer" value="1" summary="layer value is invalid"/>
 74+      <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
 75+    </enum>
 76+
 77+    <enum name="layer">
 78+      <description summary="available layers for surfaces">
 79+        These values indicate which layers a surface can be rendered in. They
 80+        are ordered by z depth, bottom-most first. Traditional shell surfaces
 81+        will typically be rendered between the bottom and top layers.
 82+        Fullscreen shell surfaces are typically rendered at the top layer.
 83+        Multiple surfaces can share a single layer, and ordering within a
 84+        single layer is undefined.
 85+      </description>
 86+
 87+      <entry name="background" value="0"/>
 88+      <entry name="bottom" value="1"/>
 89+      <entry name="top" value="2"/>
 90+      <entry name="overlay" value="3"/>
 91+    </enum>
 92+
 93+    <!-- Version 3 additions -->
 94+
 95+    <request name="destroy" type="destructor" since="3">
 96+      <description summary="destroy the layer_shell object">
 97+        This request indicates that the client will not use the layer_shell
 98+        object any more. Objects that have been created through this instance
 99+        are not affected.
100+      </description>
101+    </request>
102+  </interface>
103+
104+  <interface name="zwlr_layer_surface_v1" version="5">
105+    <description summary="layer metadata interface">
106+      An interface that may be implemented by a wl_surface, for surfaces that
107+      are designed to be rendered as a layer of a stacked desktop-like
108+      environment.
109+
110+      Layer surface state (layer, size, anchor, exclusive zone,
111+      margin, interactivity) is double-buffered, and will be applied at the
112+      time wl_surface.commit of the corresponding wl_surface is called.
113+
114+      Attaching a null buffer to a layer surface unmaps it.
115+
116+      Unmapping a layer_surface means that the surface cannot be shown by the
117+      compositor until it is explicitly mapped again. The layer_surface
118+      returns to the state it had right after layer_shell.get_layer_surface.
119+      The client can re-map the surface by performing a commit without any
120+      buffer attached, waiting for a configure event and handling it as usual.
121+    </description>
122+
123+    <request name="set_size">
124+      <description summary="sets the size of the surface">
125+        Sets the size of the surface in surface-local coordinates. The
126+        compositor will display the surface centered with respect to its
127+        anchors.
128+
129+        If you pass 0 for either value, the compositor will assign it and
130+        inform you of the assignment in the configure event. You must set your
131+        anchor to opposite edges in the dimensions you omit; not doing so is a
132+        protocol error. Both values are 0 by default.
133+
134+        Size is double-buffered, see wl_surface.commit.
135+      </description>
136+      <arg name="width" type="uint"/>
137+      <arg name="height" type="uint"/>
138+    </request>
139+
140+    <request name="set_anchor">
141+      <description summary="configures the anchor point of the surface">
142+        Requests that the compositor anchor the surface to the specified edges
143+        and corners. If two orthogonal edges are specified (e.g. 'top' and
144+        'left'), then the anchor point will be the intersection of the edges
145+        (e.g. the top left corner of the output); otherwise the anchor point
146+        will be centered on that edge, or in the center if none is specified.
147+
148+        Anchor is double-buffered, see wl_surface.commit.
149+      </description>
150+      <arg name="anchor" type="uint" enum="anchor"/>
151+    </request>
152+
153+    <request name="set_exclusive_zone">
154+      <description summary="configures the exclusive geometry of this surface">
155+        Requests that the compositor avoids occluding an area with other
156+        surfaces. The compositor's use of this information is
157+        implementation-dependent - do not assume that this region will not
158+        actually be occluded.
159+
160+        A positive value is only meaningful if the surface is anchored to one
161+        edge or an edge and both perpendicular edges. If the surface is not
162+        anchored, anchored to only two perpendicular edges (a corner), anchored
163+        to only two parallel edges or anchored to all edges, a positive value
164+        will be treated the same as zero.
165+
166+        A positive zone is the distance from the edge in surface-local
167+        coordinates to consider exclusive.
168+
169+        Surfaces that do not wish to have an exclusive zone may instead specify
170+        how they should interact with surfaces that do. If set to zero, the
171+        surface indicates that it would like to be moved to avoid occluding
172+        surfaces with a positive exclusive zone. If set to -1, the surface
173+        indicates that it would not like to be moved to accommodate for other
174+        surfaces, and the compositor should extend it all the way to the edges
175+        it is anchored to.
176+
177+        For example, a panel might set its exclusive zone to 10, so that
178+        maximized shell surfaces are not shown on top of it. A notification
179+        might set its exclusive zone to 0, so that it is moved to avoid
180+        occluding the panel, but shell surfaces are shown underneath it. A
181+        wallpaper or lock screen might set their exclusive zone to -1, so that
182+        they stretch below or over the panel.
183+
184+        The default value is 0.
185+
186+        Exclusive zone is double-buffered, see wl_surface.commit.
187+      </description>
188+      <arg name="zone" type="int"/>
189+    </request>
190+
191+    <request name="set_margin">
192+      <description summary="sets a margin from the anchor point">
193+        Requests that the surface be placed some distance away from the anchor
194+        point on the output, in surface-local coordinates. Setting this value
195+        for edges you are not anchored to has no effect.
196+
197+        The exclusive zone includes the margin.
198+
199+        Margin is double-buffered, see wl_surface.commit.
200+      </description>
201+      <arg name="top" type="int"/>
202+      <arg name="right" type="int"/>
203+      <arg name="bottom" type="int"/>
204+      <arg name="left" type="int"/>
205+    </request>
206+
207+    <enum name="keyboard_interactivity">
208+      <description summary="types of keyboard interaction possible for a layer shell surface">
209+        Types of keyboard interaction possible for layer shell surfaces. The
210+        rationale for this is twofold: (1) some applications are not interested
211+        in keyboard events and not allowing them to be focused can improve the
212+        desktop experience; (2) some applications will want to take exclusive
213+        keyboard focus.
214+      </description>
215+
216+      <entry name="none" value="0">
217+        <description summary="no keyboard focus is possible">
218+          This value indicates that this surface is not interested in keyboard
219+          events and the compositor should never assign it the keyboard focus.
220+
221+          This is the default value, set for newly created layer shell surfaces.
222+
223+          This is useful for e.g. desktop widgets that display information or
224+          only have interaction with non-keyboard input devices.
225+        </description>
226+      </entry>
227+      <entry name="exclusive" value="1">
228+        <description summary="request exclusive keyboard focus">
229+          Request exclusive keyboard focus if this surface is above the shell surface layer.
230+
231+          For the top and overlay layers, the seat will always give
232+          exclusive keyboard focus to the top-most layer which has keyboard
233+          interactivity set to exclusive. If this layer contains multiple
234+          surfaces with keyboard interactivity set to exclusive, the compositor
235+          determines the one receiving keyboard events in an implementation-
236+          defined manner. In this case, no guarantee is made when this surface
237+          will receive keyboard focus (if ever).
238+
239+          For the bottom and background layers, the compositor is allowed to use
240+          normal focus semantics.
241+
242+          This setting is mainly intended for applications that need to ensure
243+          they receive all keyboard events, such as a lock screen or a password
244+          prompt.
245+        </description>
246+      </entry>
247+      <entry name="on_demand" value="2" since="4">
248+        <description summary="request regular keyboard focus semantics">
249+          This requests the compositor to allow this surface to be focused and
250+          unfocused by the user in an implementation-defined manner. The user
251+          should be able to unfocus this surface even regardless of the layer
252+          it is on.
253+
254+          Typically, the compositor will want to use its normal mechanism to
255+          manage keyboard focus between layer shell surfaces with this setting
256+          and regular toplevels on the desktop layer (e.g. click to focus).
257+          Nevertheless, it is possible for a compositor to require a special
258+          interaction to focus or unfocus layer shell surfaces (e.g. requiring
259+          a click even if focus follows the mouse normally, or providing a
260+          keybinding to switch focus between layers).
261+
262+          This setting is mainly intended for desktop shell components (e.g.
263+          panels) that allow keyboard interaction. Using this option can allow
264+          implementing a desktop shell that can be fully usable without the
265+          mouse.
266+        </description>
267+      </entry>
268+    </enum>
269+
270+    <request name="set_keyboard_interactivity">
271+      <description summary="requests keyboard events">
272+        Set how keyboard events are delivered to this surface. By default,
273+        layer shell surfaces do not receive keyboard events; this request can
274+        be used to change this.
275+
276+        This setting is inherited by child surfaces set by the get_popup
277+        request.
278+
279+        Layer surfaces receive pointer, touch, and tablet events normally. If
280+        you do not want to receive them, set the input region on your surface
281+        to an empty region.
282+
283+        Keyboard interactivity is double-buffered, see wl_surface.commit.
284+      </description>
285+      <arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/>
286+    </request>
287+
288+    <request name="get_popup">
289+      <description summary="assign this layer_surface as an xdg_popup parent">
290+        This assigns an xdg_popup's parent to this layer_surface.  This popup
291+        should have been created via xdg_surface::get_popup with the parent set
292+        to NULL, and this request must be invoked before committing the popup's
293+        initial state.
294+
295+        See the documentation of xdg_popup for more details about what an
296+        xdg_popup is and how it is used.
297+      </description>
298+      <arg name="popup" type="object" interface="xdg_popup"/>
299+    </request>
300+
301+    <request name="ack_configure">
302+      <description summary="ack a configure event">
303+        When a configure event is received, if a client commits the
304+        surface in response to the configure event, then the client
305+        must make an ack_configure request sometime before the commit
306+        request, passing along the serial of the configure event.
307+
308+        If the client receives multiple configure events before it
309+        can respond to one, it only has to ack the last configure event.
310+
311+        A client is not required to commit immediately after sending
312+        an ack_configure request - it may even ack_configure several times
313+        before its next surface commit.
314+
315+        A client may send multiple ack_configure requests before committing, but
316+        only the last request sent before a commit indicates which configure
317+        event the client really is responding to.
318+      </description>
319+      <arg name="serial" type="uint" summary="the serial from the configure event"/>
320+    </request>
321+
322+    <request name="destroy" type="destructor">
323+      <description summary="destroy the layer_surface">
324+        This request destroys the layer surface.
325+      </description>
326+    </request>
327+
328+    <event name="configure">
329+      <description summary="suggest a surface change">
330+        The configure event asks the client to resize its surface.
331+
332+        Clients should arrange their surface for the new states, and then send
333+        an ack_configure request with the serial sent in this configure event at
334+        some point before committing the new surface.
335+
336+        The client is free to dismiss all but the last configure event it
337+        received.
338+
339+        The width and height arguments specify the size of the window in
340+        surface-local coordinates.
341+
342+        The size is a hint, in the sense that the client is free to ignore it if
343+        it doesn't resize, pick a smaller size (to satisfy aspect ratio or
344+        resize in steps of NxM pixels). If the client picks a smaller size and
345+        is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
346+        surface will be centered on this axis.
347+
348+        If the width or height arguments are zero, it means the client should
349+        decide its own window dimension.
350+      </description>
351+      <arg name="serial" type="uint"/>
352+      <arg name="width" type="uint"/>
353+      <arg name="height" type="uint"/>
354+    </event>
355+
356+    <event name="closed">
357+      <description summary="surface should be closed">
358+        The closed event is sent by the compositor when the surface will no
359+        longer be shown. The output may have been destroyed or the user may
360+        have asked for it to be removed. Further changes to the surface will be
361+        ignored. The client should destroy the resource after receiving this
362+        event, and create a new surface if they so choose.
363+      </description>
364+    </event>
365+
366+    <enum name="error">
367+      <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
368+      <entry name="invalid_size" value="1" summary="size is invalid"/>
369+      <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
370+      <entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
371+      <entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/>
372+    </enum>
373+
374+    <enum name="anchor" bitfield="true">
375+      <entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
376+      <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
377+      <entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
378+      <entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
379+    </enum>
380+
381+    <!-- Version 2 additions -->
382+
383+    <request name="set_layer" since="2">
384+      <description summary="change the layer of the surface">
385+        Change the layer that the surface is rendered on.
386+
387+        Layer is double-buffered, see wl_surface.commit.
388+      </description>
389+      <arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
390+    </request>
391+
392+    <!-- Version 5 additions -->
393+
394+    <request name="set_exclusive_edge" since="5">
395+      <description summary="set the edge the exclusive zone will be applied to">
396+        Requests an edge for the exclusive zone to apply. The exclusive
397+        edge will be automatically deduced from anchor points when possible,
398+        but when the surface is anchored to a corner, it will be necessary
399+        to set it explicitly to disambiguate, as it is not possible to deduce
400+        which one of the two corner edges should be used.
401+
402+        The edge must be one the surface is anchored to, otherwise the
403+        invalid_exclusive_edge protocol error will be raised.
404+      </description>
405+      <arg name="edge" type="uint" enum="anchor"/>
406+    </request>
407+  </interface>
408+</protocol>