Skip to content

Commit 2b0e18c

Browse files
Sunderland93mtwebster
authored andcommitted
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.
1 parent 830364e commit 2b0e18c

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

src/wayland/meta-wayland-xdg-shell.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ surface_from_xdg_toplevel_resource (struct wl_resource *resource)
185185
return surface_from_xdg_surface_resource (resource);
186186
}
187187

188+
static MetaWaylandXdgPopup *
189+
meta_wayland_xdg_popup_from_surface (MetaWaylandSurface *surface)
190+
{
191+
return META_WAYLAND_XDG_POPUP (surface->role);
192+
}
193+
188194
static void
189195
meta_wayland_xdg_surface_reset (MetaWaylandXdgSurface *xdg_surface)
190196
{
@@ -1129,6 +1135,37 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
11291135
}
11301136
}
11311137

1138+
static void
1139+
dismiss_invalid_popup (MetaWaylandXdgPopup *xdg_popup)
1140+
{
1141+
if (xdg_popup->popup)
1142+
{
1143+
while (TRUE)
1144+
{
1145+
MetaWaylandSurface *top_popup_surface;
1146+
MetaWaylandXdgPopup *top_xdg_popup;
1147+
1148+
top_popup_surface =
1149+
meta_wayland_popup_get_top_popup (xdg_popup->popup);
1150+
if (!top_popup_surface)
1151+
break;
1152+
1153+
top_xdg_popup = meta_wayland_xdg_popup_from_surface (top_popup_surface);
1154+
1155+
xdg_popup_send_popup_done (top_xdg_popup->resource);
1156+
meta_wayland_popup_destroy (top_xdg_popup->popup);
1157+
1158+
if (top_xdg_popup == xdg_popup)
1159+
break;
1160+
}
1161+
}
1162+
else
1163+
{
1164+
xdg_popup_send_popup_done (xdg_popup->resource);
1165+
meta_wayland_xdg_popup_unmap (xdg_popup);
1166+
}
1167+
}
1168+
11321169
static void
11331170
meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
11341171
MetaWaylandSurfaceState *pending)
@@ -1209,7 +1246,7 @@ meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role,
12091246
{
12101247
g_warning ("Buggy client caused popup to be placed outside of "
12111248
"parent window");
1212-
dismiss_popup (xdg_popup);
1249+
dismiss_invalid_popup (xdg_popup);
12131250
}
12141251
}
12151252

0 commit comments

Comments
 (0)