diff -r ef1026c88059 dwm.c
--- a/dwm.c	Tue Sep 09 20:47:01 2008 +0100
+++ b/dwm.c	Sat Sep 27 22:41:49 2008 -0700
@@ -154,6 +154,7 @@
 static void focusin(XEvent *e);
 static void focusstack(const Arg *arg);
 static Client *getclient(Window w);
+static Client *getclientunderpt(int x, int y);
 static unsigned long getcolor(const char *colstr);
 static long getstate(Window w);
 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
@@ -182,6 +183,7 @@
 static void setup(void);
 static void showhide(Client *c);
 static void spawn(const Arg *arg);
+static void swap(Client *c1, Client *c2);
 static void tag(const Arg *arg);
 static int textnw(const char *text, unsigned int len);
 static void tile(void);
@@ -670,6 +672,16 @@
 	return c;
 }
 
+Client *
+getclientunderpt(int x, int y) {
+	Client *c;
+
+	for(c = nexttiled(clients); c; c = nexttiled(c->next))
+		if(x >= c->x && x < c->x+c->w && y >= c->y && y < c->y+c->h)
+			return c;
+	return 0;
+}
+
 unsigned long
 getcolor(const char *colstr) {
 	Colormap cmap = DefaultColormap(dpy, screen);
@@ -938,7 +950,7 @@
 movemouse(const Arg *arg) {
 	int x, y, ocx, ocy, di, nx, ny;
 	unsigned int dui;
-	Client *c;
+	Client *c, *c2;
 	Window dummy;
 	XEvent ev;
 
@@ -961,23 +973,32 @@
 			break;
 		case MotionNotify:
 			XSync(dpy, False);
-			nx = ocx + (ev.xmotion.x - x);
-			ny = ocy + (ev.xmotion.y - y);
-			if(snap && nx >= wx && nx <= wx + ww
-			        && ny >= wy && ny <= wy + wh) {
-				if(abs(wx - nx) < snap)
-					nx = wx;
-				else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < snap)
-					nx = wx + ww - NOBORDER(c->w);
-				if(abs(wy - ny) < snap)
-					ny = wy;
-				else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < snap)
-					ny = wy + wh - NOBORDER(c->h);
-				if(!c->isfloating && lt[sellt]->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
-					togglefloating(NULL);
+ 			if(lt[sellt]->arrange && !c->isfloating) {
+ 				/* move within tesselation */
+ 				nx = ev.xmotion.x;
+ 				ny = ev.xmotion.y;
+ 				c2 = getclientunderpt(nx, ny);
+ 				if(c2 && c!=c2) {
+ 					swap(c, c2);
+ 					arrange();
+ 				}
+ 			} else {
+ 				/* move floating window */
+				nx = ocx + (ev.xmotion.x - x);
+				ny = ocy + (ev.xmotion.y - y);
+				if(snap && nx >= wx && nx <= wx + ww
+						&& ny >= wy && ny <= wy + wh) {
+					if(abs(wx - nx) < snap)
+						nx = wx;
+					else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < snap)
+						nx = wx + ww - NOBORDER(c->w);
+					if(abs(wy - ny) < snap)
+						ny = wy;
+					else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < snap)
+						ny = wy + wh - NOBORDER(c->h);
+				}
+				resize(c, nx, ny, c->w, c->h, False);
 			}
-			if(!lt[sellt]->arrange || c->isfloating)
-				resize(c, nx, ny, c->w, c->h, False);
 			break;
 		}
 	}
@@ -1403,6 +1424,19 @@
 }
 
 void
+swap(Client *c1, Client *c2) {
+	Client *tmp;
+	Client **tc1 = 0, **tc2 = 0, **ttmp;
+
+	for(ttmp = &clients; *ttmp; ttmp = &(*ttmp)->next) {
+		if (*ttmp == c1) tc1 = ttmp;
+		if (*ttmp == c2) tc2 = ttmp;
+	}
+	*tc1 = c2; *tc2 = c1;
+	tmp = c2->next; c2->next = c1->next; c1->next = tmp;
+}
+
+void
 tag(const Arg *arg) {
 	if(sel && arg->ui & TAGMASK) {
 		sel->tags = arg->ui & TAGMASK;
