diff options
author | 2018-10-06 14:49:33 +1000 | |
---|---|---|
committer | 2018-10-07 11:07:29 +1000 | |
commit | 1059e173f4c0139e909c7d8b5d450f30c0adad0e (patch) | |
tree | f14474b2d5118151129593443e5f8f785c3f6ab0 /sway | |
parent | Merge pull request #2778 from emersion/swaybar-seat-pointer (diff) | |
download | sway-1059e173f4c0139e909c7d8b5d450f30c0adad0e.tar.gz sway-1059e173f4c0139e909c7d8b5d450f30c0adad0e.tar.zst sway-1059e173f4c0139e909c7d8b5d450f30c0adad0e.zip |
Only damage popups when popups have damage
The previous behaviour was to damage the entire view, which would
recurse into each popup. This patch makes it damage only the popup's
surface, and respect the surface damage given by the client.
This adds listeners to the popup's map and unmap events rather than
doing the damage in the create and destroy functions. To get the popup's
position relative to the view, a new child_impl function get_root_coords
has been introduced, which traverses up the parents.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/desktop/xdg_shell.c | 17 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 17 | ||||
-rw-r--r-- | sway/tree/view.c | 35 |
3 files changed, 61 insertions, 8 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index a8b527a7..9036448b 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -20,6 +20,19 @@ | |||
20 | 20 | ||
21 | static const struct sway_view_child_impl popup_impl; | 21 | static const struct sway_view_child_impl popup_impl; |
22 | 22 | ||
23 | static void popup_get_root_coords(struct sway_view_child *child, | ||
24 | int *root_sx, int *root_sy) { | ||
25 | struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child; | ||
26 | struct wlr_xdg_surface *surface = popup->wlr_xdg_surface; | ||
27 | *root_sx = -surface->geometry.x; | ||
28 | *root_sy = -surface->geometry.y; | ||
29 | while (surface && surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
30 | *root_sx += surface->popup->geometry.x; | ||
31 | *root_sy += surface->popup->geometry.y; | ||
32 | surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent); | ||
33 | } | ||
34 | } | ||
35 | |||
23 | static void popup_destroy(struct sway_view_child *child) { | 36 | static void popup_destroy(struct sway_view_child *child) { |
24 | if (!sway_assert(child->impl == &popup_impl, | 37 | if (!sway_assert(child->impl == &popup_impl, |
25 | "Expected an xdg_shell popup")) { | 38 | "Expected an xdg_shell popup")) { |
@@ -32,6 +45,7 @@ static void popup_destroy(struct sway_view_child *child) { | |||
32 | } | 45 | } |
33 | 46 | ||
34 | static const struct sway_view_child_impl popup_impl = { | 47 | static const struct sway_view_child_impl popup_impl = { |
48 | .get_root_coords = popup_get_root_coords, | ||
35 | .destroy = popup_destroy, | 49 | .destroy = popup_destroy, |
36 | }; | 50 | }; |
37 | 51 | ||
@@ -85,6 +99,9 @@ static struct sway_xdg_popup *popup_create( | |||
85 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 99 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); |
86 | popup->destroy.notify = popup_handle_destroy; | 100 | popup->destroy.notify = popup_handle_destroy; |
87 | 101 | ||
102 | wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map); | ||
103 | wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap); | ||
104 | |||
88 | popup_unconstrain(popup); | 105 | popup_unconstrain(popup); |
89 | 106 | ||
90 | return popup; | 107 | return popup; |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index a7838c0f..765a80b1 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -19,6 +19,19 @@ | |||
19 | 19 | ||
20 | static const struct sway_view_child_impl popup_impl; | 20 | static const struct sway_view_child_impl popup_impl; |
21 | 21 | ||
22 | static void popup_get_root_coords(struct sway_view_child *child, | ||
23 | int *root_sx, int *root_sy) { | ||
24 | struct sway_xdg_popup_v6 *popup = (struct sway_xdg_popup_v6 *)child; | ||
25 | struct wlr_xdg_surface_v6 *surface = popup->wlr_xdg_surface_v6; | ||
26 | *root_sx = -surface->geometry.x; | ||
27 | *root_sy = -surface->geometry.y; | ||
28 | while (surface && surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||
29 | *root_sx += surface->popup->geometry.x; | ||
30 | *root_sy += surface->popup->geometry.y; | ||
31 | surface = surface->popup->parent; | ||
32 | } | ||
33 | } | ||
34 | |||
22 | static void popup_destroy(struct sway_view_child *child) { | 35 | static void popup_destroy(struct sway_view_child *child) { |
23 | if (!sway_assert(child->impl == &popup_impl, | 36 | if (!sway_assert(child->impl == &popup_impl, |
24 | "Expected an xdg_shell_v6 popup")) { | 37 | "Expected an xdg_shell_v6 popup")) { |
@@ -31,6 +44,7 @@ static void popup_destroy(struct sway_view_child *child) { | |||
31 | } | 44 | } |
32 | 45 | ||
33 | static const struct sway_view_child_impl popup_impl = { | 46 | static const struct sway_view_child_impl popup_impl = { |
47 | .get_root_coords = popup_get_root_coords, | ||
34 | .destroy = popup_destroy, | 48 | .destroy = popup_destroy, |
35 | }; | 49 | }; |
36 | 50 | ||
@@ -84,6 +98,9 @@ static struct sway_xdg_popup_v6 *popup_create( | |||
84 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 98 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); |
85 | popup->destroy.notify = popup_handle_destroy; | 99 | popup->destroy.notify = popup_handle_destroy; |
86 | 100 | ||
101 | wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map); | ||
102 | wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap); | ||
103 | |||
87 | popup_unconstrain(popup); | 104 | popup_unconstrain(popup); |
88 | 105 | ||
89 | return popup; | 106 | return popup; |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 73ce55ac..50d25c4f 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "log.h" | 15 | #include "log.h" |
16 | #include "sway/criteria.h" | 16 | #include "sway/criteria.h" |
17 | #include "sway/commands.h" | 17 | #include "sway/commands.h" |
18 | #include "sway/desktop.h" | ||
18 | #include "sway/desktop/transaction.h" | 19 | #include "sway/desktop/transaction.h" |
19 | #include "sway/input/cursor.h" | 20 | #include "sway/input/cursor.h" |
20 | #include "sway/ipc-server.h" | 21 | #include "sway/ipc-server.h" |
@@ -639,12 +640,18 @@ static void view_subsurface_create(struct sway_view *view, | |||
639 | view_child_init(child, NULL, view, subsurface->surface); | 640 | view_child_init(child, NULL, view, subsurface->surface); |
640 | } | 641 | } |
641 | 642 | ||
643 | static void view_child_damage(struct sway_view_child *child, bool whole) { | ||
644 | int sx, sy; | ||
645 | child->impl->get_root_coords(child, &sx, &sy); | ||
646 | desktop_damage_surface(child->surface, | ||
647 | child->view->x + sx, child->view->y + sy, whole); | ||
648 | } | ||
649 | |||
642 | static void view_child_handle_surface_commit(struct wl_listener *listener, | 650 | static void view_child_handle_surface_commit(struct wl_listener *listener, |
643 | void *data) { | 651 | void *data) { |
644 | struct sway_view_child *child = | 652 | struct sway_view_child *child = |
645 | wl_container_of(listener, child, surface_commit); | 653 | wl_container_of(listener, child, surface_commit); |
646 | // TODO: only accumulate damage from the child | 654 | view_child_damage(child, false); |
647 | view_damage_from(child->view); | ||
648 | } | 655 | } |
649 | 656 | ||
650 | static void view_child_handle_surface_new_subsurface( | 657 | static void view_child_handle_surface_new_subsurface( |
@@ -677,6 +684,20 @@ static void view_init_subsurfaces(struct sway_view *view, | |||
677 | } | 684 | } |
678 | } | 685 | } |
679 | 686 | ||
687 | static void view_child_handle_surface_map(struct wl_listener *listener, | ||
688 | void *data) { | ||
689 | struct sway_view_child *child = | ||
690 | wl_container_of(listener, child, surface_map); | ||
691 | view_child_damage(child, true); | ||
692 | } | ||
693 | |||
694 | static void view_child_handle_surface_unmap(struct wl_listener *listener, | ||
695 | void *data) { | ||
696 | struct sway_view_child *child = | ||
697 | wl_container_of(listener, child, surface_unmap); | ||
698 | view_child_damage(child, true); | ||
699 | } | ||
700 | |||
680 | void view_child_init(struct sway_view_child *child, | 701 | void view_child_init(struct sway_view_child *child, |
681 | const struct sway_view_child_impl *impl, struct sway_view *view, | 702 | const struct sway_view_child_impl *impl, struct sway_view *view, |
682 | struct wlr_surface *surface) { | 703 | struct wlr_surface *surface) { |
@@ -692,6 +713,10 @@ void view_child_init(struct sway_view_child *child, | |||
692 | view_child_handle_surface_new_subsurface; | 713 | view_child_handle_surface_new_subsurface; |
693 | wl_signal_add(&surface->events.destroy, &child->surface_destroy); | 714 | wl_signal_add(&surface->events.destroy, &child->surface_destroy); |
694 | child->surface_destroy.notify = view_child_handle_surface_destroy; | 715 | child->surface_destroy.notify = view_child_handle_surface_destroy; |
716 | |||
717 | child->surface_map.notify = view_child_handle_surface_map; | ||
718 | child->surface_unmap.notify = view_child_handle_surface_unmap; | ||
719 | |||
695 | wl_signal_add(&view->events.unmap, &child->view_unmap); | 720 | wl_signal_add(&view->events.unmap, &child->view_unmap); |
696 | child->view_unmap.notify = view_child_handle_view_unmap; | 721 | child->view_unmap.notify = view_child_handle_view_unmap; |
697 | 722 | ||
@@ -699,15 +724,9 @@ void view_child_init(struct sway_view_child *child, | |||
699 | wlr_surface_send_enter(child->surface, output->wlr_output); | 724 | wlr_surface_send_enter(child->surface, output->wlr_output); |
700 | 725 | ||
701 | view_init_subsurfaces(child->view, surface); | 726 | view_init_subsurfaces(child->view, surface); |
702 | |||
703 | // TODO: only damage the whole child | ||
704 | container_damage_whole(child->view->container); | ||
705 | } | 727 | } |
706 | 728 | ||
707 | void view_child_destroy(struct sway_view_child *child) { | 729 | void view_child_destroy(struct sway_view_child *child) { |
708 | // TODO: only damage the whole child | ||
709 | container_damage_whole(child->view->container); | ||
710 | |||
711 | wl_list_remove(&child->surface_commit.link); | 730 | wl_list_remove(&child->surface_commit.link); |
712 | wl_list_remove(&child->surface_destroy.link); | 731 | wl_list_remove(&child->surface_destroy.link); |
713 | wl_list_remove(&child->view_unmap.link); | 732 | wl_list_remove(&child->view_unmap.link); |