diff options
-rw-r--r-- | include/sway/tree/view.h | 3 | ||||
-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 |
4 files changed, 64 insertions, 8 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 028be536..eed3d13d 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -206,6 +206,7 @@ struct sway_xwayland_unmanaged { | |||
206 | struct sway_view_child; | 206 | struct sway_view_child; |
207 | 207 | ||
208 | struct sway_view_child_impl { | 208 | struct sway_view_child_impl { |
209 | void (*get_root_coords)(struct sway_view_child *child, int *sx, int *sy); | ||
209 | void (*destroy)(struct sway_view_child *child); | 210 | void (*destroy)(struct sway_view_child *child); |
210 | }; | 211 | }; |
211 | 212 | ||
@@ -220,6 +221,8 @@ struct sway_view_child { | |||
220 | 221 | ||
221 | struct wl_listener surface_commit; | 222 | struct wl_listener surface_commit; |
222 | struct wl_listener surface_new_subsurface; | 223 | struct wl_listener surface_new_subsurface; |
224 | struct wl_listener surface_map; | ||
225 | struct wl_listener surface_unmap; | ||
223 | struct wl_listener surface_destroy; | 226 | struct wl_listener surface_destroy; |
224 | struct wl_listener view_unmap; | 227 | struct wl_listener view_unmap; |
225 | }; | 228 | }; |
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); |