From fbd237bc66b745c4495b53b68e6124de8812f82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 24 Mar 2015 17:23:13 +0800 Subject: [PATCH] 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 --- src/wayland/meta-wayland-surface.c | 31 +++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index accec6a94..51bcf3817 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -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;