wayland: Tie XDG surfaces together with the Shell that created them

This means that we don't leak when a client binds an XdgShell for a
client more than once, and we send pings/pongs to the correct shell
interface.
This commit is contained in:
Jasper St. Pierre 2014-08-22 12:52:18 -04:00
parent 5657a671c1
commit 31f5a916f4
2 changed files with 11 additions and 52 deletions

View File

@ -1018,6 +1018,8 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
return; return;
} }
surface->xdg_shell_resource = resource;
window = meta_window_wayland_new (meta_get_display (), surface); window = meta_window_wayland_new (meta_get_display (), surface);
meta_wayland_surface_set_window (surface, window); meta_wayland_surface_set_window (surface, window);
} }
@ -1074,6 +1076,8 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
return; return;
} }
surface->xdg_shell_resource = resource;
window = meta_window_wayland_new (meta_get_display (), surface); window = meta_window_wayland_new (meta_get_display (), surface);
meta_window_move_frame (window, FALSE, meta_window_move_frame (window, FALSE,
parent_surf->window->rect.x + x, parent_surf->window->rect.x + x,
@ -1095,41 +1099,13 @@ static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = {
xdg_shell_pong, xdg_shell_pong,
}; };
typedef struct {
struct wl_resource *resource;
struct wl_listener client_destroy_listener;
} XdgShell;
static void
xdg_shell_handle_client_destroy (struct wl_listener *listener, void *data)
{
XdgShell *xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
g_slice_free (XdgShell, xdg_shell);
}
static struct wl_resource *
get_xdg_shell_for_client (struct wl_client *client)
{
struct wl_listener *listener;
XdgShell *xdg_shell;
listener = wl_client_get_destroy_listener (client, xdg_shell_handle_client_destroy);
/* No xdg_shell has been bound for this client */
if (listener == NULL)
return NULL;
xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
return xdg_shell->resource;
}
static void static void
bind_xdg_shell (struct wl_client *client, bind_xdg_shell (struct wl_client *client,
void *data, void *data,
guint32 version, guint32 version,
guint32 id) guint32 id)
{ {
XdgShell *xdg_shell; struct wl_resource *resource;
if (version != META_XDG_SHELL_VERSION) if (version != META_XDG_SHELL_VERSION)
{ {
@ -1137,13 +1113,8 @@ bind_xdg_shell (struct wl_client *client,
return; return;
} }
xdg_shell = g_slice_new (XdgShell); resource = wl_resource_create (client, &xdg_shell_interface, version, id);
wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL);
xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, version, id);
wl_resource_set_implementation (xdg_shell->resource, &meta_wayland_xdg_shell_interface, data, NULL);
xdg_shell->client_destroy_listener.notify = xdg_shell_handle_client_destroy;
wl_client_add_destroy_listener (client, &xdg_shell->client_destroy_listener);
} }
static void static void
@ -1856,23 +1827,10 @@ void
meta_wayland_surface_ping (MetaWaylandSurface *surface, meta_wayland_surface_ping (MetaWaylandSurface *surface,
guint32 serial) guint32 serial)
{ {
if (surface->xdg_surface.resource) if (surface->xdg_shell_resource)
{ xdg_shell_send_ping (surface->xdg_shell_resource, serial);
struct wl_client *client = wl_resource_get_client (surface->resource);
struct wl_resource *xdg_shell = get_xdg_shell_for_client (client);
if (xdg_shell == NULL)
{
g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?");
return;
}
xdg_shell_send_ping (xdg_shell, serial);
}
else if (surface->wl_shell_surface.resource) else if (surface->wl_shell_surface.resource)
{ wl_shell_surface_send_ping (surface->wl_shell_surface.resource, serial);
wl_shell_surface_send_ping (surface->wl_shell_surface.resource, serial);
}
} }
void void

View File

@ -81,6 +81,7 @@ struct _MetaWaylandSurface
MetaWaylandCompositor *compositor; MetaWaylandCompositor *compositor;
MetaSurfaceActor *surface_actor; MetaSurfaceActor *surface_actor;
MetaWindow *window; MetaWindow *window;
struct wl_resource *xdg_shell_resource;
MetaWaylandSurfaceExtension xdg_surface; MetaWaylandSurfaceExtension xdg_surface;
MetaWaylandSurfaceExtension xdg_popup; MetaWaylandSurfaceExtension xdg_popup;
MetaWaylandSurfaceExtension wl_shell_surface; MetaWaylandSurfaceExtension wl_shell_surface;