From: Dana Jansens Date: Fri, 21 Mar 2003 09:31:23 +0000 (+0000) Subject: add a window resistance plugin X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=34ab5a1fb88f910d1a2d4e5f40859edcf035150b;p=chaz%2Fopenbox add a window resistance plugin --- diff --git a/plugins/.cvsignore b/plugins/.cvsignore index 618dd114..1d0256fb 100644 --- a/plugins/.cvsignore +++ b/plugins/.cvsignore @@ -5,3 +5,5 @@ Makefile.in .libs .deps focus_la-focus.lo +resistance.la +resistance_la-resistance.lo diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 97d6d53f..b56f3206 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -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 index 00000000..e60b683e --- /dev/null +++ b/plugins/resistance.c @@ -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 + +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); +}