wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit d2a9e3a86049469ac2af0cde11340cd5552e130b
parent 6af8aeed4ac2c85454ff326a000941783b329a20
Author: bsdaemon <bsdaemon@comcast.net>
Date:   Wed, 31 May 2006 02:47:07 -0400

Rewrote window snapping code


Diffstat:
cmd/wm/area.c | 5++---
cmd/wm/event.c | 5+----
cmd/wm/mouse.c | 479++++++++++++++++---------------------------------------------------------------
cmd/wm/wm.h | 4++--
liblitz/blitz.h | 11+++++++++--
5 files changed, 110 insertions(+), 394 deletions(-)

diff --git a/cmd/wm/area.c b/cmd/wm/area.c @@ -147,8 +147,7 @@ place_client(Area *a, Client *c) unsigned int i, j, k, x, y, maxx, maxy, dx, dy, cx, cy, diff, num = 0; XPoint p1 = {0, 0}, p2 = {0, 0}; Frame *f = c->frame.data[c->sel]; - int snapw = rect.width * def.snap / 1000; - int snaph = rect.height * def.snap / 1000; + int snap = rect.height / 66; XRectangle *rects; if(c->trans) @@ -230,7 +229,7 @@ place_client(Area *a, Client *c) f->rect.y = a->rect.y + (random() % (diff ? diff : 1)); } - snap_move(&f->rect, rects, num, snapw, snaph); + snap_rect(rects, num, &f->rect, CENTER, snap); if(rects) free(rects); } diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -103,10 +103,7 @@ handle_buttonpress(XEvent *e) case Button3: { BlitzAlign align = blitz_quadofcoord(&c->rect, ev->x, ev->y); - if(align != CENTER) - do_mouse_resize(c, align); - else - do_mouse_move(c); + do_mouse_resize(c, align); } default: break; diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c @@ -12,150 +12,88 @@ #define ButtonMask (ButtonPressMask | ButtonReleaseMask) #define MouseMask (ButtonMask | PointerMotionMask) -static int -check_vert_match(XRectangle *r, XRectangle *neighbor) -{ - /* check if neighbor matches edge */ - return (((neighbor->y <= r->y) && (neighbor->y + neighbor->height >= r->y)) - || ((neighbor->y >= r->y) && (r->y + r->height >= neighbor->y))); -} +static void +snap_line(XRectangle *rects, int num, int x1, int y1, int x2, int y2, + int snapw, BlitzAlign mask, int *delta); -static int -check_horiz_match(XRectangle * r, XRectangle * neighbor) -{ - /* check if neighbor matches edge */ - return (((neighbor->x <= r->x) && (neighbor->x + neighbor->width >= r->x)) - || ((neighbor->x >= r->x) - && (r->x + r->width >= neighbor->x))); +static void +rect_morph_xy(XRectangle *rect, int dx, int dy, BlitzAlign mask) { + if(mask & NORTH) { + rect->y += dy; + rect->height -= dy; + } + if(mask & WEST) { + rect->x += dx; + rect->width -= dx; + } + if(mask & EAST) + rect->width += dx; + if(mask & SOUTH) + rect->height += dy; } void -snap_move(XRectangle *r, XRectangle *rects, - unsigned int num, int snapw, int snaph) -{ - int i, j, w = 0, n = 0, e = 0, s = 0; - - /* snap to other windows */ - for(i = 0; i <= snapw && !(w && e); i++) { - for(j = 0; j < num && !(w && e); j++) { - /* check west neighbors leftwards */ - if(!w) { - if(r->x - i == (rects[j].x + rects[j].width)) { - /* west edge of neighbor found, check vert match */ - w = check_vert_match(r, &rects[j]); - if(w) - r->x = rects[j].x + rects[j].width; - } - } - /* check west neighbors rightwards */ - if(!w) { - if(r->x + i == (rects[j].x + rects[j].width)) { - /* west edge of neighbor found, check vert match */ - w = check_vert_match(r, &rects[j]); - if(w) - r->x = rects[j].x + rects[j].width; - } - } - /* check east neighbors leftwards */ - if(!e) { - if(r->x + r->width - i == rects[j].x) { - /* east edge of neighbor found, check vert match */ - e = check_vert_match(r, &rects[j]); - if(e) - r->x = rects[j].x - r->width; - } - } - /* check east neighbors rightwards */ - if(!e) { - if(r->x + r->width + i == rects[j].x) { - /* east edge of neighbor found, check vert match */ - e = check_vert_match(r, &rects[j]); - if(e) - r->x = rects[j].x - r->width; - } - } - } - - /* snap to west screen border */ - if(!w && (r->x - i == rect.x)) { - w = 1; - r->x = rect.x; - } - /* snap to west screen border */ - if(!w && (r->x + i == rect.x)) { - w = 1; - r->x = rect.x; - } - /* snap to east screen border */ - if(!e && (r->x + r->width - i == rect.width)) { - e = 1; - r->x = rect.x + rect.width - r->width; - } - if(!e && (r->x + r->width + i == rect.width)) { - e = 1; - r->x = rect.x + rect.width - r->width; - } - } - - for(i = 0; i <= snaph && !(n && s); i++) { - for(j = 0; j < num && !(n && s); j++) { - /* check north neighbors upwards */ - if(!n) { - if(r->y - i == (rects[j].y + rects[j].height)) { - /* north edge of neighbor found, check horiz match */ - n = check_horiz_match(r, &rects[j]); - if(n) - r->y = rects[j].y + rects[j].height; - } - } - /* check north neighbors downwards */ - if(!n) { - if(r->y + i == (rects[j].y + rects[j].height)) { - /* north edge of neighbor found, check horiz match */ - n = check_horiz_match(r, &rects[j]); - if(n) - r->y = rects[j].y + rects[j].height; - } - } - /* check south neighbors upwards */ - if(!s) { - if(r->y + r->height - i == rects[j].y) { - /* south edge of neighbor found, check horiz match */ - s = check_horiz_match(r, &rects[j]); - if(s) - r->y = rects[j].y - r->height; - } - } - /* check south neighbors downwards */ - if(!s) { - if(r->y + r->height + i == rects[j].y) { - /* south edge of neighbor found, check horiz match */ - s = check_horiz_match(r, &rects[j]); - if(s) - r->y = rects[j].y - r->height; - } - } - } +snap_rect(XRectangle *rects, int num, XRectangle *current, + BlitzAlign mask, int snap) { + int dx = snap + 1, dy = snap + 1; + + if(mask & NORTH) + snap_line(rects, num, current->x, current->y, + current->x + current->width, current->y, + snap, mask, &dy); + if(mask & EAST) + snap_line(rects, num, current->x + current->width, current->y, + current->x + current->width, current->y + current->height, + snap, mask, &dx); + if(mask & SOUTH) + snap_line(rects, num, current->x, current->y + current->height, + current->x + current->width, current->y + current->height, + snap, mask, &dy); + if(mask & WEST) + snap_line(rects, num, current->x, current->y, + current->x, current->y + current->height, + snap, mask, &dx); + + rect_morph_xy(current, abs(dx) <= snap ? dx : 0, + abs(dy) <= snap ? dy : 0, mask); +} - /* snap to north screen border */ - if(!n && (r->y - i == rect.y)) { - n = 1; - r->y = rect.y; - } - if(!n && (r->y + i == rect.y)) { - n = 1; - r->y = rect.y; - } - /* snap to south screen border */ - if(!s && (r->y + r->height - i == rect.height)) { - s = 1; - r->y = rect.y + rect.height - r->height; - } - if(!s && (r->y + r->height + i == rect.height)) { - s = 1; - r->y = rect.y + rect.height - r->height; - } - } +static void +snap_line(XRectangle *rects, int num, int x1, int y1, int x2, int y2, + int snapw, BlitzAlign mask, int *delta) { + int i, t_xy; + + /* horizontal */ + if(y1 == y2 && (mask & (NORTH|SOUTH))) { + for(i=0; i < num; i++) { + if(!((rects[i].x + rects[i].width < x1) || + (rects[i].x > x2))) { + + if(abs(rects[i].y - y1) <= abs(*delta)) + *delta = rects[i].y - y1; + + t_xy = rects[i].y + rects[i].height; + if(abs(t_xy - y1) < abs(*delta)) + *delta = t_xy - y1; + } + } + } + else if (mask & (EAST|WEST)) { + /* This is the same as above, tr/xy/yx/, + * s/width/height/, s/height/width/ */ + for(i=0; i < num; i++) { + if(!((rects[i].y + rects[i].height < y1) || + (rects[i].y > y2))) { + + if(abs(rects[i].x - x1) <= abs(*delta)) + *delta = rects[i].x - x1; + + t_xy = rects[i].x + rects[i].width; + if(abs(t_xy - x1) < abs(*delta)) + *delta = t_xy - x1; + } + } + } } static void @@ -180,241 +118,7 @@ draw_xor_border(XRectangle *r) void do_mouse_move(Client *c) { - int px = 0, py = 0, wex, wey, ex, ey, i; - Window dummy; - XEvent ev; - unsigned int num = 0; - unsigned int dmask; - Frame *f = c->frame.data[c->sel]; - int aidx = idx_of_area(f->area); - int snapw = aidx ? 0 : (rect.width * def.snap) / 1000; - int snaph = aidx ? 0 : (rect.height * def.snap) / 1000; - XRectangle *rects = aidx ? nil : rects_of_view(f->area->view, &num); - XRectangle frect = f->rect; - XPoint pt; - - XQueryPointer(dpy, c->framewin, &dummy, &dummy, &i, &i, &wex, &wey, &dmask); - XTranslateCoordinates(dpy, c->framewin, root, wex, wey, &ex, &ey, &dummy); - pt.x = ex; - pt.y = ey; - XSync(dpy, False); - - if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, - None, cursor[CurMove], CurrentTime) != GrabSuccess) - return; - - XGrabServer(dpy); - draw_xor_border(&frect); - for(;;) { - XMaskEvent(dpy, MouseMask | ExposureMask, &ev); - switch (ev.type) { - case ButtonRelease: - draw_xor_border(&frect); - if(aidx) - resize_column(c, &frect, &pt); - else - resize_client(c, &frect, False); - if(rects) - free(rects); - XUngrabServer(dpy); - XUngrabPointer(dpy, CurrentTime); - XSync(dpy, False); - return; - break; - case MotionNotify: - draw_xor_border(&frect); - pt.x = ev.xmotion.x; - pt.y = ev.xmotion.y; - XTranslateCoordinates(dpy, c->framewin, root, ev.xmotion.x, - ev.xmotion.y, &px, &py, &dummy); - frect.x = px - ex; - frect.y = py - ey; - if(!aidx) - snap_move(&frect, rects, num, snapw, snaph); - draw_xor_border(&frect); - break; - case Expose: - (handler[Expose])(&ev); - break; - default: break; - } - } -} - -static void -snap_resize(XRectangle *r, XRectangle *o, BlitzAlign align, - XRectangle *rects, unsigned int num, int px, int ox, int py, - int oy, int snapw, int snaph) -{ - int i, j, pend = 0; - int w, h; - - /* x */ - switch (align) { - case NEAST: - case SEAST: - w = px - r->x + (o->width - ox); - if(w < 10) - break; - r->width = w; - if(w <= snapw) - break; - /* snap to border */ - for(i = 0; !pend && (i < snapw); i++) { - if(r->x + r->width - i == rect.x + rect.width) { - r->width -= i; - break; - } - if(r->x + r->width + i == rect.x + rect.width) { - r->width += i; - break; - } - for(j = 0; j < num; j++) { - if(r->x + r->width - i == rects[j].x) { - pend = check_vert_match(r, &rects[j]); - if(pend) { - r->width -= i; - break; - } - } - if(r->x + r->width + i == rects[j].x) { - pend = check_vert_match(r, &rects[j]); - if(pend) { - r->width += i; - break; - } - } - } - } - break; - case NWEST: - case SWEST: - w = r->width + r->x - px + ox; - if(w < 10) - break; - r->width = w; - r->x = px - ox; - if(w <= snapw) - break; - /* snap to border */ - for(i = 0; !pend && (i < snapw); i++) { - if(r->x - i == rect.x) { - r->x -= i; - r->width += i; - break; - } - if(r->x + i == rect.x) { - r->x += i; - r->width -= i; - break; - } - for(j = 0; j < num; j++) { - if(r->x - i == rects[j].x + rects[j].width) { - pend = check_vert_match(r, &rects[j]); - if(pend) { - r->x -= i; - r->width += i; - break; - } - } - if(r->x + i == rects[j].x + rects[j].width) { - pend = check_vert_match(r, &rects[j]); - if(pend) { - r->x += i; - r->width -= i; - break; - } - } - } - } - break; - default: - break; - } - - /* y */ - pend = 0; - switch (align) { - case SWEST: - case SEAST: - h = py - r->y + (o->height - oy); - if(h < 10) - break; - r->height = h; - if(h <= snaph) - break; - /* snap to border */ - for(i = 0; !pend && (i < snaph); i++) { - if(r->y + r->height - i == rect.y + rect.height) { - r->height -= i; - break; - } - if(r->y + r->height + i == rect.y + rect.height) { - r->height += i; - break; - } - for(j = 0; j < num; j++) { - if(r->y + r->height - i == rects[j].y) { - pend = check_horiz_match(r, &rects[j]); - if(pend) { - r->height -= i; - break; - } - } - if(r->y + r->height + i == rects[j].y) { - pend = check_horiz_match(r, &rects[j]); - if(pend) { - r->height += i; - break; - } - } - } - } - break; - case NWEST: - case NEAST: - h = r->height + r->y - py + oy; - if(h < 10) - break; - r->height = h; - r->y = py - oy; - if(h <= snaph) - break; - /* snap to border */ - for(i = 0; !pend && (i < snaph); i++) { - if(r->y - i == rect.y) { - r->y -= i; - r->height += i; - break; - } - if(r->y + i == rect.y) { - r->y += i; - r->height -= i; - break; - } - for(j = 0; j < num; j++) { - if(r->y - i == rects[j].y + rects[j].height) { - pend = check_horiz_match(r, &rects[j]); - if(pend) { - r->y -= i; - r->height += i; - break; - } - } - if(r->y + i == rects[j].y + rects[j].height) { - pend = check_horiz_match(r, &rects[j]); - if(pend) { - r->y += i; - r->height -= i; - break; - } - } - } - } - break; - default: - break; - } + do_mouse_resize(c, CENTER); } void @@ -423,23 +127,23 @@ do_mouse_resize(Client *c, BlitzAlign align) int px = 0, py = 0, i, ox, oy; Window dummy; XEvent ev; - unsigned int dmask; unsigned int num = 0; Frame *f = c->frame.data[c->sel]; int aidx = idx_of_area(f->area); - int snapw = aidx ? 0 : (rect.width * def.snap) / 1000; - int snaph = aidx ? 0 : (rect.height * def.snap) / 1000; + int snap = aidx ? 0 : rect.height / 66; XRectangle *rects = aidx ? nil : rects_of_view(f->area->view, &num); XRectangle frect = f->rect; XRectangle origin = frect; + XPoint pt; - XQueryPointer(dpy, c->framewin, &dummy, &dummy, &i, &i, &ox, &oy, &dmask); + XQueryPointer(dpy, c->framewin, &dummy, &dummy, &ox, &oy, &i, &i, &i); + pt.x = ox; pt.y = oy; XSync(dpy, False); if(XGrabPointer(dpy, c->framewin, False, MouseMask, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize], CurrentTime) != GrabSuccess) + None, cursor[CurResize], CurrentTime) != GrabSuccess) return; - + XGrabServer(dpy); draw_xor_border(&frect); for(;;) { @@ -448,7 +152,7 @@ do_mouse_resize(Client *c, BlitzAlign align) case ButtonRelease: draw_xor_border(&frect); if(aidx) - resize_column(c, &frect, nil); + resize_column(c, &frect, (align == CENTER) ? &pt : nil); else resize_client(c, &frect, False); if(rects) @@ -460,10 +164,19 @@ do_mouse_resize(Client *c, BlitzAlign align) break; case MotionNotify: draw_xor_border(&frect); + + pt.x = ev.xmotion.x; + pt.y = ev.xmotion.y; XTranslateCoordinates(dpy, c->framewin, root, ev.xmotion.x, ev.xmotion.y, &px, &py, &dummy); - snap_resize(&frect, &origin, align, rects, num, px, - ox, py, oy, snapw, snaph); + + rect_morph_xy(&origin, px-ox, py-oy, align); + frect=origin; + ox=px; oy=py; + + if(!aidx) + snap_rect(rects, num, &frect, align, snap); + draw_xor_border(&frect); break; case Expose: diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -300,8 +300,8 @@ void do_mouse_resize(Client *c,BlitzAlign align); void do_mouse_move(Client *c); void grab_mouse(Window w, unsigned long mod, unsigned int button); void ungrab_mouse(Window w, unsigned long mod, unsigned int button); -void snap_move(XRectangle *r, XRectangle *rects, unsigned int num, - int snapw, int snaph); +void snap_rect(XRectangle *rects, int num, XRectangle *current, + BlitzAlign mask, int snap); /* rule.c */ void update_rules(RuleVector *rule, const char *data); diff --git a/liblitz/blitz.h b/liblitz/blitz.h @@ -25,8 +25,15 @@ */ typedef enum { - CENTER, WEST, NWEST, NORTH, NEAST, EAST, - SEAST, SOUTH, SWEST + NORTH = 0x01, + EAST = 0x02, + SOUTH = 0x04, + WEST = 0x08, + NEAST = NORTH | EAST, + NWEST = NORTH | WEST, + SEAST = SOUTH | EAST, + SWEST = SOUTH | WEST, + CENTER = NEAST | SWEST } BlitzAlign; typedef struct {