mirror of
https://github.com/swaywm/sway.git
synced 2024-11-22 16:01:27 +00:00
Deny moving a sticky container to workspace if it's the same output
Rationale: Sticky containers are always assigned to the visible workspace. The basic idea here is to check the destination's output (move.c:190). But if the command was `move container to workspace x` then a workspace might have been created for it. We could destroy the workspace in this case, but that results in unnecessary IPC events. To avoid this, the logic for `move container to workspace x` has been adjusted. It now delays creating the workspace until the end, and uses `workspace_get_initial_output` to determine and check the output before creating it.
This commit is contained in:
parent
a0649190de
commit
5653fc754b
|
@ -16,6 +16,8 @@ struct sway_workspace {
|
|||
|
||||
extern char *prev_workspace_name;
|
||||
|
||||
struct sway_container *workspace_get_initial_output(const char *name);
|
||||
|
||||
char *workspace_next_name(const char *output_name);
|
||||
|
||||
bool workspace_switch(struct sway_container *workspace,
|
||||
|
|
|
@ -100,7 +100,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
// determine destination
|
||||
if (strcasecmp(argv[1], "workspace") == 0) {
|
||||
// move container to workspace x
|
||||
struct sway_container *ws;
|
||||
struct sway_container *ws = NULL;
|
||||
char *ws_name = NULL;
|
||||
if (strcasecmp(argv[2], "next") == 0 ||
|
||||
strcasecmp(argv[2], "prev") == 0 ||
|
||||
strcasecmp(argv[2], "next_on_output") == 0 ||
|
||||
|
@ -110,14 +111,13 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
} else if (strcasecmp(argv[2], "back_and_forth") == 0) {
|
||||
if (!(ws = workspace_by_name(argv[2]))) {
|
||||
if (prev_workspace_name) {
|
||||
ws = workspace_create(NULL, prev_workspace_name);
|
||||
ws_name = strdup(prev_workspace_name);
|
||||
} else {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"No workspace was previously active.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char *ws_name = NULL;
|
||||
if (strcasecmp(argv[2], "number") == 0) {
|
||||
// move "container to workspace number x"
|
||||
if (argc < 4) {
|
||||
|
@ -141,12 +141,26 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
ws = workspace_by_name(ws_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ws) {
|
||||
ws = workspace_create(NULL, ws_name);
|
||||
}
|
||||
free(ws_name);
|
||||
}
|
||||
if (!ws) {
|
||||
// We have to create the workspace, but if the container is
|
||||
// sticky and the workspace is going to be created on the same
|
||||
// output, we'll bail out first.
|
||||
if (container_is_floating(current) && current->is_sticky) {
|
||||
struct sway_container *old_output =
|
||||
container_parent(current, C_OUTPUT);
|
||||
struct sway_container *new_output =
|
||||
workspace_get_initial_output(ws_name);
|
||||
if (old_output == new_output) {
|
||||
free(ws_name);
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Can't move sticky container to another workspace "
|
||||
"on the same output");
|
||||
}
|
||||
}
|
||||
ws = workspace_create(NULL, ws_name);
|
||||
}
|
||||
free(ws_name);
|
||||
destination = seat_get_focus_inactive(config->handler_context.seat, ws);
|
||||
} else if (strcasecmp(argv[1], "output") == 0) {
|
||||
struct sway_container *source = container_parent(current, C_OUTPUT);
|
||||
|
@ -173,6 +187,16 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
return cmd_results_new(CMD_INVALID, "move", expected_syntax);
|
||||
}
|
||||
|
||||
if (container_is_floating(current) && current->is_sticky) {
|
||||
struct sway_container *old_output = container_parent(current, C_OUTPUT);
|
||||
struct sway_container *new_output = destination->type == C_OUTPUT ?
|
||||
destination : container_parent(destination, C_OUTPUT);
|
||||
if (old_output == new_output) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", "Can't move sticky "
|
||||
"container to another workspace on the same output");
|
||||
}
|
||||
}
|
||||
|
||||
// move container, arrange windows and return focus
|
||||
container_move_to(current, destination);
|
||||
struct sway_container *focus =
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct sway_container *get_workspace_initial_output(const char *name) {
|
||||
struct sway_container *workspace_get_initial_output(const char *name) {
|
||||
struct sway_container *parent;
|
||||
// Search for workspace<->output pair
|
||||
int e = config->workspace_outputs->length;
|
||||
|
@ -48,7 +48,7 @@ static struct sway_container *get_workspace_initial_output(const char *name) {
|
|||
struct sway_container *workspace_create(struct sway_container *output,
|
||||
const char *name) {
|
||||
if (output == NULL) {
|
||||
output = get_workspace_initial_output(name);
|
||||
output = workspace_get_initial_output(name);
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Added workspace %s for output %s", name, output->name);
|
||||
|
|
Loading…
Reference in a new issue