diff options
-rw-r--r-- | include/sway/layers.h | 11 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 80 |
2 files changed, 91 insertions, 0 deletions
diff --git a/include/sway/layers.h b/include/sway/layers.h index 025776f8..457634c2 100644 --- a/include/sway/layers.h +++ b/include/sway/layers.h | |||
@@ -20,6 +20,7 @@ struct sway_layer_surface { | |||
20 | struct wl_listener surface_commit; | 20 | struct wl_listener surface_commit; |
21 | struct wl_listener output_destroy; | 21 | struct wl_listener output_destroy; |
22 | struct wl_listener new_popup; | 22 | struct wl_listener new_popup; |
23 | struct wl_listener new_subsurface; | ||
23 | 24 | ||
24 | struct wlr_box geo; | 25 | struct wlr_box geo; |
25 | enum zwlr_layer_shell_v1_layer layer; | 26 | enum zwlr_layer_shell_v1_layer layer; |
@@ -39,6 +40,16 @@ struct sway_layer_popup { | |||
39 | struct wl_listener new_popup; | 40 | struct wl_listener new_popup; |
40 | }; | 41 | }; |
41 | 42 | ||
43 | struct sway_layer_subsurface { | ||
44 | struct wlr_subsurface *wlr_subsurface; | ||
45 | struct sway_layer_surface *layer_surface; | ||
46 | |||
47 | struct wl_listener map; | ||
48 | struct wl_listener unmap; | ||
49 | struct wl_listener destroy; | ||
50 | struct wl_listener commit; | ||
51 | }; | ||
52 | |||
42 | struct sway_output; | 53 | struct sway_output; |
43 | void arrange_layers(struct sway_output *output); | 54 | void arrange_layers(struct sway_output *output); |
44 | 55 | ||
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 738b1797..d4ca4fb4 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -351,6 +351,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
351 | wl_list_remove(&sway_layer->unmap.link); | 351 | wl_list_remove(&sway_layer->unmap.link); |
352 | wl_list_remove(&sway_layer->surface_commit.link); | 352 | wl_list_remove(&sway_layer->surface_commit.link); |
353 | wl_list_remove(&sway_layer->new_popup.link); | 353 | wl_list_remove(&sway_layer->new_popup.link); |
354 | wl_list_remove(&sway_layer->new_subsurface.link); | ||
354 | if (sway_layer->layer_surface->output != NULL) { | 355 | if (sway_layer->layer_surface->output != NULL) { |
355 | struct sway_output *output = sway_layer->layer_surface->output->data; | 356 | struct sway_output *output = sway_layer->layer_surface->output->data; |
356 | if (output != NULL) { | 357 | if (output != NULL) { |
@@ -380,6 +381,82 @@ static void handle_unmap(struct wl_listener *listener, void *data) { | |||
380 | unmap(sway_layer); | 381 | unmap(sway_layer); |
381 | } | 382 | } |
382 | 383 | ||
384 | static void subsurface_damage(struct sway_layer_subsurface *subsurface, | ||
385 | bool whole) { | ||
386 | struct sway_layer_surface *layer = subsurface->layer_surface; | ||
387 | struct wlr_output *wlr_output = layer->layer_surface->output; | ||
388 | if (!wlr_output) { | ||
389 | return; | ||
390 | } | ||
391 | struct sway_output *output = wlr_output->data; | ||
392 | int ox = subsurface->wlr_subsurface->current.x + layer->geo.x; | ||
393 | int oy = subsurface->wlr_subsurface->current.y + layer->geo.y; | ||
394 | output_damage_surface( | ||
395 | output, ox, oy, subsurface->wlr_subsurface->surface, whole); | ||
396 | } | ||
397 | |||
398 | static void subsurface_handle_unmap(struct wl_listener *listener, void *data) { | ||
399 | struct sway_layer_subsurface *subsurface = | ||
400 | wl_container_of(listener, subsurface, unmap); | ||
401 | subsurface_damage(subsurface, true); | ||
402 | } | ||
403 | |||
404 | static void subsurface_handle_map(struct wl_listener *listener, void *data) { | ||
405 | struct sway_layer_subsurface *subsurface = | ||
406 | wl_container_of(listener, subsurface, map); | ||
407 | subsurface_damage(subsurface, true); | ||
408 | } | ||
409 | |||
410 | static void subsurface_handle_commit(struct wl_listener *listener, void *data) { | ||
411 | struct sway_layer_subsurface *subsurface = | ||
412 | wl_container_of(listener, subsurface, commit); | ||
413 | subsurface_damage(subsurface, false); | ||
414 | } | ||
415 | |||
416 | static void subsurface_handle_destroy(struct wl_listener *listener, | ||
417 | void *data) { | ||
418 | struct sway_layer_subsurface *subsurface = | ||
419 | wl_container_of(listener, subsurface, destroy); | ||
420 | |||
421 | wl_list_remove(&subsurface->map.link); | ||
422 | wl_list_remove(&subsurface->unmap.link); | ||
423 | wl_list_remove(&subsurface->destroy.link); | ||
424 | wl_list_remove(&subsurface->commit.link); | ||
425 | free(subsurface); | ||
426 | } | ||
427 | |||
428 | static struct sway_layer_subsurface *create_subsurface( | ||
429 | struct wlr_subsurface *wlr_subsurface, | ||
430 | struct sway_layer_surface *layer_surface) { | ||
431 | struct sway_layer_subsurface *subsurface = | ||
432 | calloc(1, sizeof(struct sway_layer_surface)); | ||
433 | if (subsurface == NULL) { | ||
434 | return NULL; | ||
435 | } | ||
436 | |||
437 | subsurface->wlr_subsurface = wlr_subsurface; | ||
438 | subsurface->layer_surface = layer_surface; | ||
439 | |||
440 | subsurface->map.notify = subsurface_handle_map; | ||
441 | wl_signal_add(&wlr_subsurface->events.map, &subsurface->map); | ||
442 | subsurface->unmap.notify = subsurface_handle_unmap; | ||
443 | wl_signal_add(&wlr_subsurface->events.unmap, &subsurface->unmap); | ||
444 | subsurface->destroy.notify = subsurface_handle_destroy; | ||
445 | wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | ||
446 | subsurface->commit.notify = subsurface_handle_commit; | ||
447 | wl_signal_add(&wlr_subsurface->surface->events.commit, &subsurface->commit); | ||
448 | |||
449 | return subsurface; | ||
450 | } | ||
451 | |||
452 | static void handle_new_subsurface(struct wl_listener *listener, void *data) { | ||
453 | struct sway_layer_surface *sway_layer_surface = | ||
454 | wl_container_of(listener, sway_layer_surface, new_subsurface); | ||
455 | struct wlr_subsurface *wlr_subsurface = data; | ||
456 | create_subsurface(wlr_subsurface, sway_layer_surface); | ||
457 | } | ||
458 | |||
459 | |||
383 | static struct sway_layer_surface *popup_get_layer( | 460 | static struct sway_layer_surface *popup_get_layer( |
384 | struct sway_layer_popup *popup) { | 461 | struct sway_layer_popup *popup) { |
385 | while (popup->parent_type == LAYER_PARENT_POPUP) { | 462 | while (popup->parent_type == LAYER_PARENT_POPUP) { |
@@ -563,6 +640,9 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { | |||
563 | wl_signal_add(&layer_surface->events.unmap, &sway_layer->unmap); | 640 | wl_signal_add(&layer_surface->events.unmap, &sway_layer->unmap); |
564 | sway_layer->new_popup.notify = handle_new_popup; | 641 | sway_layer->new_popup.notify = handle_new_popup; |
565 | wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup); | 642 | wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup); |
643 | sway_layer->new_subsurface.notify = handle_new_subsurface; | ||
644 | wl_signal_add(&layer_surface->surface->events.new_subsurface, | ||
645 | &sway_layer->new_subsurface); | ||
566 | 646 | ||
567 | sway_layer->layer_surface = layer_surface; | 647 | sway_layer->layer_surface = layer_surface; |
568 | layer_surface->data = sway_layer; | 648 | layer_surface->data = sway_layer; |