We now carry the shell_client around with each shell_surface.  This is much
more reliable than tacitly assuming that there is only one wl_shell or
xdg_shell instance bound to a particular wl_client.  In particular, weston
would crash when a client bound to both wl_shell and xdg_shell even if it
only ever used one of them.

Signed-off-by: Jason Ekstrand <[email protected]>
---
 desktop-shell/shell.c | 54 +++++++++++++++++++++------------------------------
 1 file changed, 22 insertions(+), 32 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 59fa99c..0e4329b 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -63,6 +63,8 @@ enum shell_surface_type {
        SHELL_SURFACE_XWAYLAND
 };
 
+struct shell_client;
+
 /*
  * Surface stacking and ordering.
  *
@@ -104,6 +106,7 @@ enum shell_surface_type {
 struct shell_surface {
        struct wl_resource *resource;
        struct wl_signal destroy_signal;
+       struct shell_client *owner;
 
        struct weston_surface *surface;
        struct weston_view *view;
@@ -233,9 +236,6 @@ set_alpha_if_fullscreen(struct shell_surface *shsurf)
                shsurf->fullscreen.black_view->alpha = 0.25;
 }
 
-static struct shell_client *
-get_shell_client(struct wl_client *client);
-
 static struct desktop_shell *
 shell_surface_get_shell(struct shell_surface *shsurf);
 
@@ -1859,12 +1859,10 @@ static void
 handle_xdg_ping(struct shell_surface *shsurf, uint32_t serial)
 {
        struct weston_compositor *compositor = shsurf->shell->compositor;
-       struct wl_client *client = wl_resource_get_client(shsurf->resource);
-       struct shell_client *sc;
+       struct shell_client *sc = shsurf->owner;
        struct wl_event_loop *loop;
        static const int ping_timeout = 200;
 
-       sc = get_shell_client(client);
        if (sc->unresponsive) {
                xdg_ping_timeout_handler(sc);
                return;
@@ -1982,19 +1980,6 @@ create_keyboard_focus_listener(struct weston_seat *seat)
        wl_signal_add(&seat->keyboard->focus_signal, listener);
 }
 
-static struct shell_client *
-get_shell_client(struct wl_client *client)
-{
-       struct wl_listener *listener;
-
-       listener = wl_client_get_destroy_listener(client,
-                                                 handle_shell_client_destroy);
-       if (listener == NULL)
-               return NULL;
-
-       return container_of(listener, struct shell_client, destroy_listener);
-}
-
 static void
 shell_client_pong(struct shell_client *sc, uint32_t serial)
 {
@@ -2015,9 +2000,9 @@ static void
 shell_surface_pong(struct wl_client *client,
                   struct wl_resource *resource, uint32_t serial)
 {
-       struct shell_client *sc;
+       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+       struct shell_client *sc = shsurf->owner;
 
-       sc = get_shell_client(client);
        shell_client_pong(sc, serial);
 }
 
@@ -3105,7 +3090,8 @@ get_shell_surface(struct weston_surface *surface)
 }
 
 static struct shell_surface *
-create_common_surface(void *shell, struct weston_surface *surface,
+create_common_surface(struct shell_client *owner, void *shell,
+                     struct weston_surface *surface,
                      const struct weston_shell_client *client)
 {
        struct shell_surface *shsurf;
@@ -3134,6 +3120,7 @@ create_common_surface(void *shell, struct weston_surface 
*surface,
        shsurf->resource_destroy_listener.notify = handle_resource_destroy;
        wl_resource_add_destroy_listener(surface->resource,
                                         &shsurf->resource_destroy_listener);
+       shsurf->owner = owner;
 
        shsurf->shell = (struct desktop_shell *) shell;
        shsurf->unresponsive = 0;
@@ -3176,7 +3163,7 @@ static struct shell_surface *
 create_shell_surface(void *shell, struct weston_surface *surface,
                     const struct weston_shell_client *client)
 {
-       return create_common_surface(shell, surface, client);
+       return create_common_surface(NULL, shell, surface, client);
 }
 
 static struct weston_view *
@@ -3193,7 +3180,8 @@ shell_get_shell_surface(struct wl_client *client,
 {
        struct weston_surface *surface =
                wl_resource_get_user_data(surface_resource);
-       struct desktop_shell *shell = wl_resource_get_user_data(resource);
+       struct shell_client *sc = wl_resource_get_user_data(resource);
+       struct desktop_shell *shell = sc->shell;
        struct shell_surface *shsurf;
 
        if (get_shell_surface(surface)) {
@@ -3203,7 +3191,7 @@ shell_get_shell_surface(struct wl_client *client,
                return;
        }
 
-       shsurf = create_shell_surface(shell, surface, &shell_client);
+       shsurf = create_common_surface(sc, shell, surface, &shell_client);
        if (!shsurf) {
                wl_resource_post_error(surface_resource,
                                       WL_DISPLAY_ERROR_INVALID_OBJECT,
@@ -3447,12 +3435,13 @@ xdg_use_unstable_version(struct wl_client *client,
 }
 
 static struct shell_surface *
-create_xdg_surface(void *shell, struct weston_surface *surface,
+create_xdg_surface(struct shell_client *owner, void *shell,
+                  struct weston_surface *surface,
                   const struct weston_shell_client *client)
 {
        struct shell_surface *shsurf;
 
-       shsurf = create_common_surface(shell, surface, client);
+       shsurf = create_common_surface(owner, shell, surface, client);
        shsurf->type = SHELL_SURFACE_TOPLEVEL;
 
        return shsurf;
@@ -3477,7 +3466,7 @@ xdg_get_xdg_surface(struct wl_client *client,
                return;
        }
 
-       shsurf = create_xdg_surface(shell, surface, &xdg_client);
+       shsurf = create_xdg_surface(sc, shell, surface, &xdg_client);
        if (!shsurf) {
                wl_resource_post_error(surface_resource,
                                       WL_DISPLAY_ERROR_INVALID_OBJECT,
@@ -3526,7 +3515,8 @@ static const struct weston_shell_client xdg_popup_client 
= {
 };
 
 static struct shell_surface *
-create_xdg_popup(void *shell, struct weston_surface *surface,
+create_xdg_popup(struct shell_client *owner, void *shell,
+                struct weston_surface *surface,
                 const struct weston_shell_client *client,
                 struct weston_surface *parent,
                 struct shell_seat *seat,
@@ -3535,7 +3525,7 @@ create_xdg_popup(void *shell, struct weston_surface 
*surface,
 {
        struct shell_surface *shsurf;
 
-       shsurf = create_common_surface(shell, surface, client);
+       shsurf = create_common_surface(owner, shell, surface, client);
        shsurf->type = SHELL_SURFACE_POPUP;
        shsurf->popup.shseat = seat;
        shsurf->popup.serial = serial;
@@ -3580,7 +3570,7 @@ xdg_get_xdg_popup(struct wl_client *client,
        parent = wl_resource_get_user_data(parent_resource);
        seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
 
-       shsurf = create_xdg_popup(shell, surface, &xdg_popup_client,
+       shsurf = create_xdg_popup(sc, shell, surface, &xdg_popup_client,
                                  parent, seat, serial, x, y);
        if (!shsurf) {
                wl_resource_post_error(surface_resource,
@@ -5070,7 +5060,7 @@ bind_shell(struct wl_client *client, void *data, uint32_t 
version, uint32_t id)
        if (sc)
                wl_resource_set_implementation(sc->resource,
                                               &shell_implementation,
-                                              shell, NULL);
+                                              sc, NULL);
 }
 
 static void
-- 
1.9.0

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to