mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Fix wlr_surface destruction bug
This commit is contained in:
		
							parent
							
								
									073dff63da
								
							
						
					
					
						commit
						31d78ff497
					
				
					 4 changed files with 16 additions and 10 deletions
				
			
		| 
						 | 
					@ -14,6 +14,10 @@ struct wl_compositor_state {
 | 
				
			||||||
void wl_compositor_init(struct wl_display *display,
 | 
					void wl_compositor_init(struct wl_display *display,
 | 
				
			||||||
		struct wl_compositor_state *state, struct wlr_renderer *renderer);
 | 
							struct wl_compositor_state *state, struct wlr_renderer *renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_surface;
 | 
				
			||||||
 | 
					void wl_compositor_surface_destroyed(struct wl_compositor_state *compositor,
 | 
				
			||||||
 | 
							struct wlr_surface *surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_shell_state {
 | 
					struct wl_shell_state {
 | 
				
			||||||
	struct wl_global *wl_global;
 | 
						struct wl_global *wl_global;
 | 
				
			||||||
	struct wl_list wl_resources;
 | 
						struct wl_list wl_resources;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,8 @@
 | 
				
			||||||
#include "compositor.h"
 | 
					#include "compositor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_surface_listener(struct wl_listener *listener, void *data) {
 | 
					static void destroy_surface_listener(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wl_compositor_state *state;
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(data);
 | 
				
			||||||
	struct wlr_surface *surface = data;
 | 
						struct wl_compositor_state *state = surface->compositor_data;
 | 
				
			||||||
	state = wl_container_of(listener, state, destroy_surface_listener);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_resource *res = NULL;
 | 
						struct wl_resource *res = NULL;
 | 
				
			||||||
	wl_list_for_each(res, &state->surfaces, link) {
 | 
						wl_list_for_each(res, &state->surfaces, link) {
 | 
				
			||||||
| 
						 | 
					@ -25,8 +24,11 @@ static void wl_compositor_create_surface(struct wl_client *client,
 | 
				
			||||||
	struct wl_resource *surface_resource = wl_resource_create(client,
 | 
						struct wl_resource *surface_resource = wl_resource_create(client,
 | 
				
			||||||
			&wl_surface_interface, wl_resource_get_version(resource), id);
 | 
								&wl_surface_interface, wl_resource_get_version(resource), id);
 | 
				
			||||||
	struct wlr_surface *surface = wlr_surface_create(surface_resource, state->renderer);
 | 
						struct wlr_surface *surface = wlr_surface_create(surface_resource, state->renderer);
 | 
				
			||||||
 | 
						surface->compositor_data = state;
 | 
				
			||||||
 | 
						surface->compositor_listener.notify = &destroy_surface_listener;
 | 
				
			||||||
 | 
						wl_resource_add_destroy_listener(surface_resource, &surface->compositor_listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&state->surfaces, wl_resource_get_link(surface_resource));
 | 
						wl_list_insert(&state->surfaces, wl_resource_get_link(surface_resource));
 | 
				
			||||||
	wl_signal_add(&surface->signals.destroy, &state->destroy_surface_listener);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wl_compositor_create_region(struct wl_client *client,
 | 
					static void wl_compositor_create_region(struct wl_client *client,
 | 
				
			||||||
| 
						 | 
					@ -73,7 +75,6 @@ void wl_compositor_init(struct wl_display *display,
 | 
				
			||||||
		&wl_compositor_interface, 4, state, wl_compositor_bind);
 | 
							&wl_compositor_interface, 4, state, wl_compositor_bind);
 | 
				
			||||||
	state->wl_global = wl_global;
 | 
						state->wl_global = wl_global;
 | 
				
			||||||
	state->renderer = renderer;
 | 
						state->renderer = renderer;
 | 
				
			||||||
	state->destroy_surface_listener.notify = destroy_surface_listener;
 | 
					 | 
				
			||||||
	wl_list_init(&state->wl_resources);
 | 
						wl_list_init(&state->wl_resources);
 | 
				
			||||||
	wl_list_init(&state->surfaces);
 | 
						wl_list_init(&state->surfaces);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,15 +37,17 @@ struct wlr_surface {
 | 
				
			||||||
	float surface_to_buffer_matrix[16];
 | 
						float surface_to_buffer_matrix[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct wl_signal destroy;
 | 
					 | 
				
			||||||
		struct wl_signal commit;
 | 
							struct wl_signal commit;
 | 
				
			||||||
	} signals;
 | 
						} signals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_list frame_callback_list; // wl_surface.frame
 | 
						struct wl_list frame_callback_list; // wl_surface.frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener compositor_listener; // destroy listener used by compositor
 | 
				
			||||||
 | 
						void *compositor_data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_renderer;
 | 
					struct wlr_renderer;
 | 
				
			||||||
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
 | 
					struct wlr_surface *wlr_surface_create(struct wl_resource *res,
 | 
				
			||||||
		struct wlr_renderer *renderer);
 | 
						struct wlr_renderer *renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,13 +161,13 @@ const struct wl_surface_interface surface_interface = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_surface(struct wl_resource *resource) {
 | 
					static void destroy_surface(struct wl_resource *resource) {
 | 
				
			||||||
	struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
				
			||||||
	wl_signal_emit(&surface->signals.destroy, surface);
 | 
					 | 
				
			||||||
	wlr_texture_destroy(surface->texture);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_texture_destroy(surface->texture);
 | 
				
			||||||
	struct wlr_frame_callback *cb, *next;
 | 
						struct wlr_frame_callback *cb, *next;
 | 
				
			||||||
	wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link) {
 | 
						wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link) {
 | 
				
			||||||
		wl_resource_destroy(cb->resource);
 | 
							wl_resource_destroy(cb->resource);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(surface);
 | 
						free(surface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -177,7 +177,6 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res,
 | 
				
			||||||
	surface->texture = wlr_render_texture_init(renderer);
 | 
						surface->texture = wlr_render_texture_init(renderer);
 | 
				
			||||||
	surface->resource = res;
 | 
						surface->resource = res;
 | 
				
			||||||
	wl_signal_init(&surface->signals.commit);
 | 
						wl_signal_init(&surface->signals.commit);
 | 
				
			||||||
	wl_signal_init(&surface->signals.destroy);
 | 
					 | 
				
			||||||
	wl_list_init(&surface->frame_callback_list);
 | 
						wl_list_init(&surface->frame_callback_list);
 | 
				
			||||||
	wl_resource_set_implementation(res, &surface_interface,
 | 
						wl_resource_set_implementation(res, &surface_interface,
 | 
				
			||||||
			surface, destroy_surface);
 | 
								surface, destroy_surface);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue