summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorMikael Magnusson <mikachu@gmail.com>2013-08-19 00:03:51 +0200
committerMikael Magnusson <mikachu@gmail.com>2013-08-19 21:35:44 +0200
commit780b2428a2463f164608c498f7d2e586016b8e11 (patch)
tree907040e1ca50ac6d07cef48748055941073c229e /openbox
parent2d5239b60a5caa20c6030fa996ea4711113dcea6 (diff)
Add ForEach action which is like If but runs on all clients
Also adds a Stop action that lets you stop running, in case you only want to run actions on the first match.
Diffstat (limited to 'openbox')
-rw-r--r--openbox/actions.c26
-rw-r--r--openbox/actions.h2
-rw-r--r--openbox/actions/if.c44
3 files changed, 66 insertions, 6 deletions
diff --git a/openbox/actions.c b/openbox/actions.c
index ac849a97..bf00c6c8 100644
--- a/openbox/actions.c
+++ b/openbox/actions.c
@@ -52,6 +52,7 @@ struct _ObActionsDefinition {
ObActionsRunFunc run;
ObActionsShutdownFunc shutdown;
gboolean modifies_focused_window;
+ gboolean can_stop;
};
struct _ObActionsAct {
@@ -111,6 +112,7 @@ ObActionsDefinition* do_register(const gchar *name,
def->run = run;
def->shutdown = NULL;
def->modifies_focused_window = TRUE;
+ def->can_stop = FALSE;
registered = g_slist_prepend(registered, def);
return def;
@@ -174,6 +176,22 @@ gboolean actions_set_modifies_focused_window(const gchar *name,
return FALSE;
}
+gboolean actions_set_can_stop(const gchar *name,
+ gboolean can_stop)
+{
+ GSList *it;
+ ObActionsDefinition *def;
+
+ for (it = registered; it; it = g_slist_next(it)) {
+ def = it->data;
+ if (!g_ascii_strcasecmp(name, def->name)) {
+ def->can_stop = can_stop;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void actions_definition_ref(ObActionsDefinition *def)
{
++def->ref;
@@ -356,16 +374,18 @@ void actions_run_acts(GSList *acts,
/* fire the action's run function with this data */
if (ok) {
if (!act->def->run(&data, act->options)) {
- if (actions_act_is_interactive(act))
+ if (actions_act_is_interactive(act)) {
actions_interactive_end_act();
+ }
if (client && client == focus_client &&
act->def->modifies_focused_window)
{
update_user_time = TRUE;
}
} else {
- /* make sure its interactive if it returned TRUE */
- g_assert(act->i_input);
+ /* make sure its interactive or allowed to stop
+ if it returned TRUE */
+ g_assert(act->i_input || act->def->can_stop);
/* no actions are run after the interactive one */
break;
diff --git a/openbox/actions.h b/openbox/actions.h
index f413ad82..f8e1ba83 100644
--- a/openbox/actions.h
+++ b/openbox/actions.h
@@ -84,6 +84,8 @@ gboolean actions_set_shutdown(const gchar *name,
ObActionsShutdownFunc shutdown);
gboolean actions_set_modifies_focused_window(const gchar *name,
gboolean modifies);
+gboolean actions_set_can_stop(const gchar *name,
+ gboolean modifies);
ObActionsAct* actions_parse(xmlNodePtr node);
ObActionsAct* actions_parse_string(const gchar *name);
diff --git a/openbox/actions/if.c b/openbox/actions/if.c
index 8a31c9a0..1802c6ac 100644
--- a/openbox/actions/if.c
+++ b/openbox/actions/if.c
@@ -64,15 +64,22 @@ typedef struct {
GArray* queries;
GSList *thenacts;
GSList *elseacts;
+ gboolean stop;
} Options;
static gpointer setup_func(xmlNodePtr node);
static void free_func(gpointer options);
-static gboolean run_func(ObActionsData *data, gpointer options);
+static gboolean run_func_if(ObActionsData *data, gpointer options);
+static gboolean run_func_stop(ObActionsData *data, gpointer options);
+static gboolean run_func_foreach(ObActionsData *data, gpointer options);
void action_if_startup(void)
{
- actions_register("If", setup_func, free_func, run_func);
+ actions_register("If", setup_func, free_func, run_func_if);
+ actions_register("Stop", NULL, NULL, run_func_stop);
+ actions_register("ForEach", setup_func, free_func, run_func_foreach);
+
+ actions_set_can_stop("Stop", TRUE);
}
static inline void set_bool(xmlNodePtr node,
@@ -228,7 +235,7 @@ static void free_func(gpointer options)
}
/* Always return FALSE because its not interactive */
-static gboolean run_func(ObActionsData *data, gpointer options)
+static gboolean run_func_if(ObActionsData *data, gpointer options)
{
Options *o = options;
ObClient *action_target = data->client;
@@ -351,3 +358,34 @@ static gboolean run_func(ObActionsData *data, gpointer options)
return FALSE;
}
+
+static gboolean run_func_foreach(ObActionsData *data, gpointer options)
+{
+ GList *it;
+ Options *o = options;
+
+ o->stop = FALSE;
+
+ for (it = client_list; it; it = g_list_next(it)) {
+ data->client = it->data;
+ run_func_if(data, options);
+ if (o->stop) {
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean run_func_stop(ObActionsData *data, gpointer options)
+{
+ Options *o = options;
+
+ /* This stops the loop above so we don't invoke actions on any more
+ clients */
+ o->stop = TRUE;
+
+ /* TRUE causes actions_run_acts to not run further actions on the current
+ client */
+ return TRUE;
+}