all repos — openbox @ 780b2428a2463f164608c498f7d2e586016b8e11

openbox fork - make it a bit more like ryudo

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.
Mikael Magnusson mikachu@gmail.com
commit

780b2428a2463f164608c498f7d2e586016b8e11

parent

2d5239b60a5caa20c6030fa996ea4711113dcea6

3 files changed, 66 insertions(+), 6 deletions(-)

jump to
M openbox/actions.copenbox/actions.c

@@ -52,6 +52,7 @@ ObActionsDataFreeFunc free;

ObActionsRunFunc run; ObActionsShutdownFunc shutdown; gboolean modifies_focused_window; + gboolean can_stop; }; struct _ObActionsAct {

@@ -111,6 +112,7 @@ def->free = free;

def->run = run; def->shutdown = NULL; def->modifies_focused_window = TRUE; + def->can_stop = FALSE; registered = g_slist_prepend(registered, def); return def;

@@ -168,6 +170,22 @@ for (it = registered; it; it = g_slist_next(it)) {

def = it->data; if (!g_ascii_strcasecmp(name, def->name)) { def->modifies_focused_window = modifies; + return TRUE; + } + } + 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; } }

@@ -356,16 +374,18 @@

/* 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;
M openbox/actions.hopenbox/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);
M openbox/actions/if.copenbox/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 @@ g_slice_free(Options, o);

} /* 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 @@ data->context, action_target);

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; +}