X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Faction.c;h=20bf686f2e69701f31580d9c0a350d2c2ee4fe18;hb=4ff717355a98d96d3ad1c93a28f2bf435b9b60ba;hp=8e7b56a341dffe0c14a3636893396d6385201149;hpb=18c0714c518b6893835cded4967a5edcb47940f9;p=chaz%2Fopenbox diff --git a/openbox/action.c b/openbox/action.c index 8e7b56a3..20bf686f 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -42,14 +42,27 @@ inline void client_action_start(union ActionData *data) { if (config_focus_follow) if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button) - grab_pointer(TRUE, FALSE, OB_CURSOR_NONE); + grab_pointer(FALSE, FALSE, OB_CURSOR_NONE); } inline void client_action_end(union ActionData *data) { if (config_focus_follow) - if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button) - grab_pointer(FALSE, FALSE, OB_CURSOR_NONE); + if (data->any.context != OB_FRAME_CONTEXT_CLIENT) { + if (!data->any.button) { + ungrab_pointer(); + } else { + ObClient *c; + + /* usually this is sorta redundant, but with a press action + that moves windows our from under the cursor, the enter + event will come as a GrabNotify which is ignored, so this + makes a fake enter event + */ + if ((c = client_under_pointer())) + event_enter_client(c); + } + } } typedef struct @@ -1082,7 +1095,6 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, { GSList *it; ObAction *a; - gboolean inter = FALSE; if (!acts) return; @@ -1090,25 +1102,6 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, if (x < 0 && y < 0) screen_pointer_pos(&x, &y); - if (grab_on_keyboard()) - inter = TRUE; - else - for (it = acts; it; it = g_slist_next(it)) { - a = it->data; - if (a->data.any.interactive) { - inter = TRUE; - break; - } - } - - 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" */ - grab_keyboard(FALSE); - } - for (it = acts; it; it = g_slist_next(it)) { a = it->data; @@ -1138,8 +1131,9 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, { /* interactive actions are not queued */ a->func(&a->data); - } else if ((context == OB_FRAME_CONTEXT_CLIENT || - (c && c->type == OB_CLIENT_TYPE_DESKTOP && + } else if (c && + (context == OB_FRAME_CONTEXT_CLIENT || + (c->type == OB_CLIENT_TYPE_DESKTOP && context == OB_FRAME_CONTEXT_DESKTOP)) && (a->func == action_focus || a->func == action_activate || @@ -1194,6 +1188,25 @@ void action_execute(union ActionData *data) GError *e = NULL; gchar *cmd, **argv = 0; if (data->execute.path) { + /* Ungrab the keyboard before running the action. + + If there is an interactive action going on, then cancel it to + release the keyboard. If not, then call XUngrabKeyboard(). + + We call XUngrabKeyboard because a key press causes a passive + grab on the keyboard, and so if program we are executing wants to + grab the keyboard, it will fail if the button is still held down + (which is likely). + + Use the X function not out own, because we're not considering + a grab to be in place at all so our function won't try ungrab + anything. + */ + if (keyboard_interactively_grabbed()) + keyboard_interactive_cancel(); + else + XUngrabKeyboard(ob_display, data->any.time); + cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL); if (cmd) { if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) { @@ -1246,7 +1259,8 @@ void action_activate(union ActionData *data) { if (data->client.any.c) { if (!data->any.button || client_mouse_focusable(data->client.any.c) || - data->any.context != OB_FRAME_CONTEXT_CLIENT) + (data->any.context != OB_FRAME_CONTEXT_CLIENT && + data->any.context != OB_FRAME_CONTEXT_FRAME)) { /* if using focus_delay, stop the timer now so that focus doesn't go moving on us */ @@ -1266,7 +1280,8 @@ void action_focus(union ActionData *data) { if (data->client.any.c) { if (!data->any.button || client_mouse_focusable(data->client.any.c) || - data->any.context != OB_FRAME_CONTEXT_CLIENT) + (data->any.context != OB_FRAME_CONTEXT_CLIENT && + data->any.context != OB_FRAME_CONTEXT_FRAME)) { /* if using focus_delay, stop the timer now so that focus doesn't go moving on us */ @@ -1285,7 +1300,7 @@ void action_focus(union ActionData *data) void action_unfocus (union ActionData *data) { if (data->client.any.c == focus_client) - focus_fallback(FALSE); + focus_fallback(TRUE); } void action_iconify(union ActionData *data)