Skip to content

Commit

Permalink
view: associate launch contexts with views
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rpigott authored and emersion committed Nov 26, 2022
1 parent d75c9f9 commit 864b3a9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 39 deletions.
22 changes: 19 additions & 3 deletions include/sway/desktop/launcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,26 @@

#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;

void launcher_ctx_create(pid_t pid);
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 remove_workspace_pid(pid_t pid);
void launcher_ctx_consume(struct launcher_ctx *ctx);

void launcher_ctx_destroy(struct launcher_ctx *ctx);

void launcher_ctx_create(pid_t pid);

#endif
3 changes: 3 additions & 0 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct sway_view {
struct sway_xdg_decoration *xdg_decoration;

pid_t pid;
struct launcher_ctx *ctx;

// The size the view would want to be if it weren't tiled.
// Used when changing a view from tiled to floating.
Expand Down Expand Up @@ -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);

void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);

#endif
50 changes: 16 additions & 34 deletions sway/desktop/launcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@

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.
*
Expand Down Expand Up @@ -59,7 +47,20 @@ static pid_t get_parent_pid(pid_t child) {
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) {
return;
}
Expand All @@ -71,7 +72,7 @@ static void launcher_ctx_destroy(struct launcher_ctx *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) {
wl_list_init(&launcher_ctxs);
return NULL;
Expand All @@ -97,7 +98,7 @@ static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
return ctx;
}

static struct sway_workspace *launcher_ctx_get_workspace(
struct sway_workspace *launcher_ctx_get_workspace(
struct launcher_ctx *ctx) {
struct sway_workspace *ws = NULL;
struct sway_output *output = NULL;
Expand Down Expand Up @@ -135,16 +136,6 @@ static struct sway_workspace *launcher_ctx_get_workspace(
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) {
struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy);
switch (ctx->node->type) {
Expand Down Expand Up @@ -217,12 +208,3 @@ void launcher_ctx_create(pid_t pid) {

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);
}
28 changes: 26 additions & 2 deletions sway/tree/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void view_destroy(struct sway_view *view) {
}
list_free(view->executed_criteria);

view_assign_ctx(view, NULL);

free(view->title_format);

if (view->impl->destroy) {
Expand Down Expand Up @@ -534,6 +536,20 @@ static void view_populate_pid(struct sway_view *view) {
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) {
struct sway_seat *seat = input_manager_current_seat();

Expand Down Expand Up @@ -569,13 +585,14 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
}
list_free(criterias);
if (ws) {
remove_workspace_pid(view->pid);
view_assign_ctx(view, NULL);
return ws;
}

// 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) {
view_assign_ctx(view, NULL);
return ws;
}

Expand Down Expand Up @@ -718,6 +735,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
view_populate_pid(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
// to honor that request. Otherwise, fallback to assigns, pid mappings,
// focused workspace, etc
Expand Down

0 comments on commit 864b3a9

Please sign in to comment.