From: Seunghun Lee Date: Mon, 4 Dec 2023 01:44:06 +0000 (+0900) Subject: xdg_shell_v6: Do not issue a protocol error X-Git-Tag: accepted/tizen/unified/20231205.171428~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=19565a63093f7b0ec85d8980d97c7e10cc4dd0df;p=platform%2Fupstream%2Fenlightenment.git xdg_shell_v6: Do not issue a protocol error The libds will issue a protocol error for any client that attempts to request wl_surface.commit after the xdg_toplevel_v6 resource has been destroyed, but xdg_surface_v6 resource still alive. The purpose of this commit is to prevent it from happening by setting ds_xdg_surface_v6->role to DS_XDG_SURFACE_V6_ROLE_TOPLEVEL to fool libds implementation when xdg_toplevel_v6 resource is destroyed. Change-Id: I0546e38513f19bbaf1be65fd2b8f90189c682cdf --- diff --git a/src/bin/e_xdg_shell_v6.c b/src/bin/e_xdg_shell_v6.c index ab1c5c006a..21d020b94c 100644 --- a/src/bin/e_xdg_shell_v6.c +++ b/src/bin/e_xdg_shell_v6.c @@ -29,6 +29,8 @@ struct _E_Xdg_Toplevel_V6 struct ds_xdg_toplevel_v6 *ds_toplevel; E_Client *ec; + struct wl_resource *xdg_surface_resource; + struct wl_listener set_parent; struct wl_listener set_title; struct wl_listener set_app_id; @@ -41,6 +43,8 @@ struct _E_Xdg_Toplevel_V6 struct wl_listener configure; struct wl_listener ping_timeout; struct wl_listener surface_commit; + struct wl_listener resource_destroy; + struct wl_listener xdg_surface_resource_destroy; }; static void _e_xdg_shell_v6_cb_destroy(struct wl_listener *listener, void *data); @@ -720,6 +724,53 @@ _e_xdg_toplevel_v6_finish(E_Xdg_Toplevel_V6 *toplevel) e_shell_e_client_destroy(ec); } +static void +_e_xdg_toplevel_v6_cb_resource_destroy(struct wl_listener *listener, void *data) +{ + E_Xdg_Toplevel_V6 *toplevel; + struct ds_xdg_surface_v6 *ds_xdg_surface; + + toplevel = wl_container_of(listener, toplevel, resource_destroy); + ds_xdg_surface = ds_xdg_surface_v6_from_resource(toplevel->xdg_surface_resource); + if (ds_xdg_surface) + ds_xdg_surface->role = DS_XDG_SURFACE_V6_ROLE_TOPLEVEL; + + wl_list_remove(&toplevel->resource_destroy.link); + wl_list_init(&toplevel->resource_destroy.link); +} + +static void +_e_xdg_toplevel_v6_cb_xdg_surface_resource_destroy(struct wl_listener *listener, void *data) +{ + E_Xdg_Toplevel_V6 *toplevel; + + toplevel = wl_container_of(listener, toplevel, xdg_surface_resource_destroy); + wl_list_remove(&toplevel->resource_destroy.link); + wl_list_remove(&toplevel->xdg_surface_resource_destroy.link); + free(toplevel); +} + +/* + * FIXME HACK + * The libds will issue a protocol error for any client that attempts to + * request wl_surface.commit after the xdg_toplevel_v6 resource has been + * destroyed, but xdg_surface_v6 resource still alive. + * The purpose of this function is to prevent it from happening by setting + * ds_xdg_surface_v6->role to DS_XDG_SURFACE_V6_ROLE_TOPLEVEL to fool libds + * implementation when xdg_toplevel_v6 resource is destroyed. + */ +static void +_e_xdg_toplevel_v6_role_keep_handler_init(E_Xdg_Toplevel_V6 *toplevel, struct ds_xdg_surface_v6 *ds_xdg_surface) +{ + toplevel->xdg_surface_resource = ds_xdg_surface->resource; + + toplevel->xdg_surface_resource_destroy.notify = _e_xdg_toplevel_v6_cb_xdg_surface_resource_destroy; + wl_resource_add_destroy_listener(ds_xdg_surface->resource, &toplevel->xdg_surface_resource_destroy); + + toplevel->resource_destroy.notify = _e_xdg_toplevel_v6_cb_resource_destroy; + wl_resource_add_destroy_listener(ds_xdg_surface->toplevel->resource, &toplevel->resource_destroy); +} + static void _e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface) { @@ -738,6 +789,7 @@ _e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface) _e_xdg_toplevel_v6_listener_init(toplevel); _e_xdg_toplevel_v6_init(toplevel); + _e_xdg_toplevel_v6_role_keep_handler_init(toplevel, ds_xdg_surface); LOG("Created E_Xdg_Toplevel_V6(%p)", toplevel->ec, toplevel); } @@ -753,5 +805,4 @@ _e_xdg_toplevel_v6_cb_xdg_surface_destroy(struct wl_listener *listener, void *da _e_xdg_toplevel_v6_listener_finish(toplevel); _e_xdg_toplevel_v6_finish(toplevel); - free(toplevel); }