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.
This commit is contained in:
parent
2d5239b60a
commit
780b2428a2
3 changed files with 66 additions and 6 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue