From 98b0f78200d8808384e631f286aae09686f97d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 2 Sep 2016 18:51:34 +0800 Subject: [PATCH] wayland: Warn when an application tries to map popup incorrectly When a popup is mapped but will not be the top most popup (for example the parent is not the current top most popup, or if there already is a popup mapped but the parent is a toplevel), warn and ignore it instead of continuing, as continuing would be a protocol violation. https://bugzilla.gnome.org/show_bug.cgi?id=770745 --- gdk/wayland/gdkdisplay-wayland.h | 2 ++ gdk/wayland/gdkwindow-wayland.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index ace514349d..a68940f5b8 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -90,6 +90,8 @@ struct _GdkWaylandDisplay /* Keep a list of orphaned dialogs (i.e. without parent) */ GList *orphan_dialogs; + GList *current_popups; + struct wl_cursor_theme *scaled_cursor_themes[GDK_WAYLAND_THEME_SCALES_COUNT]; gchar *cursor_theme_name; int cursor_theme_size; diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 98d666dd71..ccd3bc4f32 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -1971,6 +1971,14 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window, g_warning ("Can't map popup, already mapped"); return; } + if ((display->current_popups && + g_list_last (display->current_popups)->data != parent) || + (!display->current_popups && + !parent_impl->display_server.xdg_toplevel)) + { + g_warning ("Tried to map a popup with a non-top most parent"); + return; + } impl->display_server.xdg_surface = zxdg_shell_v6_get_xdg_surface (display->xdg_shell, @@ -2000,6 +2008,8 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window, zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial); wl_surface_commit (impl->display_server.wl_surface); + + display->current_popups = g_list_append (display->current_popups, window); } static struct wl_seat * @@ -2362,6 +2372,8 @@ gdk_wayland_window_hide_surface (GdkWindow *window) { zxdg_popup_v6_destroy (impl->display_server.xdg_popup); impl->display_server.xdg_popup = NULL; + display_wayland->current_popups = + g_list_remove (display_wayland->current_popups, window); } if (impl->display_server.xdg_surface) {