]> git.armaanb.net Git - dwm.git/blobdiff - dwm.c
Apply zoomswap patch
[dwm.git] / dwm.c
diff --git a/dwm.c b/dwm.c
index 2202d3b90be4c9ec6eadc722152eb7af1e172972..f2ab57c130000c0bb1f59135b879678fa840dd55 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -167,6 +167,7 @@ static void drawbar(Monitor *m);
 static void drawbars(void);
 static void enternotify(XEvent *e);
 static void expose(XEvent *e);
+static Client *findbefore(Client *c);
 static void focus(Client *c);
 static void focusin(XEvent *e);
 static void focusmon(const Arg *arg);
@@ -187,8 +188,10 @@ static void monocle(Monitor *m);
 static void motionnotify(XEvent *e);
 static void movemouse(const Arg *arg);
 static Client *nexttiled(Client *c);
-static void pop(Client *);
+static Client *prevtiled(Client *c);
 static void propertynotify(XEvent *e);
+static void pushdown(const Arg *arg);
+static void pushup(const Arg *arg);
 static void quit(const Arg *arg);
 static Monitor *recttomon(int x, int y, int w, int h);
 static void resize(Client *c, int x, int y, int w, int h, int interact);
@@ -238,6 +241,7 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
 static void zoom(const Arg *arg);
 
 /* variables */
+static Client *prevzoom = NULL;
 static const char broken[] = "broken";
 static char stext[256];
 static int screen;
@@ -788,6 +792,16 @@ expose(XEvent *e)
                drawbar(m);
 }
 
+Client *
+findbefore(Client *c)
+{
+       Client *tmp;
+       if (c == selmon->clients)
+               return NULL;
+       for (tmp = selmon->clients; tmp && tmp->next != c; tmp = tmp->next);
+       return tmp;
+}
+
 void
 focus(Client *c)
 {
@@ -1205,13 +1219,14 @@ nexttiled(Client *c)
        return c;
 }
 
-void
-pop(Client *c)
-{
-       detach(c);
-       attach(c);
-       focus(c);
-       arrange(c->mon);
+Client *
+prevtiled(Client *c) {
+       Client *p, *r;
+
+       for(p = selmon->clients, r = NULL; p && p != c; p = p->next)
+               if(!p->isfloating && ISVISIBLE(p))
+                       r = p;
+       return r;
 }
 
 void
@@ -1251,6 +1266,49 @@ propertynotify(XEvent *e)
        }
 }
 
+void
+pushdown(const Arg *arg) {
+       Client *sel = selmon->sel, *c;
+
+       if(!sel || sel->isfloating)
+               return;
+       if((c = nexttiled(sel->next))) {
+               detach(sel);
+               sel->next = c->next;
+               c->next = sel;
+       } else {
+               detach(sel);
+               attach(sel);
+       }
+       focus(sel);
+       arrange(selmon);
+}
+
+void
+pushup(const Arg *arg) {
+       Client *sel = selmon->sel, *c;
+
+       if(!sel || sel->isfloating)
+               return;
+       if((c = prevtiled(sel))) {
+               detach(sel);
+               sel->next = c;
+               if(selmon->clients == c)
+                       selmon->clients = sel;
+               else {
+                       for(c = selmon->clients; c->next != sel->next; c = c->next);
+                       c->next = sel;
+               }
+       } else {
+               for(c = sel; c->next; c = c->next);
+               detach(sel);
+               sel->next = NULL;
+               c->next = sel;
+       }
+       focus(sel);
+       arrange(selmon);
+}
+
 void
 quit(const Arg *arg)
 {
@@ -2105,14 +2163,38 @@ void
 zoom(const Arg *arg)
 {
        Client *c = selmon->sel;
+       Client *at = NULL, *cold, *cprevious = NULL;
 
        if (!selmon->lt[selmon->sellt]->arrange
        || (selmon->sel && selmon->sel->isfloating))
                return;
-       if (c == nexttiled(selmon->clients))
-               if (!c || !(c = nexttiled(c->next)))
-                       return;
-       pop(c);
+       if (c == nexttiled(selmon->clients)) {
+               at = findbefore(prevzoom);
+               if (at)
+                       cprevious = nexttiled(at->next);
+               if (!cprevious || cprevious != prevzoom) {
+                       prevzoom = NULL;
+                       if (!c || !(c = nexttiled(c->next)))
+                               return;
+               } else
+                       c = cprevious;
+       }
+       cold = nexttiled(selmon->clients);
+       if (c != cold && !at)
+               at = findbefore(c);
+       detach(c);
+       attach(c);
+       /* swap windows instead of pushing the previous one down */
+       if (c != cold && at) {
+               prevzoom = cold;
+               if (cold && at != cold) {
+                       detach(cold);
+                       cold->next = at->next;
+                       at->next = cold;
+               }
+       }
+       focus(c);
+       arrange(c->mon);
 }
 
 int