WIP Output-namespaced workspaces

This commit is contained in:
Kenny Levinsen 2019-12-23 13:36:55 +01:00
parent 088b374b1a
commit 59e308480e
14 changed files with 127 additions and 51 deletions

View file

@ -190,6 +190,7 @@ sway_cmd cmd_unmark;
sway_cmd cmd_urgent; sway_cmd cmd_urgent;
sway_cmd cmd_workspace; sway_cmd cmd_workspace;
sway_cmd cmd_workspace_layout; sway_cmd cmd_workspace_layout;
sway_cmd cmd_workspace_namespace;
sway_cmd cmd_ws_auto_back_and_forth; sway_cmd cmd_ws_auto_back_and_forth;
sway_cmd cmd_xwayland; sway_cmd cmd_xwayland;

View file

@ -471,6 +471,11 @@ enum xwayland_mode {
XWAYLAND_MODE_IMMEDIATE XWAYLAND_MODE_IMMEDIATE
}; };
enum sway_workspace_namespace {
WORKSPACE_NAMESPACE_GLOBAL,
WORKSPACE_NAMESPACE_OUTPUT,
};
/** /**
* The configuration struct. The result of loading a config file. * The configuration struct. The result of loading a config file.
*/ */
@ -512,6 +517,7 @@ struct sway_config {
enum sway_fowa focus_on_window_activation; enum sway_fowa focus_on_window_activation;
enum sway_popup_during_fullscreen popup_during_fullscreen; enum sway_popup_during_fullscreen popup_during_fullscreen;
enum xwayland_mode xwayland; enum xwayland_mode xwayland;
enum sway_workspace_namespace workspace_namespace;
// swaybg // swaybg
char *swaybg_command; char *swaybg_command;

View file

@ -58,14 +58,14 @@ void workspace_begin_destroy(struct sway_workspace *workspace);
void workspace_consider_destroy(struct sway_workspace *ws); void workspace_consider_destroy(struct sway_workspace *ws);
char *workspace_next_name(const char *output_name); char *workspace_next_name(struct sway_output *output);
bool workspace_switch(struct sway_workspace *workspace, bool workspace_switch(struct sway_workspace *workspace,
bool no_auto_back_and_forth); bool no_auto_back_and_forth);
struct sway_workspace *workspace_by_number(const char* name); struct sway_workspace *workspace_by_number(struct sway_output *output, const char* name);
struct sway_workspace *workspace_by_name(const char*); struct sway_workspace *workspace_by_name(struct sway_output *output, const char* name);
struct sway_workspace *workspace_output_next( struct sway_workspace *workspace_output_next(
struct sway_workspace *current, bool create); struct sway_workspace *current, bool create);

View file

@ -105,6 +105,7 @@ static struct cmd_handler config_handlers[] = {
{ "swaybg_command", cmd_swaybg_command }, { "swaybg_command", cmd_swaybg_command },
{ "swaynag_command", cmd_swaynag_command }, { "swaynag_command", cmd_swaynag_command },
{ "workspace_layout", cmd_workspace_layout }, { "workspace_layout", cmd_workspace_layout },
{ "workspace_namespace", cmd_workspace_namespace },
{ "xwayland", cmd_xwayland }, { "xwayland", cmd_xwayland },
}; };

View file

@ -430,9 +430,9 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
strcasecmp(argv[1], "next_on_output") == 0 || strcasecmp(argv[1], "next_on_output") == 0 ||
strcasecmp(argv[1], "prev_on_output") == 0 || strcasecmp(argv[1], "prev_on_output") == 0 ||
strcasecmp(argv[1], "current") == 0) { strcasecmp(argv[1], "current") == 0) {
ws = workspace_by_name(argv[1]); ws = workspace_by_name(old_output, argv[1]);
} else if (strcasecmp(argv[1], "back_and_forth") == 0) { } else if (strcasecmp(argv[1], "back_and_forth") == 0) {
if (!(ws = workspace_by_name(argv[1]))) { if (!(ws = workspace_by_name(old_output, argv[1]))) {
if (seat->prev_workspace_name) { if (seat->prev_workspace_name) {
ws_name = strdup(seat->prev_workspace_name); ws_name = strdup(seat->prev_workspace_name);
} else { } else {
@ -451,10 +451,10 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
"Invalid workspace number '%s'", argv[2]); "Invalid workspace number '%s'", argv[2]);
} }
ws_name = join_args(argv + 2, argc - 2); ws_name = join_args(argv + 2, argc - 2);
ws = workspace_by_number(ws_name); ws = workspace_by_number(old_output, ws_name);
} else { } else {
ws_name = join_args(argv + 1, argc - 1); ws_name = join_args(argv + 1, argc - 1);
ws = workspace_by_name(ws_name); ws = workspace_by_name(old_output, ws_name);
} }
if (!no_auto_back_and_forth && config->auto_back_and_forth && if (!no_auto_back_and_forth && config->auto_back_and_forth &&
@ -465,7 +465,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
// if target workspace is the current one // if target workspace is the current one
free(ws_name); free(ws_name);
ws_name = strdup(seat->prev_workspace_name); ws_name = strdup(seat->prev_workspace_name);
ws = workspace_by_name(ws_name); ws = workspace_by_name(old_output, ws_name);
} }
} }
} }
@ -483,7 +483,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
"on the same output"); "on the same output");
} }
} }
ws = workspace_create(NULL, ws_name); ws = workspace_create(old_output, ws_name);
} }
free(ws_name); free(ws_name);
struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws); struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws);
@ -614,7 +614,7 @@ static void workspace_move_to_output(struct sway_workspace *workspace,
// on the old output // on the old output
struct sway_seat *seat = config->handler_context.seat; struct sway_seat *seat = config->handler_context.seat;
if (old_output->workspaces->length == 0) { if (old_output->workspaces->length == 0) {
char *ws_name = workspace_next_name(old_output->wlr_output->name); char *ws_name = workspace_next_name(old_output);
struct sway_workspace *ws = workspace_create(old_output, ws_name); struct sway_workspace *ws = workspace_create(old_output, ws_name);
free(ws_name); free(ws_name);
seat_set_raw_focus(seat, &ws->node); seat_set_raw_focus(seat, &ws->node);
@ -658,6 +658,11 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Can't find output with name/direction '%s'", argv[0]); "Can't find output with name/direction '%s'", argv[0]);
} }
if (config->workspace_namespace == WORKSPACE_NAMESPACE_OUTPUT &&
workspace_by_name(new_output, workspace->name) != NULL) {
free(workspace->name);
workspace->name = workspace_next_name(new_output);
}
workspace_move_to_output(workspace, new_output); workspace_move_to_output(workspace, new_output);
arrange_output(old_output); arrange_output(old_output);

View file

@ -31,6 +31,12 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
int argn = 1; int argn = 1;
struct sway_workspace *workspace = NULL; struct sway_workspace *workspace = NULL;
struct sway_seat *seat = config->handler_context.seat;
struct sway_workspace *current = seat_get_focused_workspace(seat);
if (!current) {
return cmd_results_new(CMD_FAILURE, "No workspace available");
}
if (strcasecmp(argv[1], "to") == 0) { if (strcasecmp(argv[1], "to") == 0) {
// 'rename workspace to new_name' // 'rename workspace to new_name'
workspace = config->handler_context.workspace; workspace = config->handler_context.workspace;
@ -40,7 +46,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"Invalid workspace number '%s'", argv[2]); "Invalid workspace number '%s'", argv[2]);
} }
workspace = workspace_by_number(argv[2]); workspace = workspace_by_number(current->output, argv[2]);
while (argn < argc && strcasecmp(argv[argn], "to") != 0) { while (argn < argc && strcasecmp(argv[argn], "to") != 0) {
++argn; ++argn;
} }
@ -51,7 +57,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
++end; ++end;
} }
char *old_name = join_args(argv + argn, end - argn); char *old_name = join_args(argv + argn, end - argn);
workspace = workspace_by_name(old_name); workspace = workspace_by_name(current->output, old_name);
free(old_name); free(old_name);
argn = end; argn = end;
} }
@ -79,7 +85,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"Cannot use special workspace name '%s'", argv[argn]); "Cannot use special workspace name '%s'", argv[argn]);
} }
struct sway_workspace *tmp_workspace = workspace_by_name(new_name); struct sway_workspace *tmp_workspace = workspace_by_name(current->output, new_name);
if (tmp_workspace) { if (tmp_workspace) {
free(new_name); free(new_name);
if (tmp_workspace == workspace) { if (tmp_workspace == workspace) {

View file

@ -198,15 +198,15 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"Invalid workspace number '%s'", argv[1]); "Invalid workspace number '%s'", argv[1]);
} }
if (!(ws = workspace_by_number(argv[1]))) { if (!(ws = workspace_by_number(current->output, argv[1]))) {
char *name = join_args(argv + 1, argc - 1); char *name = join_args(argv + 1, argc - 1);
ws = workspace_create(NULL, name); ws = workspace_create(current->output, name);
free(name); free(name);
} }
} else if (strcasecmp(argv[0], "next") == 0 || } else if (strcasecmp(argv[0], "next") == 0 ||
strcasecmp(argv[0], "prev") == 0 || strcasecmp(argv[0], "prev") == 0 ||
strcasecmp(argv[0], "current") == 0) { strcasecmp(argv[0], "current") == 0) {
ws = workspace_by_name(argv[0]); ws = workspace_by_name(current->output, argv[0]);
} else if (strcasecmp(argv[0], "next_on_output") == 0) { } else if (strcasecmp(argv[0], "next_on_output") == 0) {
ws = workspace_output_next(current, create); ws = workspace_output_next(current, create);
} else if (strcasecmp(argv[0], "prev_on_output") == 0) { } else if (strcasecmp(argv[0], "prev_on_output") == 0) {
@ -216,13 +216,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"There is no previous workspace"); "There is no previous workspace");
} }
if (!(ws = workspace_by_name(argv[0]))) { if (!(ws = workspace_by_name(current->output, argv[0]))) {
ws = workspace_create(NULL, seat->prev_workspace_name); ws = workspace_create(current->output, seat->prev_workspace_name);
} }
} else { } else {
char *name = join_args(argv, argc); char *name = join_args(argv, argc);
if (!(ws = workspace_by_name(name))) { if (!(ws = workspace_by_name(current->output, name))) {
ws = workspace_create(NULL, name); ws = workspace_create(current->output, name);
} }
free(name); free(name);
} }

View file

@ -0,0 +1,27 @@
#include <strings.h>
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "util.h"
// workspace_namespace [global|output]
struct cmd_results *cmd_workspace_namespace(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "workspace_namespace", EXPECTED_EQUAL_TO, 1))) {
return error;
}
if (strcasecmp(argv[0], "global") == 0 ||
strcasecmp(argv[0], "default") == 0) {
config->workspace_namespace = WORKSPACE_NAMESPACE_GLOBAL;
} else if (strcasecmp(argv[0], "output") == 0) {
config->workspace_namespace = WORKSPACE_NAMESPACE_OUTPUT;
} else {
return cmd_results_new(CMD_FAILURE,
"Expected 'workspace_namespace <default|global|output>'");
}
return cmd_results_new(CMD_SUCCESS, NULL);
}

View file

@ -114,6 +114,7 @@ sway_sources = files(
'commands/urgent.c', 'commands/urgent.c',
'commands/workspace.c', 'commands/workspace.c',
'commands/workspace_layout.c', 'commands/workspace_layout.c',
'commands/workspace_namespace.c',
'commands/ws_auto_back_and_forth.c', 'commands/ws_auto_back_and_forth.c',
'commands/xwayland.c', 'commands/xwayland.c',

View file

@ -88,6 +88,9 @@ The following commands may only be used in the configuration file.
*workspace_layout* default|stacking|tabbed *workspace_layout* default|stacking|tabbed
Specifies the initial layout for new workspaces. Specifies the initial layout for new workspaces.
*workspace_namespace* default|global|output
Specifies the workspace namespacing.
*xwayland* enable|disable|force *xwayland* enable|disable|force
Enables or disables Xwayland support, which allows X11 applications to be Enables or disables Xwayland support, which allows X11 applications to be
used. _enable_ will lazily load Xwayland so Xwayland will not be launched used. _enable_ will lazily load Xwayland so Xwayland will not be launched

View file

@ -48,7 +48,7 @@ static void restore_workspaces(struct sway_output *output) {
} }
if (other->workspaces->length == 0) { if (other->workspaces->length == 0) {
char *next = workspace_next_name(other->wlr_output->name); char *next = workspace_next_name(other);
struct sway_workspace *ws = workspace_create(other, next); struct sway_workspace *ws = workspace_create(other, next);
free(next); free(next);
ipc_event_workspace(NULL, ws, "init"); ipc_event_workspace(NULL, ws, "init");
@ -109,7 +109,6 @@ bool output_enable(struct sway_output *output, struct output_config *oc) {
if (!sway_assert(!output->enabled, "output is already enabled")) { if (!sway_assert(!output->enabled, "output is already enabled")) {
return false; return false;
} }
struct wlr_output *wlr_output = output->wlr_output;
size_t len = sizeof(output->layers) / sizeof(output->layers[0]); size_t len = sizeof(output->layers) / sizeof(output->layers[0]);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
wl_list_init(&output->layers[i]); wl_list_init(&output->layers[i]);
@ -129,7 +128,7 @@ bool output_enable(struct sway_output *output, struct output_config *oc) {
struct sway_workspace *ws = NULL; struct sway_workspace *ws = NULL;
if (!output->workspaces->length) { if (!output->workspaces->length) {
// Create workspace // Create workspace
char *ws_name = workspace_next_name(wlr_output->name); char *ws_name = workspace_next_name(output);
sway_log(SWAY_DEBUG, "Creating default workspace %s", ws_name); sway_log(SWAY_DEBUG, "Creating default workspace %s", ws_name);
ws = workspace_create(output, ws_name); ws = workspace_create(output, ws_name);
// Set each seat's focus if not already set // Set each seat's focus if not already set
@ -212,6 +211,13 @@ static void output_evacuate(struct sway_output *output) {
continue; continue;
} }
if (config->workspace_namespace == WORKSPACE_NAMESPACE_OUTPUT &&
workspace_by_name(new_output, workspace->name) != NULL) {
// Rename the workspace to avoid name collision
free(workspace->name);
workspace->name = workspace_next_name(new_output);
}
struct sway_workspace *new_output_ws = struct sway_workspace *new_output_ws =
output_get_active_workspace(new_output); output_get_active_workspace(new_output);

View file

@ -252,7 +252,7 @@ struct sway_workspace *root_workspace_for_pid(pid_t pid) {
found: found:
if (pw && pw->workspace) { if (pw && pw->workspace) {
ws = workspace_by_name(pw->workspace); ws = workspace_by_name(pw->output, pw->workspace);
if (!ws) { if (!ws) {
sway_log(SWAY_DEBUG, sway_log(SWAY_DEBUG,

View file

@ -470,6 +470,11 @@ static void view_populate_pid(struct sway_view *view) {
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();
struct sway_workspace *current = seat_get_focused_workspace(seat);
if (!sway_assert(current != NULL, "no workspace is focused")) {
return NULL;
}
struct sway_output *output = current->output;
// Check if there's any `assign` criteria for the view // Check if there's any `assign` criteria for the view
list_t *criterias = criteria_for_view(view, list_t *criterias = criteria_for_view(view,
@ -486,16 +491,16 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
} else { } else {
// CT_ASSIGN_WORKSPACE(_NUMBER) // CT_ASSIGN_WORKSPACE(_NUMBER)
ws = criteria->type == CT_ASSIGN_WORKSPACE_NUMBER ? ws = criteria->type == CT_ASSIGN_WORKSPACE_NUMBER ?
workspace_by_number(criteria->target) : workspace_by_number(output, criteria->target) :
workspace_by_name(criteria->target); workspace_by_name(output, criteria->target);
if (!ws) { if (!ws) {
if (strcasecmp(criteria->target, "back_and_forth") == 0) { if (strcasecmp(criteria->target, "back_and_forth") == 0) {
if (seat->prev_workspace_name) { if (seat->prev_workspace_name) {
ws = workspace_create(NULL, seat->prev_workspace_name); ws = workspace_create(output, seat->prev_workspace_name);
} }
} else { } else {
ws = workspace_create(NULL, criteria->target); ws = workspace_create(output, criteria->target);
} }
} }
break; break;

View file

@ -171,15 +171,14 @@ void workspace_consider_destroy(struct sway_workspace *ws) {
workspace_begin_destroy(ws); workspace_begin_destroy(ws);
} }
static bool workspace_valid_on_output(const char *output_name, static bool workspace_valid_on_output(struct sway_output *output,
const char *ws_name) { const char *ws_name) {
struct workspace_config *wsc = workspace_find_config(ws_name); struct workspace_config *wsc = workspace_find_config(ws_name);
char identifier[128]; char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) { if (!output) {
return false; return false;
} }
output_name = output->wlr_output->name; char *output_name = output->wlr_output->name;
output_get_identifier(identifier, sizeof(identifier), output); output_get_identifier(identifier, sizeof(identifier), output);
if (!wsc) { if (!wsc) {
@ -198,7 +197,7 @@ static bool workspace_valid_on_output(const char *output_name,
} }
static void workspace_name_from_binding(const struct sway_binding * binding, static void workspace_name_from_binding(const struct sway_binding * binding,
const char* output_name, int *min_order, char **earliest_name) { struct sway_output* output, int *min_order, char **earliest_name) {
char *cmdlist = strdup(binding->command); char *cmdlist = strdup(binding->command);
char *dup = cmdlist; char *dup = cmdlist;
char *name = NULL; char *name = NULL;
@ -245,7 +244,7 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
sway_log(SWAY_DEBUG, "Isolated name from workspace number: '%s'", _target); sway_log(SWAY_DEBUG, "Isolated name from workspace number: '%s'", _target);
// Make sure the workspace number doesn't already exist // Make sure the workspace number doesn't already exist
if (isdigit(_target[0]) && workspace_by_number(_target)) { if (isdigit(_target[0]) && workspace_by_number(output, _target)) {
free(_target); free(_target);
free(dup); free(dup);
return; return;
@ -253,7 +252,7 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
} }
// Make sure that the workspace doesn't already exist // Make sure that the workspace doesn't already exist
if (workspace_by_name(_target)) { if (workspace_by_name(output, _target)) {
free(_target); free(_target);
free(dup); free(dup);
return; return;
@ -261,7 +260,7 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
// make sure that the workspace can appear on the given // make sure that the workspace can appear on the given
// output // output
if (!workspace_valid_on_output(output_name, _target)) { if (!workspace_valid_on_output(output, _target)) {
free(_target); free(_target);
free(dup); free(dup);
return; return;
@ -279,7 +278,8 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
free(dup); free(dup);
} }
char *workspace_next_name(const char *output_name) { char *workspace_next_name(struct sway_output* output) {
char *output_name = output->wlr_output->name;
sway_log(SWAY_DEBUG, "Workspace: Generating new workspace name for output %s", sway_log(SWAY_DEBUG, "Workspace: Generating new workspace name for output %s",
output_name); output_name);
// Scan for available workspace names by looking through output-workspace // Scan for available workspace names by looking through output-workspace
@ -287,27 +287,22 @@ char *workspace_next_name(const char *output_name) {
struct sway_mode *mode = config->current_mode; struct sway_mode *mode = config->current_mode;
char identifier[128]; char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) {
return NULL;
}
output_name = output->wlr_output->name;
output_get_identifier(identifier, sizeof(identifier), output); output_get_identifier(identifier, sizeof(identifier), output);
int order = INT_MAX; int order = INT_MAX;
char *target = NULL; char *target = NULL;
for (int i = 0; i < mode->keysym_bindings->length; ++i) { for (int i = 0; i < mode->keysym_bindings->length; ++i) {
workspace_name_from_binding(mode->keysym_bindings->items[i], workspace_name_from_binding(mode->keysym_bindings->items[i],
output_name, &order, &target); output, &order, &target);
} }
for (int i = 0; i < mode->keycode_bindings->length; ++i) { for (int i = 0; i < mode->keycode_bindings->length; ++i) {
workspace_name_from_binding(mode->keycode_bindings->items[i], workspace_name_from_binding(mode->keycode_bindings->items[i],
output_name, &order, &target); output, &order, &target);
} }
for (int i = 0; i < config->workspace_configs->length; ++i) { for (int i = 0; i < config->workspace_configs->length; ++i) {
// Unlike with bindings, this does not guarantee order // Unlike with bindings, this does not guarantee order
const struct workspace_config *wsc = config->workspace_configs->items[i]; const struct workspace_config *wsc = config->workspace_configs->items[i];
if (workspace_by_name(wsc->workspace)) { if (workspace_by_name(output, wsc->workspace)) {
continue; continue;
} }
bool found = false; bool found = false;
@ -333,7 +328,7 @@ char *workspace_next_name(const char *output_name) {
unsigned int ws_num = 1; unsigned int ws_num = 1;
do { do {
snprintf(name, sizeof(name), "%u", ws_num++); snprintf(name, sizeof(name), "%u", ws_num++);
} while (workspace_by_number(name)); } while (workspace_by_number(output, name));
return strdup(name); return strdup(name);
} }
@ -348,7 +343,12 @@ static bool _workspace_by_number(struct sway_workspace *ws, void *data) {
return !isdigit(*ws_name); return !isdigit(*ws_name);
} }
struct sway_workspace *workspace_by_number(const char* name) { struct sway_workspace *workspace_by_number(struct sway_output *output,
const char* name) {
if (config->workspace_namespace == WORKSPACE_NAMESPACE_OUTPUT) {
return output_find_workspace(output, _workspace_by_number,
(void*)name);
}
return root_find_workspace(_workspace_by_number, (void *) name); return root_find_workspace(_workspace_by_number, (void *) name);
} }
@ -356,7 +356,8 @@ static bool _workspace_by_name(struct sway_workspace *ws, void *data) {
return strcasecmp(ws->name, data) == 0; return strcasecmp(ws->name, data) == 0;
} }
struct sway_workspace *workspace_by_name(const char *name) { struct sway_workspace *workspace_by_name(struct sway_output *output,
const char *name) {
struct sway_seat *seat = input_manager_current_seat(); struct sway_seat *seat = input_manager_current_seat();
struct sway_workspace *current = seat_get_focused_workspace(seat); struct sway_workspace *current = seat_get_focused_workspace(seat);
@ -375,9 +376,23 @@ struct sway_workspace *workspace_by_name(const char *name) {
if (!seat->prev_workspace_name) { if (!seat->prev_workspace_name) {
return NULL; return NULL;
} }
if (config->workspace_namespace == WORKSPACE_NAMESPACE_OUTPUT) {
if (output == NULL) {
return NULL;
}
return output_find_workspace(output, _workspace_by_name,
(void*)seat->prev_workspace_name);
}
return root_find_workspace(_workspace_by_name, return root_find_workspace(_workspace_by_name,
(void*)seat->prev_workspace_name); (void*)seat->prev_workspace_name);
} else { } else {
if (config->workspace_namespace == WORKSPACE_NAMESPACE_OUTPUT) {
if (output == NULL) {
return NULL;
}
return output_find_workspace(output, _workspace_by_name,
(void*)name);
}
return root_find_workspace(_workspace_by_name, (void*)name); return root_find_workspace(_workspace_by_name, (void*)name);
} }
} }
@ -401,7 +416,7 @@ static struct sway_workspace *workspace_output_prev_next_impl(
if (!workspace_is_empty(workspace) && create && if (!workspace_is_empty(workspace) && create &&
(index + dir < 0 || index + dir == output->workspaces->length)) { (index + dir < 0 || index + dir == output->workspaces->length)) {
struct sway_output *output = workspace->output; struct sway_output *output = workspace->output;
char *next = workspace_next_name(output->wlr_output->name); char *next = workspace_next_name(output);
workspace_create(output, next); workspace_create(output, next);
free(next); free(next);
} }
@ -467,10 +482,10 @@ bool workspace_switch(struct sway_workspace *workspace,
if (!no_auto_back_and_forth && config->auto_back_and_forth && active_ws if (!no_auto_back_and_forth && config->auto_back_and_forth && active_ws
&& active_ws == workspace && seat->prev_workspace_name) { && active_ws == workspace && seat->prev_workspace_name) {
struct sway_workspace *new_ws = struct sway_workspace *new_ws =
workspace_by_name(seat->prev_workspace_name); workspace_by_name(NULL, seat->prev_workspace_name);
workspace = new_ws ? workspace = new_ws ?
new_ws : new_ws :
workspace_create(NULL, seat->prev_workspace_name); workspace_create(active_ws->output, seat->prev_workspace_name);
} }
sway_log(SWAY_DEBUG, "Switching to workspace %p:%s", sway_log(SWAY_DEBUG, "Switching to workspace %p:%s",
@ -801,4 +816,4 @@ size_t workspace_num_tiling_views(struct sway_workspace *ws) {
size_t count = 0; size_t count = 0;
workspace_for_each_container(ws, count_tiling_views, &count); workspace_for_each_container(ws, count_tiling_views, &count);
return count; return count;
} }