]> Dogcows Code - chaz/openbox/commitdiff
add a window resistance plugin
authorDana Jansens <danakj@orodu.net>
Fri, 21 Mar 2003 09:31:23 +0000 (09:31 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 21 Mar 2003 09:31:23 +0000 (09:31 +0000)
plugins/.cvsignore
plugins/Makefile.am
plugins/resistance.c [new file with mode: 0644]

index 618dd1146b4076c3a86534410e769e545762f59e..1d0256fb4e48a85b7ff097a802a38bf1a4c8f6de 100644 (file)
@@ -5,3 +5,5 @@ Makefile.in
 .libs
 .deps
 focus_la-focus.lo
+resistance.la
+resistance_la-resistance.lo
index 97d6d53fedb381f301a496c16fb8cbccc7f73564..b56f3206929dee12e5c33d4e450e279375a47dcd 100644 (file)
@@ -5,12 +5,16 @@ SUBDIRS = keyboard mouse placement
 CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
 -DPLUGINDIR=\"$(plugindir)\"
 
-plugin_LTLIBRARIES=focus.la
+plugin_LTLIBRARIES=focus.la resistance.la
 
 focus_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Focus\"
 focus_la_LDFLAGS=-module -avoid-version
 focus_la_SOURCES=focus.c
 
+resistance_la_CPPFLAGS=-DG_LOG_DOMAIN=\"Plugin-Resistance\"
+resistance_la_LDFLAGS=-module -avoid-version
+resistance_la_SOURCES=resistance.c
+
 noinst_HEADERS=
 
 MAINTAINERCLEANFILES= Makefile.in
diff --git a/plugins/resistance.c b/plugins/resistance.c
new file mode 100644 (file)
index 0000000..e60b683
--- /dev/null
@@ -0,0 +1,99 @@
+#include "../kernel/dispatch.h"
+#include "../kernel/client.h"
+#include "../kernel/frame.h"
+#include "../kernel/stacking.h"
+#include "../kernel/screen.h"
+#include <glib.h>
+
+static int resistance = 10;
+static gboolean edge_resistance = TRUE; /* window-to-edge */
+static gboolean window_resistance = TRUE; /* window-to-window */
+
+static void resist(Client *c, int *x, int *y)
+{
+    GList *it;
+    Rect *area;
+    int l, t, r, b; /* requested edges */
+    int al, at, ar, ab; /* screen area edges */
+    int cl, ct, cr, cb; /* current edges */
+    int w, h; /* current size */
+    gboolean snapx = FALSE, snapy = FALSE;
+
+    if (!edge_resistance) return;
+
+    w = c->frame->area.width;
+    h = c->frame->area.height;
+
+    l = *x;
+    t = *y;
+    r = l + w - 1;
+    b = t + h - 1;
+
+    cl = c->frame->area.x;
+    ct = c->frame->area.y;
+    cr = cl + c->frame->area.width - 1;
+    cb = ct + c->frame->area.height - 1;
+    
+    /* snap to other clients */
+    if (window_resistance)
+        for (it = stacking_list; it != NULL; it = it->next) {
+            Client *target;
+            int tl, tt, tr, tb; /* 1 past the target's edges on each side */
+
+            target = it->data;
+
+            tl = target->frame->area.x - 1;
+            tt = target->frame->area.y - 1;
+            tr = tl + target->frame->area.width + 1;
+            tb = tt + target->frame->area.height + 1;
+
+            /* snapx and snapy ensure that the window snaps to the top-most
+               window edge available, without going all the way from
+               bottom-to-top in the stacking list
+            */
+            if (!snapx && cl >= tr && l < tr && l >= tr - resistance)
+                *x = tr, snapx = TRUE;
+            else if (!snapx && cr <= tl && r > tl && r <= tl + resistance)
+                *x = tl - w + 1, snapx = TRUE;
+            else if (!snapy && ct >= tb && t < tb && t >= tb - resistance)
+                *y = tb, snapy = TRUE;
+            else if (!snapy && cb <= tt && b > tt && b <= tt + resistance)
+                *y = tt - h + 1, snapy = TRUE;
+
+            if (snapx && snapy) break;
+        }
+
+    /* get the screen boundaries */
+    area = screen_area(c->desktop);
+    al = area->x;
+    at = area->y;
+    ar = al + area->width - 1;
+    ab = at + area->height - 1;
+
+    /* snap to screen edges */
+    if (cl >= al && l < al && l >= al - resistance)
+        *x = al;
+    else if (cr <= ar && r > ar && r <= ar + resistance)
+            *x = ar - w + 1;
+    if (ct >= at && t < at && t >= at - resistance)
+        *y = at;
+    else if (cb <= ab && b > ab && b < ab + resistance)
+        *y = ab - h + 1;
+}
+
+static void event(ObEvent *e, void *foo)
+{
+    g_assert(e->type == Event_Client_Moving);
+
+    resist(e->data.c.client, &e->data.c.num[0], &e->data.c.num[1]);
+}
+
+void plugin_startup()
+{
+    dispatch_register(Event_Client_Moving, (EventHandler)event, NULL);
+}
+
+void plugin_shutdown()
+{
+    dispatch_register(0, (EventHandler)event, NULL);
+}
This page took 0.028424 seconds and 4 git commands to generate.