Always unmap before destroying surface
This commit is contained in:
		
							parent
							
								
									7efd9885b6
								
							
						
					
					
						commit
						8dec7036d0
					
				|  | @ -102,6 +102,16 @@ struct wlr_xdg_surface_configure { | ||||||
| 	struct wlr_xdg_toplevel_state *toplevel_state; | 	struct wlr_xdg_toplevel_state *toplevel_state; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * An xdg-surface is a user interface element requiring management by the | ||||||
|  |  * compositor. An xdg-surface alone isn't useful, a role should be assigned to | ||||||
|  |  * it in order to map it. | ||||||
|  |  * | ||||||
|  |  * When a surface has a role and is ready to be displayed, the `map` event is | ||||||
|  |  * emitted. When a surface should no longer be displayed, the `unmap` event is | ||||||
|  |  * emitted. The `unmap` event is guaranted to be emitted before the `destroy` | ||||||
|  |  * event if the view is destroyed when mapped. | ||||||
|  |  */ | ||||||
| struct wlr_xdg_surface { | struct wlr_xdg_surface { | ||||||
| 	struct wlr_xdg_client *client; | 	struct wlr_xdg_client *client; | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
|  |  | ||||||
|  | @ -90,6 +90,16 @@ struct wlr_xdg_toplevel_v6_state { | ||||||
| 	uint32_t min_width, min_height; | 	uint32_t min_width, min_height; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * An xdg-surface is a user interface element requiring management by the | ||||||
|  |  * compositor. An xdg-surface alone isn't useful, a role should be assigned to | ||||||
|  |  * it in order to map it. | ||||||
|  |  * | ||||||
|  |  * When a surface has a role and is ready to be displayed, the `map` event is | ||||||
|  |  * emitted. When a surface should no longer be displayed, the `unmap` event is | ||||||
|  |  * emitted. The `unmap` event is guaranted to be emitted before the `destroy` | ||||||
|  |  * event if the view is destroyed when mapped. | ||||||
|  |  */ | ||||||
| struct wlr_xdg_toplevel_v6 { | struct wlr_xdg_toplevel_v6 { | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
| 	struct wlr_xdg_surface_v6 *base; | 	struct wlr_xdg_surface_v6 *base; | ||||||
|  |  | ||||||
|  | @ -75,6 +75,15 @@ struct wlr_xwayland_surface_size_hints { | ||||||
| 	uint32_t win_gravity; | 	uint32_t win_gravity; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * An Xwayland user interface component. It has an absolute position in | ||||||
|  |  * layout-local coordinates. | ||||||
|  |  * | ||||||
|  |  * When a surface is ready to be displayed, the `map` event is emitted. When a | ||||||
|  |  * surface should no longer be displayed, the `unmap` event is emitted. The | ||||||
|  |  * `unmap` event is guaranted to be emitted before the `destroy` event if the | ||||||
|  |  * view is destroyed when mapped. | ||||||
|  |  */ | ||||||
| struct wlr_xwayland_surface { | struct wlr_xwayland_surface { | ||||||
| 	xcb_window_t window_id; | 	xcb_window_t window_id; | ||||||
| 	struct wlr_xwm *xwm; | 	struct wlr_xwm *xwm; | ||||||
|  | @ -116,8 +125,7 @@ struct wlr_xwayland_surface { | ||||||
| 
 | 
 | ||||||
| 	// _NET_WM_STATE
 | 	// _NET_WM_STATE
 | ||||||
| 	bool fullscreen; | 	bool fullscreen; | ||||||
| 	bool maximized_vert; | 	bool maximized_vert, maximized_horz; | ||||||
| 	bool maximized_horz; |  | ||||||
| 
 | 
 | ||||||
| 	bool has_alpha; | 	bool has_alpha; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -273,8 +273,12 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) { | ||||||
| 		i, property); | 		i, property); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void xsurface_unmap(struct wlr_xwayland_surface *surface); | ||||||
|  | 
 | ||||||
| static void wlr_xwayland_surface_destroy( | static void wlr_xwayland_surface_destroy( | ||||||
| 		struct wlr_xwayland_surface *xsurface) { | 		struct wlr_xwayland_surface *xsurface) { | ||||||
|  | 	xsurface_unmap(xsurface); | ||||||
|  | 
 | ||||||
| 	wlr_signal_emit_safe(&xsurface->events.destroy, xsurface); | 	wlr_signal_emit_safe(&xsurface->events.destroy, xsurface); | ||||||
| 
 | 
 | ||||||
| 	if (xsurface == xsurface->xwm->focus_surface) { | 	if (xsurface == xsurface->xwm->focus_surface) { | ||||||
|  | @ -618,7 +622,8 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface, | ||||||
| 	if (!xsurface->added && | 	if (!xsurface->added && | ||||||
| 			wlr_surface_has_buffer(xsurface->surface) && | 			wlr_surface_has_buffer(xsurface->surface) && | ||||||
| 			xsurface->mapped) { | 			xsurface->mapped) { | ||||||
| 		wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface, xsurface); | 		wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface, | ||||||
|  | 			xsurface); | ||||||
| 		xsurface->added = true; | 		xsurface->added = true; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -626,9 +631,7 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface, | ||||||
| static void handle_surface_destroy(struct wl_listener *listener, void *data) { | static void handle_surface_destroy(struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xwayland_surface *xsurface = | 	struct wlr_xwayland_surface *xsurface = | ||||||
| 		wl_container_of(listener, xsurface, surface_destroy); | 		wl_container_of(listener, xsurface, surface_destroy); | ||||||
| 
 | 	xsurface_unmap(xsurface); | ||||||
| 	xsurface->surface = NULL; |  | ||||||
| 	// TODO destroy xwayland surface?
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void xwm_map_shell_surface(struct wlr_xwm *xwm, | static void xwm_map_shell_surface(struct wlr_xwm *xwm, | ||||||
|  | @ -665,6 +668,27 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm, | ||||||
| 	wlr_signal_emit_safe(&xsurface->events.map, xsurface); | 	wlr_signal_emit_safe(&xsurface->events.map, xsurface); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void xsurface_unmap(struct wlr_xwayland_surface *surface) { | ||||||
|  | 	if (surface->mapped) { | ||||||
|  | 		surface->mapped = false; | ||||||
|  | 		wlr_signal_emit_safe(&surface->events.unmap, surface); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (surface->surface_id) { | ||||||
|  | 		// Make sure we're not on the unpaired surface list or we
 | ||||||
|  | 		// could be assigned a surface during surface creation that
 | ||||||
|  | 		// was mapped before this unmap request.
 | ||||||
|  | 		wl_list_remove(&surface->unpaired_link); | ||||||
|  | 		surface->surface_id = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (surface->surface) { | ||||||
|  | 		wlr_surface_set_role_committed(surface->surface, NULL, NULL); | ||||||
|  | 		wl_list_remove(&surface->surface_destroy.link); | ||||||
|  | 		surface->surface = NULL; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void xwm_handle_create_notify(struct wlr_xwm *xwm, | static void xwm_handle_create_notify(struct wlr_xwm *xwm, | ||||||
| 		xcb_create_notify_event_t *ev) { | 		xcb_create_notify_event_t *ev) { | ||||||
| 	wlr_log(L_DEBUG, "XCB_CREATE_NOTIFY (%u)", ev->window); | 	wlr_log(L_DEBUG, "XCB_CREATE_NOTIFY (%u)", ev->window); | ||||||
|  | @ -778,25 +802,7 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (xsurface->mapped) { | 	xsurface_unmap(xsurface); | ||||||
| 		xsurface->mapped = false; |  | ||||||
| 		wlr_signal_emit_safe(&xsurface->events.unmap, xsurface); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (xsurface->surface_id) { |  | ||||||
| 		// Make sure we're not on the unpaired surface list or we
 |  | ||||||
| 		// could be assigned a surface during surface creation that
 |  | ||||||
| 		// was mapped before this unmap request.
 |  | ||||||
| 		wl_list_remove(&xsurface->unpaired_link); |  | ||||||
| 		xsurface->surface_id = 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (xsurface->surface) { |  | ||||||
| 		wlr_surface_set_role_committed(xsurface->surface, NULL, NULL); |  | ||||||
| 		wl_list_remove(&xsurface->surface_destroy.link); |  | ||||||
| 	} |  | ||||||
| 	xsurface->surface = NULL; |  | ||||||
| 
 |  | ||||||
| 	xsurface_set_wm_state(xsurface, ICCCM_WITHDRAWN_STATE); | 	xsurface_set_wm_state(xsurface, ICCCM_WITHDRAWN_STATE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue