Merge pull request #2453 from ianyfan/commands

More commands
This commit is contained in:
Ryan Dwyer 2018-08-19 16:16:32 +10:00 committed by GitHub
commit 389d159c81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 121 additions and 57 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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 },

View file

@ -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,

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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);

5
sway/commands/nop.c Normal file
View file

@ -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);
}

View file

@ -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]);

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);

View file

@ -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',

View file

@ -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).

View file

@ -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);

View file

@ -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) {