wayland/xdg-shell: Send xdg_popup.popup_done when position invalid
A client may provide a positioner that places the window outside of its parent. This isn't allowed, according to spec, so we hide the window and log a warning. This, however, leads these affected clients with an incorrect view of what is mapped or not, meaning it becomes harder to recover. Fix this by sending xdg_popup.done when we hide the popup due to an invalid position. Don't error out the client, let the bug slide, as that's a less jarring experience for existing applications that reproduce this than being disconnected, which practically feels like a crash. Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2408 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2645>
This commit is contained in:
parent
cc19547b8c
commit
ac093dc651
1 changed files with 38 additions and 1 deletions
|
@ -184,6 +184,12 @@ surface_from_xdg_toplevel_resource (struct wl_resource *resource)
|
|||
return surface_from_xdg_surface_resource (resource);
|
||||
}
|
||||
|
||||
static MetaWaylandXdgPopup *
|
||||
meta_wayland_xdg_popup_from_surface (MetaWaylandSurface *surface)
|
||||
{
|
||||
return META_WAYLAND_XDG_POPUP (surface->role);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_surface_reset (MetaWaylandXdgSurface *xdg_surface)
|
||||
{
|
||||
|
@ -1131,6 +1137,37 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dismiss_invalid_popup (MetaWaylandXdgPopup *xdg_popup)
|
||||
{
|
||||
if (xdg_popup->popup)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
MetaWaylandSurface *top_popup_surface;
|
||||
MetaWaylandXdgPopup *top_xdg_popup;
|
||||
|
||||
top_popup_surface =
|
||||
meta_wayland_popup_get_top_popup (xdg_popup->popup);
|
||||
if (!top_popup_surface)
|
||||
break;
|
||||
|
||||
top_xdg_popup = meta_wayland_xdg_popup_from_surface (top_popup_surface);
|
||||
|
||||
xdg_popup_send_popup_done (top_xdg_popup->resource);
|
||||
meta_wayland_popup_destroy (top_xdg_popup->popup);
|
||||
|
||||
if (top_xdg_popup == xdg_popup)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xdg_popup_send_popup_done (xdg_popup->resource);
|
||||
meta_wayland_xdg_popup_unmap (xdg_popup);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
|
@ -1211,7 +1248,7 @@ meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
{
|
||||
g_warning ("Buggy client caused popup to be placed outside of "
|
||||
"parent window");
|
||||
dismiss_popup (xdg_popup);
|
||||
dismiss_invalid_popup (xdg_popup);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue