From aa72318581e108789848fcb3304b7291fccaebb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 18 Apr 2020 22:33:29 +0200 Subject: [PATCH 1/3] popover: Fix indentation --- gtk/gtkpopover.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index 11dd3f273b..4a2893b324 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -550,9 +550,9 @@ present_popup (GtkPopover *popover) layout = create_popup_layout (popover); gtk_widget_get_preferred_size (GTK_WIDGET (popover), NULL, &req); if (gdk_popup_present (GDK_POPUP (priv->surface), - MAX (req.width, 1), - MAX (req.height, 1), - layout)) + MAX (req.width, 1), + MAX (req.height, 1), + layout)) update_popover_layout (popover, layout); } From 0a79eb02acc1041704b26a0b1483cb8e4574c22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 18 Apr 2020 22:33:52 +0200 Subject: [PATCH 2/3] surface: Hide chained autohiding popups together When we autohide a popup surface with a grab, hide all other auto hiding popups up the popup chain. The end result is that when you click outside a menu with submenus open, the whole menu chain is dismissed. --- gdk/gdksurface.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c index 9f26ff828d..6c8195523b 100644 --- a/gdk/gdksurface.c +++ b/gdk/gdksurface.c @@ -2783,6 +2783,18 @@ gdk_synthesize_surface_state (GdkSurface *surface, gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags); } +static void +hide_popup_chain (GdkSurface *surface) +{ + GdkSurface *parent; + + gdk_surface_hide (surface); + + parent = surface->parent; + if (parent->autohide) + hide_popup_chain (parent); +} + static gboolean check_autohide (GdkEvent *event) { @@ -2812,7 +2824,7 @@ check_autohide (GdkEvent *event) if (grab_surface != gdk_event_get_surface (event) && grab_surface->autohide) { - gdk_surface_hide (grab_surface); + hide_popup_chain (grab_surface); return TRUE; } } From ab59459f7a93149fb05b6c1660317a8eddd2a526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 18 Apr 2020 22:51:21 +0200 Subject: [PATCH 3/3] wayland: Don't continue showing if xdg_popup creation failed We don't create a grabbing popup if it's not the top most one, as that is a protocol violation, and complain if anything attempts to do it. What we didn't do is handle this gracefully in the code that tries to create said popup. Fix this by dropping the attempt to show the popup on the floor, instead of setting various state making it look like it succeeded. This won't actually fix anything, but it'll result in a bit more accurate warnings logged, as the state more correctly corresponds to the reality. --- gdk/wayland/gdksurface-wayland.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 5b6c08a5fe..c644608031 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2334,7 +2334,7 @@ can_map_grabbing_popup (GdkSurface *surface, return top_most_popup == parent; } -static void +static gboolean gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, GdkSurface *parent, GdkWaylandSeat *grab_input_seat, @@ -2348,27 +2348,27 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, gpointer positioner; if (!impl->display_server.wl_surface) - return; + return FALSE; if (!is_realized_shell_surface (parent)) - return; + return FALSE; if (is_realized_toplevel (surface)) { g_warning ("Can't map popup, already mapped as toplevel"); - return; + return FALSE; } if (is_realized_popup (surface)) { g_warning ("Can't map popup, already mapped"); - return; + return FALSE; } if (grab_input_seat && !can_map_grabbing_popup (surface, parent)) { g_warning ("Tried to map a grabbing popup with a non-top most parent"); - return; + return FALSE; } gdk_surface_freeze_updates (surface); @@ -2453,6 +2453,8 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, display->current_grabbing_popups = g_list_prepend (display->current_grabbing_popups, surface); } + + return TRUE; } static GdkWaylandSeat * @@ -2827,11 +2829,13 @@ gdk_wayland_surface_map_popup (GdkSurface *surface, grab_input_seat = find_grab_input_seat (surface, parent); else grab_input_seat = NULL; - gdk_wayland_surface_create_xdg_popup (surface, - parent, - grab_input_seat, - width, height, - layout); + + if (!gdk_wayland_surface_create_xdg_popup (surface, + parent, + grab_input_seat, + width, height, + layout)) + return; impl->popup.layout = gdk_popup_layout_copy (layout); impl->popup.unconstrained_width = width;