diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd
index b5e7d2bc..164f1540 100644
--- a/docs/labwc-actions.5.scd
+++ b/docs/labwc-actions.5.scd
@@ -86,13 +86,19 @@ Actions are used in menus and keyboard/mouse bindings.
any windows, the cursor is centered on the given output.
**
- Switch to workspace. Supported values are "last", "left", "right" or the
- full name of a workspace or its index (starting at 1) as configured in
- rc.xml.
+ Switch to workspace.
-**
+ *to* The workspace to switch to. Supported values are "last", "left",
+ "right" or the full name of a workspace or its index (starting at 1)
+ as configured in rc.xml.
+
+**
Send active window to workspace.
- Supported values are the same as for GoToDesktop.
+
+ *to* The workspace to send the window to. Supported values are the same
+ as for GoToDesktop.
+
+ *follow* [yes|no] Also switch to the specified workspace. Default yes.
**
If used as the only action for a binding: clear an earlier defined binding.
diff --git a/docs/menu.xml b/docs/menu.xml
index 87f4ed82..01b96037 100644
--- a/docs/menu.xml
+++ b/docs/menu.xml
@@ -25,11 +25,9 @@
-
diff --git a/include/action.h b/include/action.h
index 96697597..c26f15a8 100644
--- a/include/action.h
+++ b/include/action.h
@@ -19,7 +19,10 @@ struct action {
};
struct action *action_create(const char *action_name);
+
void action_arg_add_str(struct action *action, char *key, const char *value);
+void action_arg_add_bool(struct action *action, char *key, bool value);
+
void action_arg_from_xml_node(struct action *action, char *nodename, char *content);
bool actions_contain_toggle_keybinds(struct wl_list *action_list);
diff --git a/src/action.c b/src/action.c
index bea2d896..c8b92b6a 100644
--- a/src/action.c
+++ b/src/action.c
@@ -7,6 +7,7 @@
#include
#include
#include "action.h"
+#include "common/get-bool.h"
#include "common/list.h"
#include "common/mem.h"
#include "common/spawn.h"
@@ -20,6 +21,7 @@
enum action_arg_type {
LAB_ACTION_ARG_STR = 0,
+ LAB_ACTION_ARG_BOOL,
};
struct action_arg {
@@ -34,6 +36,11 @@ struct action_arg_str {
char *value;
};
+struct action_arg_bool {
+ struct action_arg base;
+ bool value;
+};
+
enum action_type {
ACTION_TYPE_INVALID = 0,
ACTION_TYPE_NONE,
@@ -117,7 +124,10 @@ action_arg_from_xml_node(struct action *action, char *nodename, char *content)
action_arg_add_str(action, NULL, content);
} else if (!strcmp(nodename, "to.action")) {
/* GoToDesktop, SendToDesktop */
- action_arg_add_str(action, NULL, content);
+ action_arg_add_str(action, "to", content);
+ } else if (!strcmp(nodename, "follow.action")) {
+ /* SendToDesktop */
+ action_arg_add_bool(action, "follow", get_bool(content));
} else if (!strcmp(nodename, "region.action")) {
/* SnapToRegion */
action_arg_add_str(action, NULL, content);
@@ -134,6 +144,13 @@ action_str_from_arg(struct action_arg *arg)
return ((struct action_arg_str *)arg)->value;
}
+static bool
+action_bool_from_arg(struct action_arg *arg)
+{
+ assert(arg->type == LAB_ACTION_ARG_BOOL);
+ return ((struct action_arg_bool *)arg)->value;
+}
+
static struct action_arg *
action_get_first_arg(struct action *action)
{
@@ -442,16 +459,25 @@ actions_run(struct view *activator, struct server *server,
}
break;
case ACTION_TYPE_SEND_TO_DESKTOP:
- if (!arg) {
- wlr_log(WLR_ERROR, "Missing argument for SendToDesktop");
- break;
- }
if (view) {
+ struct action_arg *arg;
+ char *target_name = NULL;
struct workspace *target;
- char *target_name = action_str_from_arg(arg);
+ bool follow = true;
+
+ wl_list_for_each(arg, &action->args, link) {
+ if (!strcmp("to", arg->key)) {
+ target_name = action_str_from_arg(arg);
+ } else if (!strcmp("follow", arg->key)) {
+ follow = action_bool_from_arg(arg);
+ }
+ }
target = workspaces_find(view->workspace, target_name);
if (target) {
view_move_to_workspace(view, target);
+ if (follow) {
+ workspaces_switch_to(target);
+ }
}
}
break;
@@ -517,3 +543,15 @@ action_arg_add_str(struct action *action, char *key, const char *value)
arg->value = xstrdup(value);
wl_list_append(&action->args, &arg->base.link);
}
+
+void
+action_arg_add_bool(struct action *action, char *key, bool value)
+{
+ struct action_arg_bool *arg = znew(*arg);
+ arg->base.type = LAB_ACTION_ARG_BOOL;
+ if (key) {
+ arg->base.key = xstrdup(key);
+ }
+ arg->value = value;
+ wl_list_append(&action->args, &arg->base.link);
+}
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index d0321d3d..78515e69 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -120,6 +120,11 @@ fill_keybind(char *nodename, char *content)
wlr_log(WLR_ERROR, "expect element first. "
"nodename: '%s' content: '%s'", nodename, content);
} else {
+ /*
+ * Here we deal with action sub-elements such as ,