diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index 5f10da94b..112c0eb50 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 77c404c50..5aa64dcda 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 a2191f3f2..7295f16d8 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 b32338501..d98bfc905 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 */ @@ -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; }