[gtk+] wayland: unmap popup along with its toplevel
- From: Olivier Fourdan <ofourdan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: unmap popup along with its toplevel
- Date: Mon, 12 Sep 2016 08:05:03 +0000 (UTC)
commit eb17ee1c26bb5faf08d50264dbe5fcfc79e0666c
Author: Olivier Fourdan <ofourdan redhat com>
Date: Mon Sep 5 17:53:38 2016 +0200
wayland: unmap popup along with its toplevel
If an application umaps the toplevel from its popup callback, this can
lead to a protocol error.
Make sure we mark popup parent and use that to check if their parent is
the toplevel being unmapped in which case we shall unmap the popup first
to avoid the protocol error.
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=770906
gdk/wayland/gdkwindow-wayland.c | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index ccd3bc4..be9bf98 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -132,6 +132,7 @@ struct _GdkWindowImplWayland
unsigned int awaiting_frame : 1;
GdkWindowTypeHint hint;
GdkWindow *transient_for;
+ GdkWindow *popup_parent;
PositionMethod position_method;
cairo_surface_t *staging_cairo_surface;
@@ -2009,6 +2010,7 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window,
wl_surface_commit (impl->display_server.wl_surface);
+ impl->popup_parent = parent;
display->current_popups = g_list_append (display->current_popups, window);
}
@@ -2330,6 +2332,28 @@ unmap_subsurface (GdkWindow *window)
}
static void
+unmap_popups_for_window (GdkWindow *window)
+{
+ GdkWaylandDisplay *display_wayland;
+ GList *l;
+
+ display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+ for (l = display_wayland->current_popups; l; l = l->next)
+ {
+ GdkWindow *popup = l->data;
+ GdkWindowImplWayland *popup_impl = GDK_WINDOW_IMPL_WAYLAND (popup->impl);
+
+ if (popup_impl->popup_parent == window)
+ {
+ g_warning ("Tried to unmap the parent of a popup");
+ gdk_window_hide (popup);
+
+ return;
+ }
+ }
+}
+
+static void
gdk_wayland_window_hide_surface (GdkWindow *window)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
@@ -2337,6 +2361,8 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
unset_transient_for_exported (window);
+ unmap_popups_for_window (window);
+
if (impl->display_server.wl_surface)
{
if (impl->dummy_egl_surface)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]