wayland: Check transient loop

Gdk Wayland backend walks up the transient windows tree, but does not
check for cycles when doing so.

As a result, if two or more windows are transient to each other, the
Wayland gdk backend will enter an infinite loop.

While this is clearly a bug in the application, gtk+/gdk should be more
robust and handle such errors more gracefully.

To avoid looping infinitely at various point in the code, check for a
possible loop when setting the transient relationship and deny the
request to set a window transient for another if that would create a
loop.

Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759299
This commit is contained in:
Olivier Fourdan 2015-12-14 16:34:00 +01:00
parent 0b19197493
commit b456db8cf4

View File

@ -1943,12 +1943,33 @@ gdk_wayland_window_set_startup_id (GdkWindow *window,
{
}
static gboolean
check_transient_for_loop (GdkWindow *window,
GdkWindow *parent)
{
while (parent)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl);
if (impl->transient_for == window)
return TRUE;
parent = impl->transient_for;
}
return FALSE;
}
static void
gdk_wayland_window_set_transient_for (GdkWindow *window,
GdkWindow *parent)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (check_transient_for_loop (window, parent))
{
g_warning ("Setting %p transient for %p would create a loop", window, parent);
return;
}
if (impl->subsurface)
unmap_subsurface (window);