[gtk: 12/16] wayland: Fix top-most-popup check
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 12/16] wayland: Fix top-most-popup check
- Date: Wed, 19 Feb 2020 18:59:03 +0000 (UTC)
commit 11dbc384abea77fba55a40bf06d4176ce19eaa3d
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Sun Feb 16 16:24:12 2020 +0100
wayland: Fix top-most-popup check
We can map a non-grabbing popup wherever, it's just the grabbing
popup-chain that needs to be ensured not to break any ordering rules.
Fix this by managing two lists; one of open popups, and another for
grabbing ones.
gdk/wayland/gdkdisplay-wayland.h | 1 +
gdk/wayland/gdksurface-wayland.c | 32 +++++++++++++++++++++++++++-----
2 files changed, 28 insertions(+), 5 deletions(-)
---
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 1da3e36fe8..aa5797a331 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -127,6 +127,7 @@ struct _GdkWaylandDisplay
GList *orphan_dialogs;
GList *current_popups;
+ GList *current_grabbing_popups;
struct wl_cursor_theme *cursor_theme;
gchar *cursor_theme_name;
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index c29331441d..267943799e 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -2184,6 +2184,21 @@ create_dynamic_positioner (GdkSurface *surface)
g_assert_not_reached ();
}
+static gboolean
+can_map_grabbing_popup (GdkSurface *surface,
+ GdkSurface *parent)
+{
+ GdkDisplay *display = gdk_surface_get_display (surface);
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
+ GdkSurface *top_most_popup;
+
+ if (!display_wayland->current_grabbing_popups)
+ return TRUE;
+
+ top_most_popup = g_list_first (display_wayland->current_grabbing_popups)->data;
+ return top_most_popup == parent;
+}
+
static void
gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
GdkSurface *parent,
@@ -2210,13 +2225,11 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
g_warning ("Can't map popup, already mapped");
return;
}
+
if (grab_input_seat &&
- ((display->current_popups &&
- g_list_last (display->current_popups)->data != parent) ||
- (!display->current_popups &&
- !is_realized_toplevel (parent))))
+ !can_map_grabbing_popup (surface, parent))
{
- g_warning ("Tried to map a popup with a non-top most parent");
+ g_warning ("Tried to map a grabbing popup with a non-top most parent");
return;
}
@@ -2291,6 +2304,11 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
impl->popup_parent = parent;
display->current_popups = g_list_append (display->current_popups, surface);
+ if (grab_input_seat)
+ {
+ display->current_grabbing_popups =
+ g_list_prepend (display->current_grabbing_popups, surface);
+ }
}
static GdkWaylandSeat *
@@ -2490,6 +2508,8 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
impl->display_server.xdg_popup = NULL;
display_wayland->current_popups =
g_list_remove (display_wayland->current_popups, surface);
+ display_wayland->current_grabbing_popups =
+ g_list_remove (display_wayland->current_grabbing_popups, surface);
}
if (impl->display_server.xdg_surface)
{
@@ -2512,6 +2532,8 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
impl->display_server.zxdg_popup_v6 = NULL;
display_wayland->current_popups =
g_list_remove (display_wayland->current_popups, surface);
+ display_wayland->current_grabbing_popups =
+ g_list_remove (display_wayland->current_grabbing_popups, surface);
}
if (impl->display_server.zxdg_surface_v6)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]