mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	view: associate launch contexts with views
Views now maintain a reference to a launch context which, as a last
resort, is populated at map time with a context associated with its pid.
This opens the possibility of populating it before map via another
source, e.g. xdga-tokens or configuration.
(cherry picked from commit 864b3a9a18)
			
			
This commit is contained in:
		
							parent
							
								
									9d78ede905
								
							
						
					
					
						commit
						5794a223ce
					
				
					 4 changed files with 64 additions and 39 deletions
				
			
		| 
						 | 
					@ -3,10 +3,26 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_workspace *workspace_for_pid(pid_t pid);
 | 
					struct launcher_ctx {
 | 
				
			||||||
 | 
						pid_t pid;
 | 
				
			||||||
 | 
						char *name;
 | 
				
			||||||
 | 
						struct wlr_xdg_activation_token_v1 *token;
 | 
				
			||||||
 | 
						struct wl_listener token_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct sway_node *node;
 | 
				
			||||||
 | 
						struct wl_listener node_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_list link; // sway_server::pending_launcher_ctxs
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct launcher_ctx *launcher_ctx_find_pid(pid_t pid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sway_workspace *launcher_ctx_get_workspace(struct launcher_ctx *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void launcher_ctx_consume(struct launcher_ctx *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void launcher_ctx_destroy(struct launcher_ctx *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void launcher_ctx_create(pid_t pid);
 | 
					void launcher_ctx_create(pid_t pid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void remove_workspace_pid(pid_t pid);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,7 @@ struct sway_view {
 | 
				
			||||||
	struct sway_xdg_decoration *xdg_decoration;
 | 
						struct sway_xdg_decoration *xdg_decoration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pid_t pid;
 | 
						pid_t pid;
 | 
				
			||||||
 | 
						struct launcher_ctx *ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The size the view would want to be if it weren't tiled.
 | 
						// The size the view would want to be if it weren't tiled.
 | 
				
			||||||
	// Used when changing a view from tiled to floating.
 | 
						// Used when changing a view from tiled to floating.
 | 
				
			||||||
| 
						 | 
					@ -372,4 +373,6 @@ void view_save_buffer(struct sway_view *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
 | 
					bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,18 +13,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wl_list launcher_ctxs;
 | 
					static struct wl_list launcher_ctxs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct launcher_ctx {
 | 
					 | 
				
			||||||
	pid_t pid;
 | 
					 | 
				
			||||||
	char *name;
 | 
					 | 
				
			||||||
	struct wlr_xdg_activation_token_v1 *token;
 | 
					 | 
				
			||||||
	struct wl_listener token_destroy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sway_node *node;
 | 
					 | 
				
			||||||
	struct wl_listener node_destroy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_list link;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Get the pid of a parent process given the pid of a child process.
 | 
					 * Get the pid of a parent process given the pid of a child process.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -59,7 +47,20 @@ static pid_t get_parent_pid(pid_t child) {
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void launcher_ctx_destroy(struct launcher_ctx *ctx) {
 | 
					void launcher_ctx_consume(struct launcher_ctx *ctx) {
 | 
				
			||||||
 | 
						// The view is now responsible for destroying this ctx
 | 
				
			||||||
 | 
						wl_list_remove(&ctx->token_destroy.link);
 | 
				
			||||||
 | 
						wl_list_init(&ctx->token_destroy.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_xdg_activation_token_v1_destroy(ctx->token);
 | 
				
			||||||
 | 
						ctx->token = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Prevent additional matches
 | 
				
			||||||
 | 
						wl_list_remove(&ctx->link);
 | 
				
			||||||
 | 
						wl_list_init(&ctx->link);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void launcher_ctx_destroy(struct launcher_ctx *ctx) {
 | 
				
			||||||
	if (ctx == NULL) {
 | 
						if (ctx == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -71,7 +72,7 @@ static void launcher_ctx_destroy(struct launcher_ctx *ctx) {
 | 
				
			||||||
	free(ctx);
 | 
						free(ctx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
 | 
					struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
 | 
				
			||||||
	if (!launcher_ctxs.prev && !launcher_ctxs.next) {
 | 
						if (!launcher_ctxs.prev && !launcher_ctxs.next) {
 | 
				
			||||||
		wl_list_init(&launcher_ctxs);
 | 
							wl_list_init(&launcher_ctxs);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					@ -97,7 +98,7 @@ static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
 | 
				
			||||||
	return ctx;
 | 
						return ctx;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sway_workspace *launcher_ctx_get_workspace(
 | 
					struct sway_workspace *launcher_ctx_get_workspace(
 | 
				
			||||||
		struct launcher_ctx *ctx) {
 | 
							struct launcher_ctx *ctx) {
 | 
				
			||||||
	struct sway_workspace *ws = NULL;
 | 
						struct sway_workspace *ws = NULL;
 | 
				
			||||||
	struct sway_output *output = NULL;
 | 
						struct sway_output *output = NULL;
 | 
				
			||||||
| 
						 | 
					@ -135,16 +136,6 @@ static struct sway_workspace *launcher_ctx_get_workspace(
 | 
				
			||||||
	return ws;
 | 
						return ws;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_workspace *workspace_for_pid(pid_t pid) {
 | 
					 | 
				
			||||||
	struct launcher_ctx *ctx = launcher_ctx_find_pid(pid);
 | 
					 | 
				
			||||||
	if (ctx == NULL) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	struct sway_workspace *ws = launcher_ctx_get_workspace(ctx);
 | 
					 | 
				
			||||||
	launcher_ctx_destroy(ctx);
 | 
					 | 
				
			||||||
	return ws;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) {
 | 
					static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy);
 | 
						struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy);
 | 
				
			||||||
	switch (ctx->node->type) {
 | 
						switch (ctx->node->type) {
 | 
				
			||||||
| 
						 | 
					@ -217,12 +208,3 @@ void launcher_ctx_create(pid_t pid) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&launcher_ctxs, &ctx->link);
 | 
						wl_list_insert(&launcher_ctxs, &ctx->link);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void remove_workspace_pid(pid_t pid) {
 | 
					 | 
				
			||||||
	if (!launcher_ctxs.prev || !launcher_ctxs.next) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct launcher_ctx *ctx = launcher_ctx_find_pid(pid);
 | 
					 | 
				
			||||||
	launcher_ctx_destroy(ctx);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,8 @@ void view_destroy(struct sway_view *view) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	list_free(view->executed_criteria);
 | 
						list_free(view->executed_criteria);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view_assign_ctx(view, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(view->title_format);
 | 
						free(view->title_format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (view->impl->destroy) {
 | 
						if (view->impl->destroy) {
 | 
				
			||||||
| 
						 | 
					@ -534,6 +536,20 @@ static void view_populate_pid(struct sway_view *view) {
 | 
				
			||||||
	view->pid = pid;
 | 
						view->pid = pid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx) {
 | 
				
			||||||
 | 
						if (view->ctx) {
 | 
				
			||||||
 | 
							// This ctx has been replaced
 | 
				
			||||||
 | 
							launcher_ctx_destroy(view->ctx);
 | 
				
			||||||
 | 
							view->ctx = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (ctx == NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						launcher_ctx_consume(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						view->ctx = ctx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sway_workspace *select_workspace(struct sway_view *view) {
 | 
					static struct sway_workspace *select_workspace(struct sway_view *view) {
 | 
				
			||||||
	struct sway_seat *seat = input_manager_current_seat();
 | 
						struct sway_seat *seat = input_manager_current_seat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -569,13 +585,14 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	list_free(criterias);
 | 
						list_free(criterias);
 | 
				
			||||||
	if (ws) {
 | 
						if (ws) {
 | 
				
			||||||
		remove_workspace_pid(view->pid);
 | 
							view_assign_ctx(view, NULL);
 | 
				
			||||||
		return ws;
 | 
							return ws;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if there's a PID mapping
 | 
						// Check if there's a PID mapping
 | 
				
			||||||
	ws = workspace_for_pid(view->pid);
 | 
						ws = view->ctx ? launcher_ctx_get_workspace(view->ctx) : NULL;
 | 
				
			||||||
	if (ws) {
 | 
						if (ws) {
 | 
				
			||||||
 | 
							view_assign_ctx(view, NULL);
 | 
				
			||||||
		return ws;
 | 
							return ws;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -718,6 +735,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
 | 
				
			||||||
	view_populate_pid(view);
 | 
						view_populate_pid(view);
 | 
				
			||||||
	view->container = container_create(view);
 | 
						view->container = container_create(view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (view->ctx == NULL) {
 | 
				
			||||||
 | 
							struct launcher_ctx *ctx = launcher_ctx_find_pid(view->pid);
 | 
				
			||||||
 | 
							if (ctx != NULL) {
 | 
				
			||||||
 | 
								view_assign_ctx(view, ctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If there is a request to be opened fullscreen on a specific output, try
 | 
						// If there is a request to be opened fullscreen on a specific output, try
 | 
				
			||||||
	// to honor that request. Otherwise, fallback to assigns, pid mappings,
 | 
						// to honor that request. Otherwise, fallback to assigns, pid mappings,
 | 
				
			||||||
	// focused workspace, etc
 | 
						// focused workspace, etc
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue