]> Dogcows Code - chaz/openbox/blobdiff - plugins/focus.c
warp the pointer on a workspace change to the focused window
[chaz/openbox] / plugins / focus.c
index b717f38fd4916aa7fd507c2c80db0ade26d497fc..52e6f99ec0bf4d745e498ea668abcd143293c73c 100644 (file)
@@ -1,15 +1,31 @@
 #include "../kernel/dispatch.h"
 #include "../kernel/screen.h"
 #include "../kernel/client.h"
+#include "../kernel/focus.h"
 #include "../kernel/stacking.h"
+#include "../kernel/openbox.h"
 
 static GSList **focus_order = NULL;
 
+static void focus_fallback(guint desk, gboolean warp)
+{
+    GSList *it;
+
+    for (it = focus_order[desk]; it != NULL; it = it->next)
+        if (client_focus(it->data)) {
+            if (warp) { /* XXX make this configurable */
+                Client *c = it->data;
+                XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
+                             c->area.width / 2, c->area.height / 2);
+            }
+            break;
+        }
+}
+
 static void events(ObEvent *e, void *foo)
 {
     guint i;
     guint new, old;
-    GSList *it;
 
     switch (e->type) {
     case Event_Client_Mapped:
@@ -18,6 +34,11 @@ static void events(ObEvent *e, void *foo)
             client_focus(e->data.c.client);
         break;
 
+    case Event_Client_Destroy:
+        i = e->data.c.client->desktop;
+        focus_order[i] = g_slist_remove(focus_order[i], e->data.c.client);
+        break;
+
     case Event_Ob_NumDesktops:
         new = e->data.o.num[0];
         old = e->data.o.num[1];
@@ -43,9 +64,15 @@ static void events(ObEvent *e, void *foo)
         break;
 
     case Event_Ob_Desktop:
-        for (it = focus_order[e->data.o.num[0]]; it != NULL; it = it->next)
-            if (client_focus(it->data))
-                break;
+        /* focus the next available target */
+        focus_fallback(e->data.o.num[0], TRUE);
+        break;
+
+    case Event_Client_Unfocus:
+        /* nothing is left with focus! */
+        if (focus_client == NULL) 
+            /* focus the next available target */
+            focus_fallback(screen_desktop, FALSE);
         break;
 
     case Event_Client_Focus:
@@ -65,9 +92,11 @@ void plugin_startup()
 {
     guint i;
 
-    dispatch_register(Event_Client_Mapped | Event_Ob_Desktop |
-                      Event_Ob_NumDesktops | Event_Client_Focus |
-                      Event_Client_Desktop, (EventHandler)events, NULL);
+    dispatch_register(Event_Client_Mapped | Event_Client_Destroy |
+                      Event_Ob_Desktop | Event_Ob_NumDesktops |
+                      Event_Client_Focus | Event_Client_Unfocus |
+                      Event_Client_Desktop,
+                      (EventHandler)events, NULL);
 
     focus_order = g_new(GSList*, screen_num_desktops);
     for (i = 0; i < screen_num_desktops; ++i)
This page took 0.024116 seconds and 4 git commands to generate.