133 lines
4.5 KiB
Diff
133 lines
4.5 KiB
Diff
Upstream: yes
|
|
Source: https://github.com/swaywm/sway/pull/6046
|
|
Reason: Popup menu flickers on Firefox
|
|
(https://bugzilla.mozilla.org/show_bug.cgi?id=1696662)
|
|
|
|
From cf03185561e919f1c337f087194fec150425eef5 Mon Sep 17 00:00:00 2001
|
|
From: Kenny Levinsen <kl@kl.wtf>
|
|
Date: Fri, 19 Feb 2021 18:39:54 +0100
|
|
Subject: [PATCH 1/3] view: Recursively check mapped of view_child tree
|
|
|
|
A subsurface may be set to mapped without its parent.
|
|
---
|
|
sway/tree/view.c | 14 ++++++++++++--
|
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/sway/tree/view.c b/sway/tree/view.c
|
|
index ad79b2294..c8a4ea6b6 100644
|
|
--- a/sway/tree/view.c
|
|
+++ b/sway/tree/view.c
|
|
@@ -982,8 +982,18 @@ static void view_child_subsurface_create(struct sway_view_child *child,
|
|
view_child_damage(&subsurface->child, true);
|
|
}
|
|
|
|
+static bool view_child_is_mapped(struct sway_view_child *child) {
|
|
+ while (child) {
|
|
+ if (!child->mapped) {
|
|
+ return false;
|
|
+ }
|
|
+ child = child->parent;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
static void view_child_damage(struct sway_view_child *child, bool whole) {
|
|
- if (!child || !child->mapped || !child->view || !child->view->container) {
|
|
+ if (!child || !view_child_is_mapped(child) || !child->view || !child->view->container) {
|
|
return;
|
|
}
|
|
int sx, sy;
|
|
@@ -1082,7 +1092,7 @@ void view_child_init(struct sway_view_child *child,
|
|
}
|
|
|
|
void view_child_destroy(struct sway_view_child *child) {
|
|
- if (child->mapped && child->view->container != NULL) {
|
|
+ if (view_child_is_mapped(child) && child->view->container != NULL) {
|
|
view_child_damage(child, true);
|
|
}
|
|
|
|
|
|
From e2ec65d0a32797edd0846758bc24cf685e2d19d5 Mon Sep 17 00:00:00 2001
|
|
From: Kenny Levinsen <kl@kl.wtf>
|
|
Date: Fri, 19 Feb 2021 18:41:04 +0100
|
|
Subject: [PATCH 2/3] view: Mark subchildren as unmapped in view_child_destroy
|
|
|
|
The subchildren lose their parent association at this point, so they
|
|
will not be able to see that the parent is unmapped.
|
|
|
|
Instead, just set the subchildren to be unmapped directly.
|
|
---
|
|
sway/tree/view.c | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
diff --git a/sway/tree/view.c b/sway/tree/view.c
|
|
index c8a4ea6b6..978271c24 100644
|
|
--- a/sway/tree/view.c
|
|
+++ b/sway/tree/view.c
|
|
@@ -1105,6 +1105,9 @@ void view_child_destroy(struct sway_view_child *child) {
|
|
wl_list_for_each_safe(subchild, tmpchild, &child->children, link) {
|
|
wl_list_remove(&subchild->link);
|
|
subchild->parent = NULL;
|
|
+ // The subchild lost its parent link, so it cannot see that the parent
|
|
+ // is unmapped. Unmap it directly.
|
|
+ subchild->mapped = false;
|
|
}
|
|
|
|
wl_list_remove(&child->surface_commit.link);
|
|
|
|
From c06a926e0d89e952e5a3892b63f07d5b802b34ef Mon Sep 17 00:00:00 2001
|
|
From: Kenny Levinsen <kl@kl.wtf>
|
|
Date: Fri, 19 Feb 2021 18:33:20 +0100
|
|
Subject: [PATCH 3/3] view: Set parent for view_child subsurfaces on init
|
|
|
|
view_child_init was calling view_init_subsurfaces, which did not set the
|
|
parent attribute for the subchildren. This lead to the subchildren
|
|
acting as standalone children. If the parent was an xdg_popup, this
|
|
would make the subchild unaware of the popup position.
|
|
|
|
Introduce view_child_init_subsurfaces for view_child_init to use
|
|
instead.
|
|
|
|
Closes: https://github.com/swaywm/sway/issues/6038
|
|
---
|
|
sway/tree/view.c | 13 ++++++++++++-
|
|
1 file changed, 12 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/sway/tree/view.c b/sway/tree/view.c
|
|
index 978271c24..8a2a8178d 100644
|
|
--- a/sway/tree/view.c
|
|
+++ b/sway/tree/view.c
|
|
@@ -465,6 +465,9 @@ static void view_subsurface_create(struct sway_view *view,
|
|
static void view_init_subsurfaces(struct sway_view *view,
|
|
struct wlr_surface *surface);
|
|
|
|
+static void view_child_init_subsurfaces(struct sway_view_child *view_child,
|
|
+ struct wlr_surface *surface);
|
|
+
|
|
static void view_handle_surface_new_subsurface(struct wl_listener *listener,
|
|
void *data) {
|
|
struct sway_view *view =
|
|
@@ -1033,6 +1036,14 @@ static void view_init_subsurfaces(struct sway_view *view,
|
|
}
|
|
}
|
|
|
|
+static void view_child_init_subsurfaces(struct sway_view_child *view_child,
|
|
+ struct wlr_surface *surface) {
|
|
+ struct wlr_subsurface *subsurface;
|
|
+ wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) {
|
|
+ view_child_subsurface_create(view_child, subsurface);
|
|
+ }
|
|
+}
|
|
+
|
|
static void view_child_handle_surface_map(struct wl_listener *listener,
|
|
void *data) {
|
|
struct sway_view_child *child =
|
|
@@ -1088,7 +1099,7 @@ void view_child_init(struct sway_view_child *child,
|
|
wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
|
|
}
|
|
|
|
- view_init_subsurfaces(child->view, surface);
|
|
+ view_child_init_subsurfaces(child, surface);
|
|
}
|
|
|
|
void view_child_destroy(struct sway_view_child *child) {
|