mirror of
https://github.com/swaywm/sway.git
synced 2024-10-31 21:47:24 +00: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
|
@ -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…
Reference in a new issue