]> git.mdlowis.com Git - proto/anvil.git/commitdiff
added tiling logic for stacked and monocle modes
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 18 Mar 2020 02:21:46 +0000 (22:21 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 18 Mar 2020 02:21:46 +0000 (22:21 -0400)
anvil.c
anvil.h
client.c
mons.c
mouse.c [new file with mode: 0644]
util.c

diff --git a/anvil.c b/anvil.c
index 8aed3ee5b49122e3d2ebb32cae7eff966232b412..bd74e7ae8bc3e2945f879b99964713f3927b63dd 100644 (file)
--- a/anvil.c
+++ b/anvil.c
@@ -11,21 +11,6 @@ static void check_for_wm(void)
     XSync(X.disp, False);
 }
 
-static inline int PRESSED(int mods, int btn)
-{
-    return ((mods & (1 << (btn + 7))) == (1 << (btn + 7)));
-}
-
-static void warp_mouse(Client* c)
-{
-    XWarpPointer(X.disp, None, c->frame, 0, 0, 0, 0,
-        c->w + 2*BORDER_WIDTH - BORDER_WIDTH/2,
-        c->h + 2*BORDER_WIDTH + TITLE_HEIGHT - BORDER_WIDTH/2
-    );
-    X.start_x = c->x + c->w + 4;
-    X.start_y = c->y + c->h + 4;
-}
-
 static void xbtnpress(XEvent* e)
 {
     XButtonEvent* ev = &(e->xbutton);
@@ -35,31 +20,7 @@ static void xbtnpress(XEvent* e)
     Client* c = client_get(e->xbutton.window, &loc);
     if (c && (ev->window == c->frame))
     {
-        if (loc.column)
-        {
-            puts("tiled mouse click");
-        }
-        else
-        {
-//            client_btnclick(c, ev->button, ev->x, ev->y);
-            if (ev->button == Button1)
-            {
-                mons_raise(loc.monitor, c);
-                if (ev->y > (TITLE_HEIGHT + BORDER_WIDTH))
-                {
-                    X.mode = M_RESIZE;
-                    warp_mouse(c);
-                }
-            }
-            else if (ev->button == Button2)
-            {
-                client_close(c);
-            }
-            else if (ev->button == Button3)
-            {
-                mons_lower(loc.monitor, c);
-            }
-        }
+        mouse_click(ev, &loc);
     }
 }
 
@@ -78,26 +39,7 @@ static void xbtnmotion(XEvent* e)
     Client* c = client_get(ev->window, &loc);
     if (c && (ev->window == c->frame))
     {
-        if (loc.column)
-        {
-            puts("tiled mouse drag");
-        }
-        else
-        {
-//            client_btnmove(c, ev->button, ev->x, ev->y);
-            if (PRESSED(ev->state, Button1))
-            {
-                if (X.mode != M_RESIZE)
-                {
-                    client_move(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
-                }
-                else
-                {
-                    client_resize(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
-                }
-                XSync(X.disp, False);
-            }
-        }
+        mouse_drag(ev, &loc);
     }
     X.start_x = ev->x_root;
     X.start_y = ev->y_root;
diff --git a/anvil.h b/anvil.h
index 89a05f237fc2db4c3f5f9f900effef96880cfaaf..5ed948d3edc1cec3b84b10da6c3c764037024c0a 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -145,6 +145,10 @@ void client_focus(Client* c);
 void client_show(Client* c, int show);
 void client_readprops(Client* c);
 
+/* mouse.c */
+void mouse_click(XButtonEvent* ev, Location* loc);
+void mouse_drag(XMotionEvent* ev, Location* loc);
+
 /* error.c */
 extern int (*error_default)(Display* disp, XErrorEvent* ev);
 int error_init(Display* disp, XErrorEvent* ev);
@@ -157,3 +161,4 @@ void* ecalloc(size_t n, size_t sz);
 void xfree(void* p);
 Atom atom(char* str);
 void sendmsg(Window win, Atom proto, Atom type);
+void warp_mouse(Client* c);
index 83c02af2d7a9898e2772667c7741d2493dcd7f40..0d78e9f2312498a4d1e34a60833d9181dd055ef2 100644 (file)
--- a/client.c
+++ b/client.c
@@ -31,7 +31,7 @@ Client* client_add(Window win, XWindowAttributes* attr)
     client_readprops(c);
 
     /* Reparent the window if applicable */
-    c->frame = XCreateSimpleWindow(X.disp, X.root, c->x, c->y, c->w, c->h, 1, X.black, X.gray);
+    c->frame = XCreateSimpleWindow(X.disp, X.root, c->x, c->y, c->w, c->h, 1, X.black, X.black);
     XSelectInput(X.disp, c->frame,
         ExposureMask | EnterWindowMask |
         ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
diff --git a/mons.c b/mons.c
index ec722bef21d2bc5281e22bbc0bd6b9b511edc7ab..ce63915eb0f8efe017cb42f3e5d99fcaf227e240 100644 (file)
--- a/mons.c
+++ b/mons.c
@@ -29,7 +29,7 @@ void mons_init(void)
         for (int i = 0; i < 10; i++)
         {
             Column* col = ecalloc(1, sizeof(Column));
-            col->mode = TILE_MONOCLE,
+            col->mode = TILE_STACKED,
             col->width = m->w;
             Workspace* wspace = ecalloc(1, sizeof(Workspace));
             wspace->columns = col;
@@ -69,7 +69,7 @@ void mons_layer(Monitor* mon)
     }
 }
 
-static void tile_monocle(Monitor* mon, Column* col, Client* c)
+static void add_monocle(Monitor* mon, Column* col, Client* c)
 {
     coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
     client_adjust(c);
@@ -77,7 +77,7 @@ static void tile_monocle(Monitor* mon, Column* col, Client* c)
     col->clients = c;
 }
 
-static void tile_expand(Monitor* mon, Column* col, Client* client)
+static void add_expand(Monitor* mon, Column* col, Client* client)
 {
     /*
         * stack all existing clients top to bottom only showing title bars
@@ -88,16 +88,33 @@ static void tile_expand(Monitor* mon, Column* col, Client* client)
     col->clients = client;
 }
 
-static void tile_stacked(Monitor* mon, Column* col, Client* client)
+static void add_stacked(Monitor* mon, Column* col, Client* client)
 {
-    /*
-        * find biggest client in stack
-        * split that client in half
-        * move+resize new client to fill the gap
-    */
-    (void)mon, (void)col;
-    client->next = col->clients;
-    col->clients = client;
+    coldims(mon, col, &(client->x), &(client->y), &(client->w), &(client->h));
+    if (col->clients)
+    {
+        Client* max = col->clients;
+        for (Client* c = max; c; c = c->next)
+        {
+            if (c->h > max->h)
+            {
+                max = c;
+            }
+        }
+        client->h = max->h/2;
+        client->y = max->y + client->h;
+        max->h -= max->h/2;
+        client->next = max->next;
+        max->next = client;
+        client_adjust(max);
+        client_adjust(client);
+    }
+    else
+    {
+        client->next = col->clients;
+        col->clients = client;
+        client_adjust(client);
+    }
 }
 
 /* adds a new client to the most appropriate monitor */
@@ -120,15 +137,15 @@ void mons_addclient(Client* c)
         Column* col = pickcol(mon->cspace->columns, ptrx - mon->x);
         if (col->mode == TILE_MONOCLE)
         {
-            tile_monocle(mon, col, c);
+            add_monocle(mon, col, c);
         }
         else if (col->mode == TILE_EXPAND)
         {
-            tile_expand(mon, col, c);
+            add_expand(mon, col, c);
         }
         else if (col->mode == TILE_STACKED)
         {
-            tile_stacked(mon, col, c);
+            add_stacked(mon, col, c);
         }
     }
     mons_layer(mon);
diff --git a/mouse.c b/mouse.c
new file mode 100644 (file)
index 0000000..d44c814
--- /dev/null
+++ b/mouse.c
@@ -0,0 +1,96 @@
+#include "anvil.h"
+
+static inline int PRESSED(int mods, int btn)
+{
+    return ((mods & (1 << (btn + 7))) == (1 << (btn + 7)));
+}
+
+static void float_click(XButtonEvent* ev, Location* loc)
+{
+    if (ev->button == Button1)
+    {
+        mons_raise(loc->monitor, loc->client);
+        if (ev->y > (TITLE_HEIGHT + BORDER_WIDTH))
+        {
+            X.mode = M_RESIZE;
+            warp_mouse(loc->client);
+        }
+    }
+    else if (ev->button == Button2)
+    {
+        client_close(loc->client);
+    }
+    else if (ev->button == Button3)
+    {
+        mons_lower(loc->monitor, loc->client);
+    }
+}
+
+static void monocle_click(XButtonEvent* ev, Location* loc)
+{
+    if (ev->button == Button2)
+    {
+        client_close(loc->client);
+    }
+    else if (ev->button == Button3)
+    {
+        Client *tail, *client = loc->column->clients;
+        if (client->next)
+        {
+            loc->column->clients = client->next;
+            for (tail = loc->column->clients; tail && tail->next; tail = tail->next);
+            client->next = NULL;
+            tail->next = client;
+        }
+    }
+    mons_layer(loc->monitor);
+}
+
+void mouse_click(XButtonEvent* ev, Location* loc)
+{
+    if (!loc->column)
+    {
+        float_click(ev, loc);
+    }
+    else if (loc->column->mode == TILE_MONOCLE)
+    {
+        monocle_click(ev, loc);
+    }
+    else if (loc->column->mode == TILE_STACKED)
+    {
+        puts("tiled (S) mouse click");
+    }
+    else if (loc->column->mode == TILE_EXPAND)
+    {
+        puts("tiled (E) mouse click");
+    }
+}
+
+static void float_drag(XMotionEvent* ev, Location* loc)
+{
+    if (PRESSED(ev->state, Button1))
+    {
+        if (X.mode != M_RESIZE)
+        {
+            client_move(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+        }
+        else
+        {
+            client_resize(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+        }
+        XSync(X.disp, False);
+    }
+}
+
+void mouse_drag(XMotionEvent* ev, Location* loc)
+{
+    if (!loc->column)
+    {
+        float_drag(ev, loc);
+    }
+    else
+    {
+        puts("tiled mouse drag");
+    }
+}
+
diff --git a/util.c b/util.c
index d442726a681d7a88a277de4b12cb61abd552134f..d96af32330edd1d52da3077766e377d1578b9d15 100644 (file)
--- a/util.c
+++ b/util.c
@@ -51,3 +51,12 @@ void sendmsg(Window win, Atom proto, Atom type)
     XSync(X.disp, False);
 }
 
+void warp_mouse(Client* c)
+{
+    int new_w = c->w - BORDER_WIDTH/2;
+    int new_h = c->h - BORDER_WIDTH/2;
+    XWarpPointer(X.disp, None, c->frame, 0, 0, 0, 0, new_w, new_h);
+    X.start_x = c->x + new_w;
+    X.start_y = c->y + new_h;
+}
+