From c5a6c37275978ddc8c221ca73ae1a39254dd68f5 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 21 Oct 2018 11:26:22 +1000 Subject: [PATCH] Make workspace back_and_forth seat-specific * When using multiple seats, each seat has its own prev_workspace_name for the purpose of workspace back_and_forth. * Removes prev_workspace_name global variable. * Removes unused next_name_map function in tree/workspace.c. * Fixes memory leak in seat_destroy (seat was not freed). --- include/sway/input/seat.h | 1 + include/sway/tree/workspace.h | 2 -- sway/commands/move.c | 8 ++++---- sway/commands/swap.c | 8 ++++---- sway/commands/workspace.c | 5 +++-- sway/input/seat.c | 2 ++ sway/tree/view.c | 4 ++-- sway/tree/workspace.c | 35 ++++++++++++++++------------------- 8 files changed, 32 insertions(+), 33 deletions(-) diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index ef65810c..bef2af77 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -51,6 +51,7 @@ struct sway_seat { bool has_focus; struct wl_list focus_stack; // list of containers in focus order struct sway_workspace *workspace; + char *prev_workspace_name; // for workspace back_and_forth // If the focused layer is set, views cannot receive keyboard focus struct wlr_layer_surface_v1 *focused_layer; diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index efdae5a1..b5ae92f3 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -45,8 +45,6 @@ struct sway_workspace { struct sway_workspace_state current; }; -extern char *prev_workspace_name; - struct workspace_config *workspace_find_config(const char *ws_name); struct sway_output *workspace_get_initial_output(const char *name); diff --git a/sway/commands/move.c b/sway/commands/move.c index 941b284a..a5b7f661 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -429,8 +429,8 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) { ws = workspace_by_name(argv[2]); } else if (strcasecmp(argv[2], "back_and_forth") == 0) { if (!(ws = workspace_by_name(argv[2]))) { - if (prev_workspace_name) { - ws_name = strdup(prev_workspace_name); + if (seat->prev_workspace_name) { + ws_name = strdup(seat->prev_workspace_name); } else { return cmd_results_new(CMD_FAILURE, "move", "No workspace was previously active."); @@ -455,13 +455,13 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) { } if (!no_auto_back_and_forth && config->auto_back_and_forth && - prev_workspace_name) { + seat->prev_workspace_name) { // auto back and forth move if (old_ws && old_ws->name && strcmp(old_ws->name, ws_name) == 0) { // if target workspace is the current one free(ws_name); - ws_name = strdup(prev_workspace_name); + ws_name = strdup(seat->prev_workspace_name); ws = workspace_by_name(ws_name); } } diff --git a/sway/commands/swap.c b/sway/commands/swap.c index 6062724d..afe11a47 100644 --- a/sway/commands/swap.c +++ b/sway/commands/swap.c @@ -116,8 +116,8 @@ static void container_swap(struct sway_container *con1, output_get_active_workspace(con2->workspace->output); char *stored_prev_name = NULL; - if (prev_workspace_name) { - stored_prev_name = strdup(prev_workspace_name); + if (seat->prev_workspace_name) { + stored_prev_name = strdup(seat->prev_workspace_name); } swap_places(con1, con2); @@ -132,8 +132,8 @@ static void container_swap(struct sway_container *con1, swap_focus(con1, con2, seat, focus); if (stored_prev_name) { - free(prev_workspace_name); - prev_workspace_name = stored_prev_name; + free(seat->prev_workspace_name); + seat->prev_workspace_name = stored_prev_name; } if (fs1) { diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index da597f8a..745b40c7 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -142,12 +142,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { strcasecmp(argv[0], "current") == 0) { ws = workspace_by_name(argv[0]); } else if (strcasecmp(argv[0], "back_and_forth") == 0) { - if (!prev_workspace_name) { + struct sway_seat *seat = config->handler_context.seat; + if (!seat->prev_workspace_name) { return cmd_results_new(CMD_INVALID, "workspace", "There is no previous workspace"); } if (!(ws = workspace_by_name(argv[0]))) { - ws = workspace_create(NULL, prev_workspace_name); + ws = workspace_create(NULL, seat->prev_workspace_name); } } else { char *name = join_args(argv, argc); diff --git a/sway/input/seat.c b/sway/input/seat.c index 2e352b19..16acc8a5 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -51,6 +51,8 @@ void seat_destroy(struct sway_seat *seat) { wl_list_remove(&seat->new_drag_icon.link); wl_list_remove(&seat->link); wlr_seat_destroy(seat->wlr_seat); + free(seat->prev_workspace_name); + free(seat); } static struct sway_seat_node *seat_node_from_node( diff --git a/sway/tree/view.c b/sway/tree/view.c index 85afbb87..b23afb97 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -465,8 +465,8 @@ static struct sway_workspace *select_workspace(struct sway_view *view) { if (!ws) { if (strcasecmp(criteria->target, "back_and_forth") == 0) { - if (prev_workspace_name) { - ws = workspace_create(NULL, prev_workspace_name); + if (seat->prev_workspace_name) { + ws = workspace_create(NULL, seat->prev_workspace_name); } } else { ws = workspace_create(NULL, criteria->target); diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index fff16515..65284679 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -140,13 +140,6 @@ void workspace_consider_destroy(struct sway_workspace *ws) { workspace_begin_destroy(ws); } -char *prev_workspace_name = NULL; - -void next_name_map(struct sway_container *ws, void *data) { - int *count = data; - ++count; -} - static bool workspace_valid_on_output(const char *output_name, const char *ws_name) { struct workspace_config *wsc = workspace_find_config(ws_name); @@ -309,9 +302,12 @@ struct sway_workspace *workspace_by_name(const char *name) { } else if (strcmp(name, "current") == 0) { return current; } else if (strcasecmp(name, "back_and_forth") == 0) { - return prev_workspace_name ? - root_find_workspace(_workspace_by_name, (void*)prev_workspace_name) - : NULL; + struct sway_seat *seat = input_manager_current_seat(); + if (!seat->prev_workspace_name) { + return NULL; + } + return root_find_workspace(_workspace_by_name, + (void*)seat->prev_workspace_name); } else { return root_find_workspace(_workspace_by_name, (void*)name); } @@ -380,23 +376,24 @@ bool workspace_switch(struct sway_workspace *workspace, struct sway_workspace *active_ws = seat_get_focused_workspace(seat); if (!no_auto_back_and_forth && config->auto_back_and_forth - && active_ws == workspace - && prev_workspace_name) { - struct sway_workspace *new_ws = workspace_by_name(prev_workspace_name); + && active_ws == workspace && seat->prev_workspace_name) { + struct sway_workspace *new_ws = + workspace_by_name(seat->prev_workspace_name); workspace = new_ws ? new_ws : - workspace_create(NULL, prev_workspace_name); + workspace_create(NULL, seat->prev_workspace_name); } - if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) + if (!seat->prev_workspace_name || + (strcmp(seat->prev_workspace_name, active_ws->name) && active_ws != workspace)) { - free(prev_workspace_name); - prev_workspace_name = malloc(strlen(active_ws->name) + 1); - if (!prev_workspace_name) { + free(seat->prev_workspace_name); + seat->prev_workspace_name = malloc(strlen(active_ws->name) + 1); + if (!seat->prev_workspace_name) { wlr_log(WLR_ERROR, "Unable to allocate previous workspace name"); return false; } - strcpy(prev_workspace_name, active_ws->name); + strcpy(seat->prev_workspace_name, active_ws->name); } wlr_log(WLR_DEBUG, "Switching to workspace %p:%s",