]> Dogcows Code - chaz/openbox/blobdiff - openbox/action.c
don't listen to focus events in the dock, unless you're going to do it properly
[chaz/openbox] / openbox / action.c
index 8e7b56a341dffe0c14a3636893396d6385201149..20bf686f2e69701f31580d9c0a350d2c2ee4fe18 100644 (file)
@@ -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)
This page took 0.023054 seconds and 4 git commands to generate.