MetaWaylandSurface: Return top most toplevel window for popups

Make meta_wayland_surface_get_toplevel_window return the top most window
in case its a chain of popups. This is to make all popups in a chain
including the top most surface have the same scale.

The reason for this is that popups are mostly integrated part of the
user interface of its parent (such as menus). Having them in a different
scale would look awkward.

Note that this doesn't affect non-popup windows with parent-child
relationship, because such windows are typically not an integral part of
the user interface (settings window, dialogs, ..) and can typically be
moved independently. It would probably make sense to make attached modal
dialogs have the same scale as their parent windows, but modal dialogs
are currently not supported for Wayland clients.

https://bugzilla.gnome.org/show_bug.cgi?id=744934
This commit is contained in:
Jonas Ådahl 2015-03-24 17:23:13 +08:00
parent f6c9261bf6
commit fbd237bc66

View File

@ -1587,6 +1587,17 @@ wl_shell_surface_set_fullscreen (struct wl_client *client,
wl_shell_surface_set_state (surface, SURFACE_STATE_FULLSCREEN);
}
static void
handle_wl_shell_popup_parent_destroyed (struct wl_listener *listener,
void *data)
{
MetaWaylandSurface *surface =
wl_container_of (listener, surface, popup.parent_destroy_listener);
wl_list_remove (&surface->popup.parent_destroy_listener.link);
surface->popup.parent = NULL;
}
static void
wl_shell_surface_set_popup (struct wl_client *client,
struct wl_resource *resource,
@ -1615,6 +1626,15 @@ wl_shell_surface_set_popup (struct wl_client *client,
parent_surf->window->rect.y + y);
surface->window->placed = TRUE;
if (!surface->popup.parent)
{
surface->popup.parent = parent_surf;
surface->popup.parent_destroy_listener.notify =
handle_wl_shell_popup_parent_destroyed;
wl_resource_add_destroy_listener (parent_surf->resource,
&surface->popup.parent_destroy_listener);
}
meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
}
@ -2229,9 +2249,14 @@ meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
while (surface)
{
if (surface->window)
return surface->window;
surface = surface->sub.parent;
{
if (surface->popup.parent)
surface = surface->popup.parent;
else
return surface->window;
}
else
surface = surface->sub.parent;
}
return NULL;