discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=8173c06c4d666248650c75616cad35ed5b63500e

commit 8173c06c4d666248650c75616cad35ed5b63500e
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Thu Dec 1 12:11:38 2016 -0500

    add handler for triggering xdg-shell data cleanup on client del
    
    in the case of internal windows, the client is deleted before any surfaces
    are destroyed. this requires a special case to perform cleanups in order to
    prevent client objects from leaking
---
 src/modules/wl_desktop_shell/e_mod_main.c | 13 ++++++++++++-
 src/modules/wl_desktop_shell/e_mod_main.h |  2 ++
 src/modules/wl_desktop_shell/xdg5.c       | 15 +++++++++++++--
 src/modules/wl_desktop_shell/xdg6.c       | 31 ++++++++++++++++++++++---------
 4 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/src/modules/wl_desktop_shell/e_mod_main.c 
b/src/modules/wl_desktop_shell/e_mod_main.c
index 5f10da9..112c0eb 100644
--- a/src/modules/wl_desktop_shell/e_mod_main.c
+++ b/src/modules/wl_desktop_shell/e_mod_main.c
@@ -16,7 +16,8 @@ e_shell_surface_destroy(struct wl_resource *resource)
    /* get the client for this resource */
    ec = wl_resource_get_user_data(resource);
    if (!ec) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   /* client may be passed here during DEL hook */
+   if (!ec->comp_data) return;
 
    if (ec->comp_data->grab)
      {
@@ -143,6 +144,16 @@ e_shell_surface_mouse_down_helper(E_Client *ec, 
E_Binding_Event_Mouse_Button *ev
    e_focus_event_mouse_down(ec);
 }
 
+EINTERN E_Shell_Data *
+e_shell_data_new(unsigned int version)
+{
+   E_Shell_Data *shd;
+
+   shd = E_NEW(E_Shell_Data, 1);
+   shd->version = version;
+   return shd;
+}
+
 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" };
 
 E_API void *
diff --git a/src/modules/wl_desktop_shell/e_mod_main.h 
b/src/modules/wl_desktop_shell/e_mod_main.h
index 77c404c..5aa64dc 100644
--- a/src/modules/wl_desktop_shell/e_mod_main.h
+++ b/src/modules/wl_desktop_shell/e_mod_main.h
@@ -11,6 +11,7 @@ EINTERN void e_shell_surface_destroy(struct wl_resource 
*resource);
 EINTERN void e_shell_surface_cb_destroy(struct wl_resource *resource);
 EINTERN void e_shell_surface_parent_set(E_Client *ec, struct wl_resource 
*parent_resource);
 EINTERN void e_shell_surface_mouse_down_helper(E_Client *ec, 
E_Binding_Event_Mouse_Button *ev, Eina_Bool move);
+EINTERN E_Shell_Data *e_shell_data_new(unsigned int version);
 
 EINTERN Eina_Bool e_xdg_shell_v5_init(void);
 EINTERN Eina_Bool e_xdg_shell_v6_init(void);
@@ -24,6 +25,7 @@ struct E_Shell_Data
    Eina_List *pending;
    struct wl_resource *surface;
    void *shell;
+   unsigned int version;
    Eina_Bool fullscreen : 1;
    Eina_Bool maximized : 1;
    Eina_Bool activated : 1;
diff --git a/src/modules/wl_desktop_shell/xdg5.c 
b/src/modules/wl_desktop_shell/xdg5.c
index a2191f3..7295f16 100644
--- a/src/modules/wl_desktop_shell/xdg5.c
+++ b/src/modules/wl_desktop_shell/xdg5.c
@@ -686,7 +686,7 @@ _e_xdg_shell_cb_surface_get(struct wl_client *client, 
struct wl_resource *resour
    cdata->shell.ping = _e_xdg_shell_surface_ping;
    cdata->shell.map = _e_xdg_shell_surface_map;
    cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-   cdata->shell.data = E_NEW(E_Shell_Data, 1);
+   cdata->shell.data = e_shell_data_new(5);
    cdata->is_xdg_surface = EINA_TRUE;
 
    /* set toplevel client properties */
@@ -776,7 +776,7 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct 
wl_resource *resource
    cdata->shell.ping = _e_xdg_shell_surface_ping;
    cdata->shell.map = _e_xdg_shell_surface_map;
    cdata->shell.unmap = _e_xdg_shell_surface_unmap;
-   cdata->shell.data = E_NEW(E_Shell_Data, 1);
+   cdata->shell.data = e_shell_data_new(5);
    cdata->is_xdg_surface = EINA_TRUE;
 
    if (!ec->internal)
@@ -878,6 +878,16 @@ _e_xdg_shell_cb_bind(struct wl_client *client, void *data 
EINA_UNUSED, uint32_t
                               NULL, NULL);
 }
 
+static void
+_xdg5_client_hook_del(void *d EINA_UNUSED, E_Client *ec)
+{
+   E_Shell_Data *shd = ec->comp_data->shell.data;
+
+   if (shd && (shd->version != 5)) return;
+   if (ec->comp_data->shell.surface)
+     e_shell_surface_cb_destroy(ec->comp_data->shell.surface);
+}
+
 EINTERN Eina_Bool
 e_xdg_shell_v5_init(void)
 {
@@ -888,5 +898,6 @@ e_xdg_shell_v5_init(void)
         ERR("Could not create xdg_shell global");
         return EINA_FALSE;
      }
+   e_client_hook_add(E_CLIENT_HOOK_DEL, _xdg5_client_hook_del, NULL);
    return EINA_TRUE;
 }
diff --git a/src/modules/wl_desktop_shell/xdg6.c 
b/src/modules/wl_desktop_shell/xdg6.c
index b323385..d98bfc9 100644
--- a/src/modules/wl_desktop_shell/xdg6.c
+++ b/src/modules/wl_desktop_shell/xdg6.c
@@ -1266,7 +1266,7 @@ _e_xdg_shell_cb_surface_get(struct wl_client *client, 
struct wl_resource *resour
                                "Client already has XDG shell surface");
         return;
      }
-   shd = cdata->shell.data = E_NEW(E_Shell_Data, 1);
+   shd = cdata->shell.data = e_shell_data_new(6);
    shd->width = shd->height = -1;
 
    /* try to create a shell surface */
@@ -1321,6 +1321,19 @@ static const struct zxdg_shell_v6_interface 
_e_xdg_shell_interface =
 };
 
 static void
+_xdg6_client_destroy(E_Client *ec)
+{
+   E_Shell_Data *shd;
+
+   shd = ec->comp_data->shell.data;
+   if (shd && (shd->version != 6)) return;
+   if (ec->comp_data->shell.surface)
+     e_shell_surface_cb_destroy(ec->comp_data->shell.surface);
+   if (shd)
+     e_shell_surface_cb_destroy(shd->surface);
+}
+
+static void
 _e_xdg_shell_cb_unbind(struct wl_resource *resource)
 {
    v6_Shell_Data *v;
@@ -1334,16 +1347,9 @@ _e_xdg_shell_cb_unbind(struct wl_resource *resource)
    EINA_LIST_REVERSE_FOREACH_SAFE(v->surfaces, l, ll, res)
      {
         E_Client *ec = wl_resource_get_user_data(res);
-        E_Shell_Data *shd;
 
         if (!e_object_is_del(E_OBJECT(ec)))
-          {
-             if (ec->comp_data->shell.surface)
-               e_shell_surface_cb_destroy(ec->comp_data->shell.surface);
-             shd = ec->comp_data->shell.data;
-             if (shd)
-               e_shell_surface_cb_destroy(shd->surface);
-          }
+          _xdg6_client_destroy(ec);
         v->surfaces = eina_list_remove_list(v->surfaces, l);
      }
 
@@ -1374,6 +1380,12 @@ _e_xdg_shell_cb_bind(struct wl_client *client, void 
*data EINA_UNUSED, uint32_t
                                   v, _e_xdg_shell_cb_unbind);
 }
 
+static void
+_xdg6_client_hook_del(void *d EINA_UNUSED, E_Client *ec)
+{
+   _xdg6_client_destroy(ec);
+}
+
 EINTERN Eina_Bool
 e_xdg_shell_v6_init(void)
 {
@@ -1384,5 +1396,6 @@ e_xdg_shell_v6_init(void)
         ERR("Could not create xdg_shell global");
         return EINA_FALSE;
      }
+   e_client_hook_add(E_CLIENT_HOOK_DEL, _xdg6_client_hook_del, NULL);
    return EINA_TRUE;
 }

-- 


Reply via email to