mirror of
https://github.com/swaywm/sway.git
synced 2024-11-23 00:11:28 +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;
|
extern char *prev_workspace_name;
|
||||||
|
|
||||||
|
struct sway_container *workspace_get_initial_output(const char *name);
|
||||||
|
|
||||||
char *workspace_next_name(const char *output_name);
|
char *workspace_next_name(const char *output_name);
|
||||||
|
|
||||||
bool workspace_switch(struct sway_container *workspace,
|
bool workspace_switch(struct sway_container *workspace,
|
||||||
|
|
|
@ -100,7 +100,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
||||||
// determine destination
|
// determine destination
|
||||||
if (strcasecmp(argv[1], "workspace") == 0) {
|
if (strcasecmp(argv[1], "workspace") == 0) {
|
||||||
// move container to workspace x
|
// move container to workspace x
|
||||||
struct sway_container *ws;
|
struct sway_container *ws = NULL;
|
||||||
|
char *ws_name = NULL;
|
||||||
if (strcasecmp(argv[2], "next") == 0 ||
|
if (strcasecmp(argv[2], "next") == 0 ||
|
||||||
strcasecmp(argv[2], "prev") == 0 ||
|
strcasecmp(argv[2], "prev") == 0 ||
|
||||||
strcasecmp(argv[2], "next_on_output") == 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) {
|
} else if (strcasecmp(argv[2], "back_and_forth") == 0) {
|
||||||
if (!(ws = workspace_by_name(argv[2]))) {
|
if (!(ws = workspace_by_name(argv[2]))) {
|
||||||
if (prev_workspace_name) {
|
if (prev_workspace_name) {
|
||||||
ws = workspace_create(NULL, prev_workspace_name);
|
ws_name = strdup(prev_workspace_name);
|
||||||
} else {
|
} else {
|
||||||
return cmd_results_new(CMD_FAILURE, "move",
|
return cmd_results_new(CMD_FAILURE, "move",
|
||||||
"No workspace was previously active.");
|
"No workspace was previously active.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char *ws_name = NULL;
|
|
||||||
if (strcasecmp(argv[2], "number") == 0) {
|
if (strcasecmp(argv[2], "number") == 0) {
|
||||||
// move "container to workspace number x"
|
// move "container to workspace number x"
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
|
@ -141,12 +141,26 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
||||||
ws = workspace_by_name(ws_name);
|
ws = workspace_by_name(ws_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!ws) {
|
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);
|
ws = workspace_create(NULL, ws_name);
|
||||||
}
|
}
|
||||||
free(ws_name);
|
free(ws_name);
|
||||||
}
|
|
||||||
destination = seat_get_focus_inactive(config->handler_context.seat, ws);
|
destination = seat_get_focus_inactive(config->handler_context.seat, ws);
|
||||||
} else if (strcasecmp(argv[1], "output") == 0) {
|
} else if (strcasecmp(argv[1], "output") == 0) {
|
||||||
struct sway_container *source = container_parent(current, C_OUTPUT);
|
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);
|
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
|
// move container, arrange windows and return focus
|
||||||
container_move_to(current, destination);
|
container_move_to(current, destination);
|
||||||
struct sway_container *focus =
|
struct sway_container *focus =
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.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;
|
struct sway_container *parent;
|
||||||
// Search for workspace<->output pair
|
// Search for workspace<->output pair
|
||||||
int e = config->workspace_outputs->length;
|
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,
|
struct sway_container *workspace_create(struct sway_container *output,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
if (output == NULL) {
|
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);
|
wlr_log(WLR_DEBUG, "Added workspace %s for output %s", name, output->name);
|
||||||
|
|
Loading…
Reference in a new issue