aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/layer_shell.c
diff options
context:
space:
mode:
authorLibravatar Vlad Pănăzan <vlad@panazan.ro>2020-12-05 18:32:44 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2020-12-07 12:30:13 +0100
commit71725a8eae6f8196d8e13a1b50af4f8ee4ebe971 (patch)
treece059eb969c1d9f6e5dc27f17ab944acf6c13042 /sway/desktop/layer_shell.c
parentinput/cursor: unhide cursor on synthetic input (diff)
downloadsway-71725a8eae6f8196d8e13a1b50af4f8ee4ebe971.tar.gz
sway-71725a8eae6f8196d8e13a1b50af4f8ee4ebe971.tar.zst
sway-71725a8eae6f8196d8e13a1b50af4f8ee4ebe971.zip
Add layer shell subsurfaces
Damage subsurfaces created by layer surfaces on map, unmap and commit. This fixes the flicker of Gtk Popovers. Fixes #5617
Diffstat (limited to 'sway/desktop/layer_shell.c')
-rw-r--r--sway/desktop/layer_shell.c80
1 files changed, 80 insertions, 0 deletions
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
384static 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
398static 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
404static 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
410static 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
416static 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
428static 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
452static 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
383static struct sway_layer_surface *popup_get_layer( 460static 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;