]> Dogcows Code - chaz/openbox/blobdiff - openbox/action.c
revert 7246 and simplify action_raiselower a bit, turns out 7246 wasn't needed for...
[chaz/openbox] / openbox / action.c
index 931cff392917417e0faba141f1668a995045b853..39c1169b3f8f996b0e9e97a6154543ee3deb7fbe 100644 (file)
@@ -20,6 +20,7 @@
 #include "debug.h"
 #include "client.h"
 #include "focus.h"
+#include "focus_cycle.h"
 #include "moveresize.h"
 #include "menu.h"
 #include "prop.h"
 
 #include <glib.h>
 
-inline void client_action_start(union ActionData *data)
+static 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);
 }
 
-inline void client_action_end(union ActionData *data)
+static 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 && data->any.c) {
+                event_ignore_all_queued_enters();
+            } 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()) && c != data->any.c)
+                    event_enter_client(c);
+            }
+        }
 }
 
 typedef struct
@@ -82,6 +93,8 @@ void action_unref(ObAction *a)
     /* deal with pointers */
     if (a->func == action_execute || a->func == action_restart)
         g_free(a->data.execute.path);
+    else if (a->func == action_debug)
+        g_free(a->data.debug.string);
     else if (a->func == action_showmenu)
         g_free(a->data.showmenu.name);
 
@@ -97,6 +110,8 @@ ObAction* action_copy(const ObAction *src)
     /* deal with pointers */
     if (a->func == action_execute || a->func == action_restart)
         a->data.execute.path = g_strdup(a->data.execute.path);
+    else if (a->func == action_debug)
+        a->data.debug.string = g_strdup(a->data.debug.string);
     else if (a->func == action_showmenu)
         a->data.showmenu.name = g_strdup(a->data.showmenu.name);
 
@@ -243,7 +258,9 @@ void setup_action_send_to_desktop_down(ObAction **a, ObUserAction uact)
 
 void setup_action_desktop(ObAction **a, ObUserAction uact)
 {
+/*
     (*a)->data.desktop.inter.any.interactive = FALSE;
+*/
 }
 
 void setup_action_desktop_prev(ObAction **a, ObUserAction uact)
@@ -458,9 +475,14 @@ void setup_client_action(ObAction **a, ObUserAction uact)
 
 ActionString actionstrings[] =
 {
+    {
+        "debug", 
+        action_debug,
+        NULL
+    },
     {
         "execute", 
-        action_execute, 
+        action_execute,
         NULL
     },
     {
@@ -961,6 +983,9 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                     if ((m = parse_find_node("icon", n->xmlChildrenNode)))
                         act->data.execute.icon_name = parse_string(doc, m);
                 }
+            } else if (act->func == action_debug) {
+                if ((n = parse_find_node("string", node->xmlChildrenNode)))
+                    act->data.debug.string = parse_string(doc, n);
             } else if (act->func == action_showmenu) {
                 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
                     act->data.showmenu.name = parse_string(doc, n);
@@ -988,9 +1013,11 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
                     act->data.desktop.desk = parse_int(doc, n);
                 if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+/*
                 if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
                     act->data.desktop.inter.any.interactive =
                         parse_bool(doc, n);
+*/
            } else if (act->func == action_send_to_desktop) {
                 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
                     act->data.sendto.desk = parse_int(doc, n);
@@ -1082,7 +1109,6 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
 {
     GSList *it;
     ObAction *a;
-    gboolean inter = FALSE;
 
     if (!acts)
         return;
@@ -1090,33 +1116,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 && button == 0) {
-        /* Ungrab the keyboard before running the action, if it was
-           not from a mouse event.
-
-           We have to do this because a key press causes a passive
-           grab on the keyboard, and so if the action we are running
-           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.
-        */
-        XUngrabKeyboard(ob_display, time);
-    }
-
     for (it = acts; it; it = g_slist_next(it)) {
         a = it->data;
 
@@ -1140,19 +1139,21 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
 
             /* XXX UGLY HACK race with motion event starting a move and the
                button release gettnig processed first. answer: don't queue
-               moveresize starts. UGLY HACK XXX */
+               moveresize starts. UGLY HACK XXX
+
+               XXX ALSO don't queue showmenu events, because on button press
+               events we need to know if a mouse grab is going to take place,
+               and set the button to 0, so that later motion events don't think
+               that a drag is going on. since showmenu grabs the pointer..
+            */
             if (a->data.any.interactive || a->func == action_move ||
-                a->func == action_resize)
+                a->func == action_resize || a->func == action_showmenu)
             {
                 /* interactive actions are not queued */
                 a->func(&a->data);
-            } 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 ||
-                        a->func == action_showmenu))
+            } else if (a->func == action_focus ||
+                       a->func == action_activate ||
+                       a->func == action_showmenu)
             {
                 /* XXX MORE UGLY HACK
                    actions from clicks on client windows are NOT queued.
@@ -1172,11 +1173,15 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
                    pointer. ugh.
 
                    also with the menus, there is a race going on. if the
-                   desktop wants to pop up a menu, and we do to, we send them
+                   desktop wants to pop up a menu, and we do too, we send them
                    the button before we pop up the menu, so they pop up their
                    menu first. but not always. if we pop up our menu before
                    sending them the button press, then the result is
                    deterministic. yay.
+
+                   XXX further more. focus actions are not queued at all,
+                   because if you bind focus->showmenu, the menu will get
+                   hidden to do the focusing
                 */
                 a->func(&a->data);
             } else
@@ -1198,6 +1203,12 @@ void action_run_string(const gchar *name, struct _ObClient *c, Time time)
     action_run(l, c, 0, time);
 }
 
+void action_debug(union ActionData *data)
+{
+    if (data->debug.string)
+        g_print("%s\n", data->debug.string);
+}
+
 void action_execute(union ActionData *data)
 {
     GError *e = NULL;
@@ -1205,6 +1216,10 @@ void action_execute(union ActionData *data)
     if (data->execute.path) {
         cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
         if (cmd) {
+            /* If there is a keyboard grab going on then we need to cancel
+               it so the application can grab things */
+            event_cancel_all_key_grabs();
+
             if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) {
                 g_message(_("Failed to execute '%s': %s"),
                           cmd, e->message);
@@ -1255,7 +1270,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 */
@@ -1275,7 +1291,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 */
@@ -1294,7 +1311,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(FALSE, FALSE);
 }
 
 void action_iconify(union ActionData *data)
@@ -1312,31 +1329,10 @@ void action_focus_order_to_bottom(union ActionData *data)
 void action_raiselower(union ActionData *data)
 {
     ObClient *c = data->client.any.c;
-    GList *it;
-    gboolean raise = FALSE;
-
-    for (it = stacking_list; it; it = g_list_next(it)) {
-        if (WINDOW_IS_CLIENT(it->data)) {
-            ObClient *cit = it->data;
-
-            if (cit == c) break;
-            if (client_normal(cit) == client_normal(c) &&
-                cit->layer == c->layer &&
-                cit->frame->visible &&
-                !client_search_transient(c, cit))
-            {
-                if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
-                    raise = TRUE;
-                    break;
-                }
-            }
-        }
-    }
 
-    if (raise)
-        action_raise(data);
-    else
-        action_lower(data);
+    client_action_start(data);
+    stacking_restack_request(c, NULL, Opposite, FALSE);
+    client_action_end(data);
 }
 
 void action_raise(union ActionData *data)
@@ -1569,25 +1565,22 @@ void action_send_to_desktop(union ActionData *data)
     if (data->sendto.desk < screen_num_desktops ||
         data->sendto.desk == DESKTOP_ALL) {
         client_set_desktop(c, data->sendto.desk, data->sendto.follow);
-        if (data->sendto.follow)
+        if (data->sendto.follow && data->sendto.desk != screen_desktop)
             screen_set_desktop(data->sendto.desk, TRUE);
     }
 }
 
 void action_desktop(union ActionData *data)
 {
-    if (!data->inter.any.interactive ||
-        (!data->inter.cancel && !data->inter.final))
+    /* XXX add the interactive/dialog option back again once the dialog
+       has been made to not use grabs */
+    if (data->desktop.desk < screen_num_desktops ||
+        data->desktop.desk == DESKTOP_ALL)
     {
-        if (data->desktop.desk < screen_num_desktops ||
-            data->desktop.desk == DESKTOP_ALL)
-        {
-            screen_set_desktop(data->desktop.desk, TRUE);
-            if (data->inter.any.interactive)
-                screen_desktop_popup(data->desktop.desk, TRUE);
-        }
-    } else
-        screen_desktop_popup(0, FALSE);
+        screen_set_desktop(data->desktop.desk, TRUE);
+        if (data->inter.any.interactive)
+            screen_desktop_popup(data->desktop.desk, TRUE);
+    }
 }
 
 void action_desktop_dir(union ActionData *data)
@@ -1606,7 +1599,8 @@ void action_desktop_dir(union ActionData *data)
     if (!data->sendtodir.inter.any.interactive ||
         (data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
     {
-        if (d != screen_desktop) screen_set_desktop(d, TRUE);
+        if (d != screen_desktop)
+            screen_set_desktop(d, TRUE);
     }
 }
 
This page took 0.037399 seconds and 4 git commands to generate.