mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Xwayland unmanaged views aren't views anymore
This commit is contained in:
		
							parent
							
								
									61fabede14
								
							
						
					
					
						commit
						2f64ce86c4
					
				
					 8 changed files with 67 additions and 59 deletions
				
			
		| 
						 | 
					@ -70,7 +70,9 @@ struct sway_container {
 | 
				
			||||||
	enum sway_container_layout prev_layout;
 | 
						enum sway_container_layout prev_layout;
 | 
				
			||||||
	enum sway_container_layout workspace_layout;
 | 
						enum sway_container_layout workspace_layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// in output-local coordinates
 | 
						// For C_ROOT, this has no meaning
 | 
				
			||||||
 | 
						// For C_OUTPUT, this is the output position in layout coordinates
 | 
				
			||||||
 | 
						// For other types, this is the position in output-local coordinates
 | 
				
			||||||
	double x, y;
 | 
						double x, y;
 | 
				
			||||||
	// does not include borders or gaps.
 | 
						// does not include borders or gaps.
 | 
				
			||||||
	double width, height;
 | 
						double width, height;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ struct sway_root {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener output_layout_change;
 | 
						struct wl_listener output_layout_change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_list unmanaged_views; // sway_view::unmanaged_view_link
 | 
						struct wl_list xwayland_unmanaged; // sway_xwayland_unmanaged::link
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct wl_signal new_container;
 | 
							struct wl_signal new_container;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,13 @@ struct sway_xwayland_surface {
 | 
				
			||||||
	int pending_width, pending_height;
 | 
						int pending_width, pending_height;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sway_xwayland_unmanaged {
 | 
				
			||||||
 | 
						struct wlr_xwayland_surface *wlr_xwayland_surface;
 | 
				
			||||||
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener destroy;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_wl_shell_surface {
 | 
					struct sway_wl_shell_surface {
 | 
				
			||||||
	struct sway_view *view;
 | 
						struct sway_view *view;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,9 +134,6 @@ void view_damage_from(struct sway_view *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface);
 | 
					void view_map(struct sway_view *view, struct wlr_surface *wlr_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_map_unmanaged(struct sway_view *view,
 | 
					 | 
				
			||||||
	struct wlr_surface *wlr_surface);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void view_unmap(struct sway_view *view);
 | 
					void view_unmap(struct sway_view *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_update_position(struct sway_view *view, double ox, double oy);
 | 
					void view_update_position(struct sway_view *view, double ox, double oy);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,15 +257,15 @@ static void render_output(struct sway_output *output, struct timespec *when,
 | 
				
			||||||
	container_descendants(workspace, C_VIEW, render_view, &rdata);
 | 
						container_descendants(workspace, C_VIEW, render_view, &rdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// render unmanaged views on top
 | 
						// render unmanaged views on top
 | 
				
			||||||
	struct sway_view *view;
 | 
						struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged;
 | 
				
			||||||
	wl_list_for_each(view, &root_container.sway_root->unmanaged_views,
 | 
						struct sway_xwayland_unmanaged *sway_surface;
 | 
				
			||||||
			unmanaged_view_link) {
 | 
						wl_list_for_each(sway_surface, unmanaged, link) {
 | 
				
			||||||
		if (view->type != SWAY_XWAYLAND_VIEW) {
 | 
							struct wlr_xwayland_surface *xsurface =
 | 
				
			||||||
 | 
								sway_surface->wlr_xwayland_surface;
 | 
				
			||||||
 | 
							if (xsurface->surface == NULL) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const struct wlr_box view_box = {
 | 
							const struct wlr_box view_box = {
 | 
				
			||||||
			.x = xsurface->x,
 | 
								.x = xsurface->x,
 | 
				
			||||||
			.y = xsurface->y,
 | 
								.y = xsurface->y,
 | 
				
			||||||
| 
						 | 
					@ -277,7 +277,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		render_surface(view->surface, wlr_output, &output->last_frame,
 | 
							render_surface(xsurface->surface, wlr_output, &output->last_frame,
 | 
				
			||||||
			view_box.x - output_box->x, view_box.y - output_box->y, 0);
 | 
								view_box.x - output_box->x, view_box.y - output_box->y, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,33 @@
 | 
				
			||||||
#include "sway/input/input-manager.h"
 | 
					#include "sway/input/input-manager.h"
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct sway_xwayland_unmanaged *sway_surface =
 | 
				
			||||||
 | 
							wl_container_of(listener, sway_surface, destroy);
 | 
				
			||||||
 | 
						wl_list_remove(&sway_surface->destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&sway_surface->link);
 | 
				
			||||||
 | 
						free(sway_surface);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void create_unmanaged(struct wlr_xwayland_surface *xsurface) {
 | 
				
			||||||
 | 
						struct sway_xwayland_unmanaged *sway_surface =
 | 
				
			||||||
 | 
							calloc(1, sizeof(struct sway_xwayland_unmanaged));
 | 
				
			||||||
 | 
						if (!sway_assert(sway_surface, "Failed to allocate surface")) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sway_surface->wlr_xwayland_surface = xsurface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy);
 | 
				
			||||||
 | 
						sway_surface->destroy.notify = unmanaged_handle_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_insert(&root_container.sway_root->xwayland_unmanaged,
 | 
				
			||||||
 | 
							&sway_surface->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: damage tracking
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool assert_xwayland(struct sway_view *view) {
 | 
					static bool assert_xwayland(struct sway_view *view) {
 | 
				
			||||||
	return sway_assert(view->type == SWAY_XWAYLAND_VIEW,
 | 
						return sway_assert(view->type == SWAY_XWAYLAND_VIEW,
 | 
				
			||||||
		"Expected xwayland view!");
 | 
							"Expected xwayland view!");
 | 
				
			||||||
| 
						 | 
					@ -121,13 +148,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_view *view = sway_surface->view;
 | 
						struct sway_view *view = sway_surface->view;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// put it back into the tree
 | 
						// put it back into the tree
 | 
				
			||||||
	if (wlr_xwayland_surface_is_unmanaged(xsurface) ||
 | 
						wlr_xwayland_surface_set_maximized(xsurface, true);
 | 
				
			||||||
			xsurface->override_redirect) {
 | 
						view_map(view, xsurface->surface);
 | 
				
			||||||
		view_map_unmanaged(view, xsurface->surface);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		wlr_xwayland_surface_set_maximized(xsurface, true);
 | 
					 | 
				
			||||||
		view_map(view, xsurface->surface);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_request_configure(struct wl_listener *listener, void *data) {
 | 
					static void handle_request_configure(struct wl_listener *listener, void *data) {
 | 
				
			||||||
| 
						 | 
					@ -147,12 +169,19 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
 | 
				
			||||||
			listener, server, xwayland_surface);
 | 
								listener, server, xwayland_surface);
 | 
				
			||||||
	struct wlr_xwayland_surface *xsurface = data;
 | 
						struct wlr_xwayland_surface *xsurface = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wlr_xwayland_surface_is_unmanaged(xsurface) ||
 | 
				
			||||||
 | 
								xsurface->override_redirect) {
 | 
				
			||||||
 | 
							wlr_log(L_DEBUG, "New xwayland unmanaged surface");
 | 
				
			||||||
 | 
							create_unmanaged(xsurface);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
 | 
						wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
 | 
				
			||||||
			xsurface->title, xsurface->class);
 | 
							xsurface->title, xsurface->class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct sway_xwayland_surface *sway_surface =
 | 
						struct sway_xwayland_surface *sway_surface =
 | 
				
			||||||
		calloc(1, sizeof(struct sway_xwayland_surface));
 | 
							calloc(1, sizeof(struct sway_xwayland_surface));
 | 
				
			||||||
	if (!sway_assert(sway_surface, "Failed to allocate surface!")) {
 | 
						if (!sway_assert(sway_surface, "Failed to allocate surface")) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,14 +47,15 @@ static struct wlr_surface *layer_surface_at(struct sway_output *output,
 | 
				
			||||||
static struct sway_container *container_at_cursor(struct sway_cursor *cursor,
 | 
					static struct sway_container *container_at_cursor(struct sway_cursor *cursor,
 | 
				
			||||||
		struct wlr_surface **surface, double *sx, double *sy) {
 | 
							struct wlr_surface **surface, double *sx, double *sy) {
 | 
				
			||||||
	// check for unmanaged views first
 | 
						// check for unmanaged views first
 | 
				
			||||||
	struct wl_list *unmanaged = &root_container.sway_root->unmanaged_views;
 | 
						struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged;
 | 
				
			||||||
	struct sway_view *view;
 | 
						struct sway_xwayland_unmanaged *sway_surface;
 | 
				
			||||||
	wl_list_for_each_reverse(view, unmanaged, unmanaged_view_link) {
 | 
						wl_list_for_each_reverse(sway_surface, unmanaged, link) {
 | 
				
			||||||
		if (view->type != SWAY_XWAYLAND_VIEW) {
 | 
							struct wlr_xwayland_surface *xsurface =
 | 
				
			||||||
 | 
								sway_surface->wlr_xwayland_surface;
 | 
				
			||||||
 | 
							if (xsurface->surface == NULL) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
 | 
					 | 
				
			||||||
		struct wlr_box box = {
 | 
							struct wlr_box box = {
 | 
				
			||||||
			.x = xsurface->x,
 | 
								.x = xsurface->x,
 | 
				
			||||||
			.y = xsurface->y,
 | 
								.y = xsurface->y,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ void layout_init(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	root_container.sway_root = calloc(1, sizeof(*root_container.sway_root));
 | 
						root_container.sway_root = calloc(1, sizeof(*root_container.sway_root));
 | 
				
			||||||
	root_container.sway_root->output_layout = wlr_output_layout_create();
 | 
						root_container.sway_root->output_layout = wlr_output_layout_create();
 | 
				
			||||||
	wl_list_init(&root_container.sway_root->unmanaged_views);
 | 
						wl_list_init(&root_container.sway_root->xwayland_unmanaged);
 | 
				
			||||||
	wl_signal_init(&root_container.sway_root->events.new_container);
 | 
						wl_signal_init(&root_container.sway_root->events.new_container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	root_container.sway_root->output_layout_change.notify =
 | 
						root_container.sway_root->output_layout_change.notify =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,6 @@ struct sway_view *view_create(enum sway_view_type type,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	view->type = type;
 | 
						view->type = type;
 | 
				
			||||||
	view->impl = impl;
 | 
						view->impl = impl;
 | 
				
			||||||
	wl_list_init(&view->unmanaged_view_link);
 | 
					 | 
				
			||||||
	return view;
 | 
						return view;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +26,8 @@ void view_destroy(struct sway_view *view) {
 | 
				
			||||||
	if (view->surface != NULL) {
 | 
						if (view->surface != NULL) {
 | 
				
			||||||
		view_unmap(view);
 | 
							view_unmap(view);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (view->swayc != NULL) {
 | 
					 | 
				
			||||||
		container_view_destroy(view->swayc);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						container_view_destroy(view->swayc);
 | 
				
			||||||
	free(view);
 | 
						free(view);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,15 +103,10 @@ void view_damage_from(struct sway_view *view) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) {
 | 
					static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) {
 | 
				
			||||||
	struct sway_container *cont = container_parent(view->swayc, C_OUTPUT);
 | 
						struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_output_layout *output_layout =
 | 
						box->x = output->x + view->swayc->x;
 | 
				
			||||||
		root_container.sway_root->output_layout;
 | 
						box->y = output->y + view->swayc->y;
 | 
				
			||||||
	struct wlr_box *output_box = wlr_output_layout_get_box(output_layout,
 | 
					 | 
				
			||||||
		cont->sway_output->wlr_output);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	box->x = output_box->x + view->swayc->x;
 | 
					 | 
				
			||||||
	box->y = output_box->y + view->swayc->y;
 | 
					 | 
				
			||||||
	box->width = view->width;
 | 
						box->width = view->width;
 | 
				
			||||||
	box->height = view->height;
 | 
						box->height = view->height;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -161,23 +153,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
 | 
				
			||||||
	view_update_outputs(view, NULL);
 | 
						view_update_outputs(view, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_map_unmanaged(struct sway_view *view,
 | 
					 | 
				
			||||||
		struct wlr_surface *wlr_surface) {
 | 
					 | 
				
			||||||
	if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	view->surface = wlr_surface;
 | 
					 | 
				
			||||||
	view->swayc = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_insert(&root_container.sway_root->unmanaged_views,
 | 
					 | 
				
			||||||
		&view->unmanaged_view_link);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	view_damage_whole(view);
 | 
					 | 
				
			||||||
	// TODO: make this work for unmanaged views
 | 
					 | 
				
			||||||
	//view_update_outputs(view, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void view_unmap(struct sway_view *view) {
 | 
					void view_unmap(struct sway_view *view) {
 | 
				
			||||||
	if (!sway_assert(view->surface != NULL, "cannot unmap unmapped view")) {
 | 
						if (!sway_assert(view->surface != NULL, "cannot unmap unmapped view")) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -185,9 +160,6 @@ void view_unmap(struct sway_view *view) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view_damage_whole(view);
 | 
						view_damage_whole(view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&view->unmanaged_view_link);
 | 
					 | 
				
			||||||
	wl_list_init(&view->unmanaged_view_link);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	container_view_destroy(view->swayc);
 | 
						container_view_destroy(view->swayc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view->swayc = NULL;
 | 
						view->swayc = NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue