]> Dogcows Code - chaz/openbox/blobdiff - openbox/actions.c
make the execute action not segfault when using a prompt (bug #4543)
[chaz/openbox] / openbox / actions.c
index 26def97809bd6153d49e2ee64173db07d9eca7ed..35d5cc25f095c23f2acd78806ee00d7d63a31544 100644 (file)
@@ -49,6 +49,7 @@ struct _ObActionsDefinition {
     } setup;
     ObActionsDataFreeFunc free;
     ObActionsRunFunc run;
+    ObActionsShutdownFunc shutdown;
 };
 
 struct _ObActionsAct {
@@ -79,7 +80,9 @@ void actions_shutdown(gboolean reconfig)
 
     /* free all the registered actions */
     while (registered) {
-        actions_definition_unref(registered->data);
+        ObActionsDefinition *d = registered->data;
+        if (d->shutdown) d->shutdown();
+        actions_definition_unref(d);
         registered = g_slist_delete_link(registered, registered);
     }
 }
@@ -135,6 +138,22 @@ gboolean actions_register(const gchar *name,
     return def != NULL;
 }
 
+gboolean actions_set_shutdown(const gchar *name,
+                              ObActionsShutdownFunc shutdown)
+{
+    GSList *it;
+    ObActionsDefinition *def;
+
+    for (it = registered; it; it = g_slist_next(it)) {
+        def = it->data;
+        if (!g_ascii_strcasecmp(name, def->name)) {
+            def->shutdown = shutdown;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
 static void actions_definition_ref(ObActionsDefinition *def)
 {
     ++def->ref;
@@ -186,14 +205,12 @@ ObActionsAct* actions_parse_string(const gchar *name)
 
     if ((act = actions_build_act_from_string(name))) {
         if (act->def->canbeinteractive) {
-            if (act->def->setup.i) {
+            if (act->def->setup.i)
                 act->options = act->def->setup.i(NULL,
                                                  &act->i_pre,
                                                  &act->i_input,
                                                  &act->i_cancel,
                                                  &act->i_post);
-                g_assert(!!act->i_input == !!act->i_cancel);
-            }
         }
         else {
             if (act->def->setup.n)
@@ -210,18 +227,16 @@ ObActionsAct* actions_parse(xmlNodePtr node)
     gchar *name;
     ObActionsAct *act = NULL;
 
-    if (obt_parse_attr_string(node, "name", &name)) {
+    if (obt_xml_attr_string(node, "name", &name)) {
         if ((act = actions_build_act_from_string(name))) {
             /* there is more stuff to parse here */
             if (act->def->canbeinteractive) {
-                if (act->def->setup.i) {
+                if (act->def->setup.i)
                     act->options = act->def->setup.i(node->children,
                                                      &act->i_pre,
                                                      &act->i_input,
                                                      &act->i_cancel,
                                                      &act->i_post);
-                    g_assert(!!act->i_input == !!act->i_cancel);
-                }
             }
             else {
                 if (act->def->setup.n)
@@ -236,7 +251,7 @@ ObActionsAct* actions_parse(xmlNodePtr node)
 
 gboolean actions_act_is_interactive(ObActionsAct *act)
 {
-    return act->i_cancel != NULL;
+    return act->i_input != NULL;
 }
 
 void actions_act_ref(ObActionsAct *act)
@@ -308,9 +323,12 @@ void actions_run_acts(GSList *acts,
                 if (interactive_act)
                     actions_interactive_cancel_act();
                 if (act->i_pre)
-                    act->i_pre(act->options);
-                ok = actions_interactive_begin_act(act, state);
+                    if (!act->i_pre(state, act->options))
+                        act->i_input = NULL; /* remove the interactivity */
             }
+            /* check again cuz it might have been cancelled */
+            if (actions_act_is_interactive(act))
+                ok = actions_interactive_begin_act(act, state);
         }
 
         /* fire the action's run function with this data */
@@ -320,7 +338,7 @@ void actions_run_acts(GSList *acts,
                     actions_interactive_end_act();
             } else {
                 /* make sure its interactive if it returned TRUE */
-                g_assert(act->i_cancel);
+                g_assert(act->i_input);
 
                 /* no actions are run after the interactive one */
                 break;
@@ -337,7 +355,8 @@ gboolean actions_interactive_act_running(void)
 void actions_interactive_cancel_act(void)
 {
     if (interactive_act) {
-        interactive_act->i_cancel(interactive_act->options);
+        if (interactive_act->i_cancel)
+            interactive_act->i_cancel(interactive_act->options);
         actions_interactive_end_act();
     }
 }
@@ -408,13 +427,19 @@ void actions_client_move(ObActionsData *data, gboolean start)
                are ignored during a grab, so don't force fake ones when they
                should be ignored
             */
-            if ((c = client_under_pointer()) && c != data->client &&
-                !grab_on_pointer())
-            {
-                ob_debug_type(OB_DEBUG_FOCUS,
-                              "Generating fake enter because we did a "
-                              "mouse-event action");
-                event_enter_client(c);
+            if (!grab_on_pointer()) {
+                if ((c = client_under_pointer()) && c != data->client) {
+                    ob_debug_type(OB_DEBUG_FOCUS,
+                                  "Generating fake enter because we did a "
+                                  "mouse-event action");
+                    event_enter_client(c);
+                }
+                else if (!c && c != data->client) {
+                    ob_debug_type(OB_DEBUG_FOCUS,
+                                  "Generating fake leave because we did a "
+                                  "mouse-event action");
+                    event_enter_client(data->client);
+                }
             }
         }
         else if (!data->button && !config_focus_under_mouse)
This page took 0.0285 seconds and 4 git commands to generate.