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;
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);
}
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)
{
E_Xdg_Toplevel_V6 *toplevel;
_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);
}
_e_xdg_toplevel_v6_listener_finish(toplevel);
_e_xdg_toplevel_v6_finish(toplevel);
- free(toplevel);
}