mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Always unmap before destroying surface
This commit is contained in:
		
							parent
							
								
									7efd9885b6
								
							
						
					
					
						commit
						8dec7036d0
					
				
					 4 changed files with 59 additions and 25 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue