Commit eb17ee1c authored by Olivier Fourdan's avatar Olivier Fourdan 🛠
Browse files

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
parent 50595cc6
......@@ -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);
}
......@@ -2329,6 +2331,28 @@ unmap_subsurface (GdkWindow *window)
impl->display_server.wl_subsurface = NULL;
}
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)
{
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment