]> Dogcows Code - chaz/openbox/blobdiff - openbox/action.c
allow setting startupnotify per execute action, default to disabled. use like this...
[chaz/openbox] / openbox / action.c
index 24a0c6346396d39c45de365b372b106e008af1c6..5cd39f3d2b56a970326672b6173058fb2d385a3e 100644 (file)
@@ -33,6 +33,7 @@
 #include "dock.h"
 #include "config.h"
 #include "mainloop.h"
+#include "startupnotify.h"
 
 #include <glib.h>
 
@@ -928,6 +929,15 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                     act->data.execute.path = parse_expand_tilde(s);
                     g_free(s);
                 }
+                if ((n = parse_find_node("startupnotify", node->xmlChildrenNode))) {
+                    xmlNodePtr m;
+                    if ((m = parse_find_node("enabled", n->xmlChildrenNode)))
+                        act->data.execute.startupnotify = parse_bool(doc, m);
+                    if ((m = parse_find_node("name", n->xmlChildrenNode)))
+                        act->data.execute.name = parse_string(doc, m);
+                    if ((m = parse_find_node("icon", n->xmlChildrenNode)))
+                        act->data.execute.icon_name = parse_string(doc, m);
+                }
             } else if (act->func == action_showmenu) {
                 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
                     act->data.showmenu.name = parse_string(doc, n);
@@ -1005,7 +1015,7 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
-                     guint state, guint button, gint x, gint y,
+                     guint state, guint button, gint x, gint y, Time time,
                      gboolean cancel, gboolean done)
 {
     GSList *it;
@@ -1034,7 +1044,7 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
            it won't work right unless we XUngrabKeyboard first,
            even though we grabbed the key/button Asychronously.
            e.g. "gnome-panel-control --main-menu" */
-        XUngrabKeyboard(ob_display, event_lasttime);
+        XUngrabKeyboard(ob_display, event_curtime);
     }
 
     for (it = acts; it; it = g_slist_next(it)) {
@@ -1048,6 +1058,8 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
 
             a->data.any.button = button;
 
+            a->data.any.time = time;
+
             if (a->data.any.interactive) {
                 a->data.inter.cancel = cancel;
                 a->data.inter.final = done;
@@ -1068,7 +1080,7 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
     }
 }
 
-void action_run_string(const gchar *name, struct _ObClient *c)
+void action_run_string(const gchar *name, struct _ObClient *c, Time time)
 {
     ObAction *a;
     GSList *l;
@@ -1078,7 +1090,7 @@ void action_run_string(const gchar *name, struct _ObClient *c)
 
     l = g_slist_append(NULL, a);
 
-    action_run(l, c, 0);
+    action_run(l, c, 0, time);
 }
 
 void action_execute(union ActionData *data)
@@ -1092,10 +1104,30 @@ void action_execute(union ActionData *data)
                 g_warning("failed to execute '%s': %s",
                           cmd, e->message);
                 g_error_free(e);
+            } else if (data->execute.startupnotify) {
+                gchar **env, *program;
+                
+                program = g_path_get_basename(argv[0]);
+                env = sn_get_spawn_environment(program,
+                                               data->execute.name,
+                                               data->execute.icon_name,
+                                               data->execute.any.time);
+                if (!g_spawn_async(NULL, argv, env, G_SPAWN_SEARCH_PATH |
+                                   G_SPAWN_DO_NOT_REAP_CHILD,
+                                   NULL, NULL, NULL, &e)) {
+                    g_warning("failed to execute '%s': %s",
+                              cmd, e->message);
+                    g_error_free(e);
+                    sn_spawn_cancel();
+                }
+                g_strfreev(env);
+                g_free(program);
+                g_strfreev(argv);
             } else {
                 if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
                                    G_SPAWN_DO_NOT_REAP_CHILD,
-                                   NULL, NULL, NULL, &e)) {
+                                   NULL, NULL, NULL, &e))
+                {
                     g_warning("failed to execute '%s': %s",
                               cmd, e->message);
                     g_error_free(e);
@@ -1111,16 +1143,31 @@ void action_execute(union ActionData *data)
 
 void action_activate(union ActionData *data)
 {
-    client_activate(data->activate.any.c, data->activate.here);
+    /* similar to the openbox dock for dockapps, don't let user actions give
+       focus to 3rd-party docks (panels) either (unless they ask for it
+       themselves). */
+    if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
+        /* if using focus_delay, stop the timer now so that focus doesn't go
+           moving on us */
+        event_halt_focus_delay();
+
+        client_activate(data->activate.any.c, data->activate.here, TRUE,
+                        data->activate.any.time);
+    }
 }
 
 void action_focus(union ActionData *data)
 {
-    /* if using focus_delay, stop the timer now so that focus doesn't go moving
-       on us */
-    event_halt_focus_delay();
+    /* similar to the openbox dock for dockapps, don't let user actions give
+       focus to 3rd-party docks (panels) either (unless they ask for it
+       themselves). */
+    if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
+        /* if using focus_delay, stop the timer now so that focus doesn't go
+           moving on us */
+        event_halt_focus_delay();
 
-    client_focus(data->client.any.c);
+        client_focus(data->client.any.c);
+    }
 }
 
 void action_unfocus (union ActionData *data)
@@ -1580,7 +1627,8 @@ void action_cycle_windows(union ActionData *data)
 
     focus_cycle(data->cycle.forward, data->cycle.linear, data->any.interactive,
                 data->cycle.dialog,
-                data->cycle.inter.final, data->cycle.inter.cancel);
+                data->cycle.inter.final, data->cycle.inter.cancel,
+                data->cycle.inter.any.time);
 }
 
 void action_directional_focus(union ActionData *data)
@@ -1593,7 +1641,8 @@ void action_directional_focus(union ActionData *data)
                             data->any.interactive,
                             data->interdiraction.dialog,
                             data->interdiraction.inter.final,
-                            data->interdiraction.inter.cancel);
+                            data->interdiraction.inter.cancel,
+                            data->interdiraction.inter.any.time);
 }
 
 void action_movetoedge(union ActionData *data)
@@ -1606,19 +1655,23 @@ void action_movetoedge(union ActionData *data)
     
     switch(data->diraction.direction) {
     case OB_DIRECTION_NORTH:
-        y = client_directional_edge_search(c, OB_DIRECTION_NORTH, data->diraction.hang)
+        y = client_directional_edge_search(c, OB_DIRECTION_NORTH,
+                                           data->diraction.hang)
             - (data->diraction.hang ? c->frame->area.height : 0);
         break;
     case OB_DIRECTION_WEST:
-        x = client_directional_edge_search(c, OB_DIRECTION_WEST, data->diraction.hang)
+        x = client_directional_edge_search(c, OB_DIRECTION_WEST,
+                                           data->diraction.hang)
             - (data->diraction.hang ? c->frame->area.width : 0);
         break;
     case OB_DIRECTION_SOUTH:
-        y = client_directional_edge_search(c, OB_DIRECTION_SOUTH, data->diraction.hang)
+        y = client_directional_edge_search(c, OB_DIRECTION_SOUTH,
+                                           data->diraction.hang)
             - (data->diraction.hang ? 0 : c->frame->area.height);
         break;
     case OB_DIRECTION_EAST:
-        x = client_directional_edge_search(c, OB_DIRECTION_EAST, data->diraction.hang)
+        x = client_directional_edge_search(c, OB_DIRECTION_EAST,
+                                           data->diraction.hang)
             - (data->diraction.hang ? 0 : c->frame->area.width);
         break;
     default:
This page took 0.024733 seconds and 4 git commands to generate.