summaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-06 14:49:33 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-07 11:07:29 +1000
commit1059e173f4c0139e909c7d8b5d450f30c0adad0e (patch)
treef14474b2d5118151129593443e5f8f785c3f6ab0 /sway
parentMerge pull request #2778 from emersion/swaybar-seat-pointer (diff)
downloadsway-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.c17
-rw-r--r--sway/desktop/xdg_shell_v6.c17
-rw-r--r--sway/tree/view.c35
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
21static const struct sway_view_child_impl popup_impl; 21static const struct sway_view_child_impl popup_impl;
22 22
23static 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
23static void popup_destroy(struct sway_view_child *child) { 36static 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
34static const struct sway_view_child_impl popup_impl = { 47static 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
20static const struct sway_view_child_impl popup_impl; 20static const struct sway_view_child_impl popup_impl;
21 21
22static 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
22static void popup_destroy(struct sway_view_child *child) { 35static 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
33static const struct sway_view_child_impl popup_impl = { 46static 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
643static 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
642static void view_child_handle_surface_commit(struct wl_listener *listener, 650static 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
650static void view_child_handle_surface_new_subsurface( 657static 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
687static 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
694static 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
680void view_child_init(struct sway_view_child *child, 701void 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
707void view_child_destroy(struct sway_view_child *child) { 729void 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);