all repos — openbox @ 44fd94ff51239e99a604ccafec039c5453467508

openbox fork - make it a bit more like ryudo

only allow running lists of actions at a time, policy is to always allow multiple action bindings, so this enforces it, and at the same time, UngrabKeyboard() before firing actions if there are no interactive ones. This is needed for some execute's, namely gnome-panel-control --main-menu.
Dana Jansens danakj@orodu.net
commit

44fd94ff51239e99a604ccafec039c5453467508

parent

19e48200739dc95f9b0079a25849e7e06c99302c

2 files changed, 44 insertions(+), 19 deletions(-)

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

@@ -28,11 +28,12 @@ #include "action.h"

#include "openbox.h" #include "grab.h" #include "keyboard.h" +#include "event.h" #include <glib.h> typedef struct ActionString { - char *name; + const gchar *name; void (*func)(union ActionData *); void (*setup)(ObAction **, ObUserAction uact); } ActionString;

@@ -784,27 +785,51 @@ }

return act; } -void action_run_full(ObAction *a, struct _ObClient *c, +void action_run_list(GSList *acts, struct _ObClient *c, guint state, guint button, gint x, gint y, gboolean cancel, gboolean done) { + GSList *it; + ObAction *a; + gboolean inter = FALSE; + if (x < 0 && y < 0) screen_pointer_pos(&x, &y); - a->data.any.c = c; - a->data.any.x = x; - a->data.any.y = y; - - a->data.any.button = button; + for (it = acts; it; it = g_slist_next(it)) { + a = it->data; + if (a->data.any.interactive) { + inter = TRUE; + break; + } + } - if (a->data.any.interactive) { - a->data.inter.cancel = cancel; - a->data.inter.final = done; - if (!(cancel || done)) - keyboard_interactive_grab(state, c, a); + if (!inter) { + /* sometimes when we execute another app as an action, + 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); } - a->func(&a->data); + for (it = acts; it; it = g_slist_next(it)) { + a = it->data; + + a->data.any.c = c; + a->data.any.x = x; + a->data.any.y = y; + + a->data.any.button = button; + + if (a->data.any.interactive) { + a->data.inter.cancel = cancel; + a->data.inter.final = done; + if (!(cancel || done)) + keyboard_interactive_grab(state, c, a); + } + + a->func(&a->data); + } } void action_execute(union ActionData *data)
M openbox/action.hopenbox/action.h

@@ -169,7 +169,7 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,

ObUserAction uact); void action_free(ObAction *a); -/*! Executes an action. +/*! Executes a list of actions. @param c The client associated with the action. Can be NULL. @param state The keyboard modifiers state at the time the user action occured @param button The mouse button used to execute the action.

@@ -180,21 +180,21 @@ affects interactive actions, but should generally always be FALSE.

@param done If the action is completing an interactive action. This only affects interactive actions, but should generally always be FALSE. */ -void action_run_full(ObAction *a, struct _ObClient *c, +void action_run_list(GSList *acts, struct _ObClient *c, guint state, guint button, gint x, gint y, gboolean cancel, gboolean done); #define action_run_mouse(a, c, s, b, x, y) \ - action_run_full(a, c, s, b, x, y, FALSE, FALSE) + action_run_list(a, c, s, b, x, y, FALSE, FALSE) #define action_run_interactive(a, c, s, n, d) \ - action_run_full(a, c, s, 0, -1, -1, n, d) + action_run_list(a, c, s, 0, -1, -1, n, d) #define action_run_key(a, c, s, x, y) \ - action_run_full(a, c, s, 0, x, y, FALSE,FALSE) + action_run_list(a, c, s, 0, x, y, FALSE,FALSE) #define action_run(a, c, s) \ - action_run_full(a, c, s, 0, -1, -1, FALSE,FALSE) + action_run_list(a, c, s, 0, -1, -1, FALSE,FALSE) /* Execute */ void action_execute(union ActionData *data);