Add ForEach action which is like If but runs on all clients
authorMikael Magnusson <mikachu@gmail.com>
Fri, 21 May 2010 12:11:57 +0000 (14:11 +0200)
committerMikael Magnusson <mikachu@gmail.com>
Sun, 19 Sep 2010 15:53:23 +0000 (17:53 +0200)
openbox/actions.c
openbox/actions/if.c

index 125084e8c5ee7c9e776ba60f0a9d40301b5556b7..419f283153b4ff79d3ed220319d96a5f87457fd4 100644 (file)
@@ -36,6 +36,7 @@ static ObActionsAct* actions_build_act_from_string(const gchar *name);
 
 static ObActionsAct *interactive_act = NULL;
 static guint         interactive_initial_state = 0;
+static gboolean      stop_running = FALSE;
 
 struct _ObActionsDefinition {
     guint ref;
@@ -290,6 +291,11 @@ static void actions_setup_data(ObActionsData *data,
     data->client = client;
 }
 
+void actions_stop_running()
+{
+    stop_running = TRUE;
+}
+
 void actions_run_acts(GSList *acts,
                       ObUserAction uact,
                       guint state,
@@ -301,6 +307,8 @@ void actions_run_acts(GSList *acts,
 {
     GSList *it;
 
+    stop_running = FALSE;
+
     /* Don't allow saving the initial state when running things from the
        menu */
     if (uact == OB_USER_ACTION_MENU_SELECTION)
@@ -337,6 +345,10 @@ void actions_run_acts(GSList *acts,
             if (!act->def->run(&data, act->options)) {
                 if (actions_act_is_interactive(act))
                     actions_interactive_end_act();
+                else if (stop_running) {
+                    stop_running = FALSE;
+                    break;
+                }
             } else {
                 /* make sure its interactive if it returned TRUE */
                 g_assert(act->i_input);
index 28010d388b43b0479417bdb1c2d188528a03de29..f7eeb4fe66ccf18a406861541401bb65f947b5ce 100644 (file)
@@ -35,11 +35,21 @@ typedef struct {
 
 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_continue(ObActionsData *data, gpointer options);
+static gboolean run_func_stop(ObActionsData *data, gpointer options);
+static gboolean run_func_foreach(ObActionsData *data, gpointer options);
+static gboolean run_func_group(ObActionsData *data, gpointer options);
+
+static gboolean foreach_stop;
 
 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("Continue", NULL, NULL, run_func_continue);
+    actions_register("ForEach", setup_func, free_func, run_func_foreach);
+    //actions_register("GroupMembers", setup_func, free_func, run_func_group);
 }
 
 static gpointer setup_func(xmlNodePtr node)
@@ -163,7 +173,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;
     GSList *acts;
@@ -208,3 +218,51 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 
     return FALSE;
 }
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func_foreach(ObActionsData *data, gpointer options)
+{
+    GList *it;
+
+    foreach_stop = FALSE;
+
+    for (it = client_list; it; it = g_list_next(it)) {
+        data->client = it->data;
+        run_func_if(data, options);
+        if (foreach_stop) {
+            foreach_stop = FALSE;
+            break;
+        }
+    }
+
+    return FALSE;
+}
+
+static gboolean run_func_continue(ObActionsData *data, gpointer options)
+{
+    actions_stop_running();
+}
+
+static gboolean run_func_stop(ObActionsData *data, gpointer options)
+{
+    actions_stop_running();
+    foreach_stop = TRUE;
+}
+/*
+static gboolean run_func_group(ObActionsData *data, gpointer acts)
+{
+    GSList *it, *a = acts;
+    ObClient *c = data->client;
+
+    if (a && c)
+        for (it = c->group->members; it; it = g_slist_next(it)) {
+            ObClient *member = it->data;
+            if (actions_run_acts(a, data->uact, data->state,
+                                 data->x, data->y, data->button,
+                                 data->context, member))
+                return TRUE;
+        }
+
+    return FALSE;
+}
+*/