Merge pull request #2453 from ianyfan/commands

More commands
master
Ryan Dwyer 6 years ago committed by GitHub
commit 389d159c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -136,6 +136,7 @@ sway_cmd cmd_mark;
sway_cmd cmd_mode; sway_cmd cmd_mode;
sway_cmd cmd_mouse_warping; sway_cmd cmd_mouse_warping;
sway_cmd cmd_move; sway_cmd cmd_move;
sway_cmd cmd_nop;
sway_cmd cmd_opacity; sway_cmd cmd_opacity;
sway_cmd cmd_new_float; sway_cmd cmd_new_float;
sway_cmd cmd_new_window; sway_cmd cmd_new_window;

@ -7,10 +7,11 @@
#include "tree/view.h" #include "tree/view.h"
enum criteria_type { enum criteria_type {
CT_COMMAND = 1 << 0, CT_COMMAND = 1 << 0,
CT_ASSIGN_OUTPUT = 1 << 1, CT_ASSIGN_OUTPUT = 1 << 1,
CT_ASSIGN_WORKSPACE = 1 << 2, CT_ASSIGN_WORKSPACE = 1 << 2,
CT_NO_FOCUS = 1 << 3, CT_ASSIGN_WORKSPACE_NUMBER = 1 << 3,
CT_NO_FOCUS = 1 << 4,
}; };
struct criteria { struct criteria {

@ -146,6 +146,7 @@ static struct cmd_handler command_handlers[] = {
{ "layout", cmd_layout }, { "layout", cmd_layout },
{ "mark", cmd_mark }, { "mark", cmd_mark },
{ "move", cmd_move }, { "move", cmd_move },
{ "nop", cmd_nop },
{ "opacity", cmd_opacity }, { "opacity", cmd_opacity },
{ "reload", cmd_reload }, { "reload", cmd_reload },
{ "rename", cmd_rename }, { "rename", cmd_rename },

@ -22,27 +22,38 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
return error; return error;
} }
++argv; --argc; ++argv;
int target_len = argc - 1;
if (strncmp(*argv, "", strlen("")) == 0) { if (strncmp(*argv, "", strlen("")) == 0) {
if (argc < 3) { if (argc < 2) {
free(criteria); free(criteria);
return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
} }
--argc;
++argv; ++argv;
--target_len;
} }
if (strcmp(*argv, "output") == 0) { if (strcmp(*argv, "output") == 0) {
criteria->type = CT_ASSIGN_OUTPUT; criteria->type = CT_ASSIGN_OUTPUT;
++argv; --argc; ++argv;
--target_len;
} else { } else {
criteria->type = CT_ASSIGN_WORKSPACE; if (strcmp(*argv, "workspace") == 0) {
--argc; ++argv;
}
if (strcmp(*argv, "number") == 0) {
--argc; ++argv;
if (argv[0][0] < '0' || argv[0][0] > '9') {
free(criteria);
return cmd_results_new(CMD_INVALID, "assign",
"Invalid workspace number '%s'", argv[0]);
}
criteria->type = CT_ASSIGN_WORKSPACE_NUMBER;
} else {
criteria->type = CT_ASSIGN_WORKSPACE;
}
} }
criteria->target = join_args(argv, target_len); criteria->target = join_args(argv, argc);
list_add(config->criteria, criteria); list_add(config->criteria, criteria);
wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw, wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,

@ -26,7 +26,16 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
return error; return error;
} }
tmp = join_args(argv + 1, argc - 1); --argc; ++argv;
}
if (argv[0][0] == '\'' || argv[0][0] == '"') {
if (argc > 0) {
return cmd_results_new(CMD_INVALID, "exec_always",
"command cannot be partially quoted");
}
tmp = strdup(argv[0]);
strip_quotes(tmp);
} else { } else {
tmp = join_args(argv, argc); tmp = join_args(argv, argc);
} }

@ -52,6 +52,10 @@ static struct cmd_results *focus_mode(struct sway_container *con,
} }
if (new_focus) { if (new_focus) {
seat_set_focus(seat, new_focus); seat_set_focus(seat, new_focus);
} else {
return cmd_results_new(CMD_FAILURE, "focus",
"Failed to find a %s container in workspace",
floating ? "floating" : "tiling");
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 500
#include <ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
@ -22,7 +23,7 @@
static const char *expected_syntax = static const char *expected_syntax =
"Expected 'move <left|right|up|down> <[px] px>' or " "Expected 'move <left|right|up|down> <[px] px>' or "
"'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or " "'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or "
"'move [--no-auto-back-and-forth] <container|window|workspace> [to] output <name|direction>' or " "'move <container|window|workspace> [to] output <name|direction>' or "
"'move <container|window> [to] mark <mark>'"; "'move <container|window> [to] mark <mark>'";
static struct sway_container *output_in_direction(const char *direction, static struct sway_container *output_in_direction(const char *direction,
@ -124,7 +125,11 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
return cmd_results_new(CMD_INVALID, "move", return cmd_results_new(CMD_INVALID, "move",
expected_syntax); expected_syntax);
} }
ws_name = strdup(argv[3]); if (!isdigit(argv[3][0])) {
return cmd_results_new(CMD_INVALID, "move",
"Invalid workspace number '%s'", argv[3]);
}
ws_name = join_args(argv + 3, argc - 3);
ws = workspace_by_number(ws_name); ws = workspace_by_number(ws_name);
} else { } else {
ws_name = join_args(argv + 2, argc - 2); ws_name = join_args(argv + 2, argc - 2);

@ -0,0 +1,5 @@
#include "sway/commands.h"
struct cmd_results *cmd_nop(int argc, char **argv) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}

@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 500
#include <ctype.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include "log.h" #include "log.h"
@ -34,6 +35,10 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
} }
} else if (strcasecmp(argv[1], "number") == 0) { } else if (strcasecmp(argv[1], "number") == 0) {
// 'rename workspace number x to new_name' // 'rename workspace number x to new_name'
if (!isdigit(argv[2][0])) {
return cmd_results_new(CMD_INVALID, "rename",
"Invalid workspace number '%s'", argv[2]);
}
workspace = workspace_by_number(argv[2]); workspace = workspace_by_number(argv[2]);
while (argn < argc && strcasecmp(argv[argn], "to") != 0) { while (argn < argc && strcasecmp(argv[argn], "to") != 0) {
++argn; ++argn;
@ -67,7 +72,8 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
strcasecmp(new_name, "next_on_output") == 0 || strcasecmp(new_name, "next_on_output") == 0 ||
strcasecmp(new_name, "prev_on_output") == 0 || strcasecmp(new_name, "prev_on_output") == 0 ||
strcasecmp(new_name, "back_and_forth") == 0 || strcasecmp(new_name, "back_and_forth") == 0 ||
strcasecmp(new_name, "current") == 0) { strcasecmp(new_name, "current") == 0 ||
strcasecmp(new_name, "number") == 0) {
free(new_name); free(new_name);
return cmd_results_new(CMD_INVALID, "rename", return cmd_results_new(CMD_INVALID, "rename",
"Cannot use special workspace name '%s'", argv[argn]); "Cannot use special workspace name '%s'", argv[argn]);

@ -25,23 +25,13 @@ void free_sway_variable(struct sway_variable *var) {
} }
struct cmd_results *cmd_set(int argc, char **argv) { struct cmd_results *cmd_set(int argc, char **argv) {
char *tmp;
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "set", EXPECTED_AT_LEAST, 2))) { if ((error = checkarg(argc, "set", EXPECTED_AT_LEAST, 2))) {
return error; return error;
} }
if (argv[0][0] != '$') { if (argv[0][0] != '$') {
wlr_log(WLR_INFO, "Warning: variable '%s' doesn't start with $", argv[0]); return cmd_results_new(CMD_INVALID, "set", "variable '%s' must start with $", argv[0]);
size_t size = snprintf(NULL, 0, "$%s", argv[0]);
tmp = malloc(size + 1);
if (!tmp) {
return cmd_results_new(CMD_FAILURE, "set", "Not possible to create variable $'%s'", argv[0]);
}
snprintf(tmp, size+1, "$%s", argv[0]);
argv[0] = tmp;
} }
struct sway_variable *var = NULL; struct sway_variable *var = NULL;

@ -36,5 +36,21 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
container->is_sticky = wants_sticky; container->is_sticky = wants_sticky;
if (wants_sticky) {
// move container to focused workspace
struct sway_container *output = container_parent(container, C_OUTPUT);
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus_inactive(seat, output);
struct sway_container *focused_workspace = container_parent(focus, C_WORKSPACE);
struct sway_container *current_workspace = container_parent(container, C_WORKSPACE);
if (current_workspace != focused_workspace) {
container_move_to(container, focused_workspace);
arrange_windows(focused_workspace);
if (!container_reap_empty(current_workspace)) {
arrange_windows(current_workspace);
}
}
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 500
#include <ctype.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include "sway/commands.h" #include "sway/commands.h"
@ -60,9 +61,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
struct sway_container *ws = NULL; struct sway_container *ws = NULL;
if (strcasecmp(argv[0], "number") == 0) { if (strcasecmp(argv[0], "number") == 0) {
if (argc < 2) { if (argc < 2) {
cmd_results_new(CMD_INVALID, "workspace", return cmd_results_new(CMD_INVALID, "workspace",
"Expected workspace number"); "Expected workspace number");
} }
if (!isdigit(argv[1][0])) {
return cmd_results_new(CMD_INVALID, "workspace",
"Invalid workspace number '%s'", argv[1]);
}
if (!(ws = workspace_by_number(argv[1]))) { if (!(ws = workspace_by_number(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(NULL, name);

@ -64,6 +64,7 @@ sway_sources = files(
'commands/mouse_warping.c', 'commands/mouse_warping.c',
'commands/move.c', 'commands/move.c',
'commands/no_focus.c', 'commands/no_focus.c',
'commands/nop.c',
'commands/output.c', 'commands/output.c',
'commands/reload.c', 'commands/reload.c',
'commands/rename.c', 'commands/rename.c',

@ -51,7 +51,7 @@ The following commands may only be used in the configuration file.
*wordexp*(3) for details). The same include file can only be included once; *wordexp*(3) for details). The same include file can only be included once;
subsequent attempts will be ignored. subsequent attempts will be ignored.
*set* <name> <value> *set* $<name> <value>
Sets variable $_name_ to _value_. You can use the new variable in the Sets variable $_name_ to _value_. You can use the new variable in the
arguments of future commands. arguments of future commands.
@ -132,7 +132,7 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
If unspecified, the default is 10 pixels. Pixels are ignored when moving If unspecified, the default is 10 pixels. Pixels are ignored when moving
tiled containers. tiled containers.
*move* [absolute] position <pos_x> [px] <pos_y> [px] *move* [absolute] position <pos\_x> [px] <pos\_y> [px]
Moves the focused container to the specified position. Moves the focused container to the specified position.
*move* [absolute] position center|mouse *move* [absolute] position center|mouse
@ -154,7 +154,7 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
Moves the focused container to the previous or next workspace on this Moves the focused container to the previous or next workspace on this
output, wrapping around if already at the first or last workspace. output, wrapping around if already at the first or last workspace.
*move* container|window [to] workspace back_and_forth *move* container|window [to] workspace back\_and\_forth
Moves the focused container to previously focused workspace. Moves the focused container to previously focused workspace.
*move* container|window|workspace [to] output <name> *move* container|window|workspace [to] output <name>
@ -167,6 +167,10 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
*move* [to] scratchpad *move* [to] scratchpad
Moves the focused window to the scratchpad. Moves the focused window to the scratchpad.
*nop* <comment>
A no operation command that can be used to override default behaviour. The
optional comment argument is ignored, but logged for debugging purposes.
*reload* *reload*
Reloads the sway config file and applies any changes. Reloads the sway config file and applies any changes.
@ -215,13 +219,20 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
The following commands may be used either in the configuration file or at The following commands may be used either in the configuration file or at
runtime. runtime.
*assign* <criteria> [→] <workspace> *assign* <criteria> [→] [workspace] [number] <workspace>
Assigns views matching _criteria_ (see *CRITERIA* for details) to Assigns views matching _criteria_ (see *CRITERIA* for details) to
_workspace_. The → (U+2192) is optional and cosmetic. This command is _workspace_. The → (U+2192) is optional and cosmetic. This command is
equivalent to: equivalent to:
for\_window <criteria> move container to workspace <workspace> for\_window <criteria> move container to workspace <workspace>
*assign* <criteria> [→] output left|right|up|down|<name>
Assigns views matching _criteria_ (see *CRITERIA* for details) to the
specified output. The → (U+2192) is optional and cosmetic. This command is
equivalent to:
for\_window <criteria> move container to output <output>
*bindsym* [--release|--locked] <key combo> <command> *bindsym* [--release|--locked] <key combo> <command>
Binds _key combo_ to execute the sway command _command_ when pressed. You Binds _key combo_ to execute the sway command _command_ when pressed. You
may use XKB key names here (*xev*(1) is a good tool for discovering these). may use XKB key names here (*xev*(1) is a good tool for discovering these).

@ -450,12 +450,22 @@ static struct sway_container *select_workspace(struct sway_view *view) {
// 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,
CT_ASSIGN_WORKSPACE | CT_ASSIGN_OUTPUT); CT_ASSIGN_WORKSPACE | CT_ASSIGN_WORKSPACE_NUMBER | CT_ASSIGN_OUTPUT);
struct sway_container *ws = NULL; struct sway_container *ws = NULL;
for (int i = 0; i < criterias->length; ++i) { for (int i = 0; i < criterias->length; ++i) {
struct criteria *criteria = criterias->items[i]; struct criteria *criteria = criterias->items[i];
if (criteria->type == CT_ASSIGN_WORKSPACE) { if (criteria->type == CT_ASSIGN_OUTPUT) {
ws = workspace_by_name(criteria->target); struct sway_container *output = output_by_name(criteria->target);
if (output) {
ws = seat_get_active_child(seat, output);
break;
}
} else {
// CT_ASSIGN_WORKSPACE(_NUMBER)
ws = criteria->type == CT_ASSIGN_WORKSPACE_NUMBER ?
workspace_by_number(criteria->target) :
workspace_by_name(criteria->target);
if (!ws) { if (!ws) {
if (strcasecmp(criteria->target, "back_and_forth") == 0) { if (strcasecmp(criteria->target, "back_and_forth") == 0) {
if (prev_workspace_name) { if (prev_workspace_name) {
@ -466,13 +476,6 @@ static struct sway_container *select_workspace(struct sway_view *view) {
} }
} }
break; break;
} else {
// CT_ASSIGN_OUTPUT
struct sway_container *output = output_by_name(criteria->target);
if (output) {
ws = seat_get_active_child(seat, output);
break;
}
} }
} }
list_free(criterias); list_free(criterias);

@ -82,11 +82,6 @@ struct sway_container *workspace_create(struct sway_container *output,
} }
char *prev_workspace_name = NULL; char *prev_workspace_name = NULL;
struct workspace_by_number_data {
int len;
const char *cset;
const char *name;
};
void next_name_map(struct sway_container *ws, void *data) { void next_name_map(struct sway_container *ws, void *data) {
int *count = data; int *count = data;
@ -154,7 +149,7 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
wlr_log(WLR_DEBUG, "Isolated name from workspace number: '%s'", _target); wlr_log(WLR_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 (workspace_by_number(_target)) { if (isdigit(_target[0]) && workspace_by_number(_target)) {
free(_target); free(_target);
free(dup); free(dup);
return; return;
@ -233,18 +228,18 @@ static bool _workspace_by_number(struct sway_container *view, void *data) {
if (view->type != C_WORKSPACE) { if (view->type != C_WORKSPACE) {
return false; return false;
} }
struct workspace_by_number_data *wbnd = data; char *name = data;
int a = strspn(view->name, wbnd->cset); char *view_name = view->name;
return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; while (isdigit(*name)) {
if (*name++ != *view_name++) {
return false;
}
}
return !isdigit(*view_name);
} }
struct sway_container *workspace_by_number(const char* name) { struct sway_container *workspace_by_number(const char* name) {
struct workspace_by_number_data wbnd = {0, "1234567890", name}; return root_find_workspace(_workspace_by_number, (void *) name);
wbnd.len = strspn(name, wbnd.cset);
if (wbnd.len <= 0) {
return NULL;
}
return root_find_workspace(_workspace_by_number, (void *) &wbnd);
} }
static bool _workspace_by_name(struct sway_container *view, void *data) { static bool _workspace_by_name(struct sway_container *view, void *data) {

Loading…
Cancel
Save