]> Dogcows Code - chaz/openbox/blobdiff - openbox/action.c
add <underMouse> focus option
[chaz/openbox] / openbox / action.c
index acb33749d72bd995335e75577e2d9e6004c9a30a..de5f9a8a089682b0c96bd842f8766d840c444455 100644 (file)
@@ -43,21 +43,22 @@ static void client_action_start(union ActionData *data)
 {
 }
 
-static void client_action_end(union ActionData *data)
+static void client_action_end(union ActionData *data, gboolean allow_enters)
 {
     if (config_focus_follow)
         if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
-            if (!data->any.button && data->any.c)
+            if (!data->any.button && data->any.c && !allow_enters) {
                 event_ignore_all_queued_enters();
-            else {
-                /* we USED to create a fake enter event here, so that when you
-                   used a Press context, and the button was still down,
-                   you could still get enter events that weren't
-                   NotifyWhileGrabbed.
-
-                   only problem with this is that then the resulting focus
-                   change events can ALSO be NotifyWhileGrabbed. And that is
-                   bad. So, don't create fake enter events anymore. */
+            } 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);
             }
         }
 }
@@ -1150,13 +1151,9 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context,
             {
                 /* 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.
@@ -1176,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
@@ -1215,11 +1216,9 @@ 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 an interactive action going on, then cancel it
-               to release the keyboard, so that the run application
-               can grab the keyboard if it wants to. */
-            if (keyboard_interactively_grabbed())
-                keyboard_interactive_cancel();
+            /* 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"),
@@ -1312,14 +1311,14 @@ 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)
 {
     client_action_start(data);
     client_iconify(data->client.any.c, TRUE, TRUE, FALSE);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_focus_order_to_bottom(union ActionData *data)
@@ -1330,38 +1329,17 @@ 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, config_focus_under_mouse);
 }
 
 void action_raise(union ActionData *data)
 {
     client_action_start(data);
     stacking_raise(CLIENT_AS_WINDOW(data->client.any.c));
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_unshaderaise(union ActionData *data)
@@ -1384,7 +1362,7 @@ void action_lower(union ActionData *data)
 {
     client_action_start(data);
     stacking_lower(CLIENT_AS_WINDOW(data->client.any.c));
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_close(union ActionData *data)
@@ -1401,21 +1379,21 @@ void action_shade(union ActionData *data)
 {
     client_action_start(data);
     client_shade(data->client.any.c, TRUE);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_unshade(union ActionData *data)
 {
     client_action_start(data);
     client_shade(data->client.any.c, FALSE);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_shade(union ActionData *data)
 {
     client_action_start(data);
     client_shade(data->client.any.c, !data->client.any.c->shaded);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_omnipresent(union ActionData *data)
@@ -1430,7 +1408,7 @@ void action_move_relative_horz(union ActionData *data)
     ObClient *c = data->relative.any.c;
     client_action_start(data);
     client_move(c, c->area.x + data->relative.deltax, c->area.y);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_move_relative_vert(union ActionData *data)
@@ -1438,7 +1416,7 @@ void action_move_relative_vert(union ActionData *data)
     ObClient *c = data->relative.any.c;
     client_action_start(data);
     client_move(c, c->area.x, c->area.y + data->relative.deltax);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_move_to_center(union ActionData *data)
@@ -1449,7 +1427,7 @@ void action_move_to_center(union ActionData *data)
     client_action_start(data);
     client_move(c, area->width / 2 - c->area.width / 2,
                 area->height / 2 - c->area.height / 2);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_resize_relative_horz(union ActionData *data)
@@ -1459,7 +1437,7 @@ void action_resize_relative_horz(union ActionData *data)
     client_resize(c,
                   c->area.width + data->relative.deltax * c->size_inc.width,
                   c->area.height);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_resize_relative_vert(union ActionData *data)
@@ -1469,7 +1447,7 @@ void action_resize_relative_vert(union ActionData *data)
         client_action_start(data);
         client_resize(c, c->area.width, c->area.height +
                       data->relative.deltax * c->size_inc.height);
-        client_action_end(data);
+        client_action_end(data, FALSE);
     }
 }
 
@@ -1479,7 +1457,7 @@ void action_move_relative(union ActionData *data)
     client_action_start(data);
     client_move(c, c->area.x + data->relative.deltax, c->area.y +
                 data->relative.deltay);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_resize_relative(union ActionData *data)
@@ -1500,21 +1478,21 @@ void action_resize_relative(union ActionData *data)
     
     client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
     client_move_resize(c, x + (ow - w), y + (oh - h), w, h);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_maximize_full(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, TRUE, 0);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_unmaximize_full(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, FALSE, 0);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_maximize_full(union ActionData *data)
@@ -1524,21 +1502,21 @@ void action_toggle_maximize_full(union ActionData *data)
                     !(data->client.any.c->max_horz ||
                       data->client.any.c->max_vert),
                     0);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_maximize_horz(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, TRUE, 1);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_unmaximize_horz(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, FALSE, 1);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_maximize_horz(union ActionData *data)
@@ -1546,21 +1524,21 @@ void action_toggle_maximize_horz(union ActionData *data)
     client_action_start(data);
     client_maximize(data->client.any.c,
                     !data->client.any.c->max_horz, 1);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_maximize_vert(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, TRUE, 2);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_unmaximize_vert(union ActionData *data)
 {
     client_action_start(data);
     client_maximize(data->client.any.c, FALSE, 2);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_maximize_vert(union ActionData *data)
@@ -1568,14 +1546,14 @@ void action_toggle_maximize_vert(union ActionData *data)
     client_action_start(data);
     client_maximize(data->client.any.c,
                     !data->client.any.c->max_vert, 2);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_fullscreen(union ActionData *data)
 {
     client_action_start(data);
     client_fullscreen(data->client.any.c, !(data->client.any.c->fullscreen));
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_send_to_desktop(union ActionData *data)
@@ -1588,7 +1566,7 @@ void action_send_to_desktop(union ActionData *data)
         data->sendto.desk == DESKTOP_ALL) {
         client_set_desktop(c, data->sendto.desk, data->sendto.follow);
         if (data->sendto.follow && data->sendto.desk != screen_desktop)
-            screen_set_desktop(data->sendto.desk, c == focus_client);
+            screen_set_desktop(data->sendto.desk, TRUE);
     }
 }
 
@@ -1621,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);
     }
 }
 
@@ -1645,7 +1624,7 @@ void action_send_to_desktop_dir(union ActionData *data)
     {
         client_set_desktop(c, d, data->sendtodir.follow);
         if (data->sendtodir.follow && d != screen_desktop)
-            screen_set_desktop(d, c == focus_client);
+            screen_set_desktop(d, TRUE);
     }
 }
 
@@ -1660,7 +1639,7 @@ void action_toggle_decorations(union ActionData *data)
 
     client_action_start(data);
     client_set_undecorated(c, !c->undecorated);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
@@ -1893,7 +1872,7 @@ void action_movetoedge(union ActionData *data)
     frame_frame_gravity(c->frame, &x, &y, c->area.width, c->area.height);
     client_action_start(data);
     client_move(c, x, y);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_growtoedge(union ActionData *data)
@@ -1960,7 +1939,7 @@ void action_growtoedge(union ActionData *data)
     frame_frame_gravity(c->frame, &x, &y, width, height);
     client_action_start(data);
     client_move_resize(c, x, y, width, height);
-    client_action_end(data);
+    client_action_end(data, FALSE);
 }
 
 void action_send_to_layer(union ActionData *data)
@@ -1977,7 +1956,7 @@ void action_toggle_layer(union ActionData *data)
         client_set_layer(c, c->below ? 0 : -1);
     else if (data->layer.layer > 0)
         client_set_layer(c, c->above ? 0 : 1);
-    client_action_end(data);
+    client_action_end(data, config_focus_under_mouse);
 }
 
 void action_toggle_dockautohide(union ActionData *data)
This page took 0.030318 seconds and 4 git commands to generate.