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
This commit is contained in:
parent
41e60d251e
commit
8173c06c4d
|
@ -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 *
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
@ -1320,6 +1320,19 @@ static const struct zxdg_shell_v6_interface _e_xdg_shell_interface =
|
|||
_e_xdg_shell_cb_pong
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue