]> git.mdlowis.com Git - proto/anvil.git/commitdiff
added logic to resize columns
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 22 Mar 2020 02:15:11 +0000 (22:15 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 22 Mar 2020 02:15:11 +0000 (22:15 -0400)
anvil.h
build.sh
keys.c
mons.c
mouse.c
util.c

diff --git a/anvil.h b/anvil.h
index a4719d2fa223706c6a3140fb25a1f69625a5dcb4..e1b6547805348d5c37f1b24b11926541b3c52866 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -25,7 +25,8 @@ enum {
     M_IDLE,
     M_RESIZE,
     M_TILE_RESIZE,
-    M_COL_RESIZE
+    M_COL_RIGHT_RESIZE,
+    M_COL_LEFT_RESIZE
 };
 
 typedef struct {
@@ -94,10 +95,11 @@ typedef struct {
     Arg arg;
 } Key;
 
-#define BORDER_WIDTH 5
-#define TITLE_HEIGHT (X.font_ext->max_logical_extent.height)
-#define MIN_HEIGHT   (TITLE_HEIGHT+BORDER_WIDTH)
-#define FONT_NAME    "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1"
+#define BORDER_WIDTH  5
+#define TITLE_HEIGHT  (X.font_ext->max_logical_extent.height)
+#define MIN_HEIGHT    (TITLE_HEIGHT+BORDER_WIDTH)
+#define MIN_COL_WIDTH 100
+#define FONT_NAME     "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1"
 
 /* anvil.c */
 extern XConf X;
@@ -118,6 +120,9 @@ void mons_wspace(int i);
 void mons_towspace(Client* c, int i);
 void mons_raise(Monitor* mon, Client* c);
 void mons_lower(Monitor* mon, Client* c);
+void mons_colsplit(void);
+void mons_coljoin(void);
+void mons_coladjust(Monitor* mon, Column* col, int leftedge, int wdiff);
 
 /* client.c */
 extern Client* Focused;
@@ -163,3 +168,4 @@ Atom atom(char* str);
 void sendmsg(Window win, Atom proto, Atom type);
 void warp_mouse(Client* c);
 Client* delclient(Client* list, Client* dead);
+void get_mouse(int* ptrx, int* ptry);
index 6270dd1f730bba50c1f1ceadf130c5a303e17492..ca67477580d11d8f2b7bfb4e91ded4f367b7f29a 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -3,4 +3,8 @@ cc -g -Wall -Wextra -Werror -I/usr/X11R6/include -L/usr/X11R6/lib -o anvil *.c -
 error="$?"
 ctags *
 grep -n 'TODO' *.c | sed -e 's/: \+/: /' -e 's/\/\* *//g' -e 's/ *\*\/$//' -e 's/TODO: *//'
+printf "\a"
+if [ $error -ne 0 ]; then
+    printf "\a"
+fi
 exit "$error"
diff --git a/keys.c b/keys.c
index 887208c01d2239e3d7dc3fd7f90c2626db369098..c9668fcfb2f763fe32f5f34181b18a166611be02 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -35,6 +35,18 @@ static void killwin(Arg *arg)
     client_close(Focused);
 }
 
+static void coljoin(Arg *arg)
+{
+    (void)arg;
+    mons_coljoin();
+}
+
+static void colsplit(Arg *arg)
+{
+    (void)arg;
+    mons_colsplit();
+}
+
 #ifdef __APPLE__
 #define MODKEY Mod1Mask
 #else
@@ -54,6 +66,8 @@ static Key keys[] = {
     { MODKEY|ShiftMask, XK_Return, runcmd,  { .cmd = terminal } },
     { MODKEY|ShiftMask, XK_l,      runcmd,  { .cmd = locker   } },
     { MODKEY|ShiftMask, XK_c,      killwin, { 0 } },
+    { MODKEY,           XK_minus,  coljoin,  { 0 } },
+    { MODKEY,           XK_equal,  colsplit, { 0 } },
 
     { MODKEY,   XK_1,   set_workspace,  { .i = 0 } },
     { MODKEY,   XK_2,   set_workspace,  { .i = 1 } },
diff --git a/mons.c b/mons.c
index 08fdacd955cb00971f657b5d7566a2d06caf4b63..0f66a50a822c8900b2083f6ef5908b68d0c9cbe2 100644 (file)
--- a/mons.c
+++ b/mons.c
@@ -1,13 +1,15 @@
 #include "anvil.h"
 #include <math.h>
 
-static Monitor* pickmon(int ptrx, int ptry);
+int PtrX = 0, PtrY = 0;
+static Monitor* pickmon(void);
 static Column* pickcol(Column* cols, int relx);
 static Workspace* pickws(Monitor* mon, int wsid);
 static void client_visibility(Workspace* wspace, int show);
 static Client* client_find(Client* clients, Window win);
 static void add_client(Monitor* mon, Client* c, int ptrx);
 static void remove_client(Location* loc, Client* c);
+static void adjust_all(Column* col, int xoff);
 
 Monitor* Monitors = NULL;
 
@@ -82,11 +84,8 @@ void mons_layer(Monitor* mon)
 /* adds a new client to the most appropriate monitor */
 void mons_addclient(Client* c)
 {
-    Window root = 0, child = 0;
-    int ptrx = 0, ptry = 0, winx = 0, winy = 0, mask = 0;
-    XQueryPointer(X.disp, X.root, &root, &child, &ptrx, &ptry, &winx, &winy, (unsigned int*)&mask);
-    Monitor* mon = pickmon(ptrx, ptry);
-    add_client(mon, c, ptrx);
+    Monitor* mon = pickmon();
+    add_client(mon, c, PtrX);
 }
 
 void mons_delclient(Client* c)
@@ -173,10 +172,7 @@ void mons_place(Client* c)
 
 void mons_wspace(int wsid)
 {
-    Window root = 0, child = 0;
-    int ptrx = 0, ptry = 0, winx = 0, winy = 0, mask = 0;
-    XQueryPointer(X.disp, X.root, &root, &child, &ptrx, &ptry, &winx, &winy, (unsigned int*)&mask);
-    Monitor* mon = pickmon(ptrx, ptry);
+    Monitor* mon = pickmon();
     Workspace* wspace = pickws(mon, wsid);
     if (mon->cspace != wspace)
     {
@@ -191,9 +187,7 @@ void mons_towspace(Client* c, int wsid)
     Location loc = {0};
     if (mons_find(c->win, &loc))
     {
-        Window root = 0, child = 0;
-        int ptrx = 0, ptry = 0, winx = 0, winy = 0, mask = 0;
-        XQueryPointer(X.disp, X.root, &root, &child, &ptrx, &ptry, &winx, &winy, (unsigned int*)&mask);
+        get_mouse(&PtrX, &PtrY);
         Workspace* wspace = pickws(loc.monitor, wsid);
         if (wspace != loc.workspace)
         {
@@ -201,7 +195,7 @@ void mons_towspace(Client* c, int wsid)
             client_show(c, 0);
             Workspace* prev = loc.monitor->cspace;
             loc.monitor->cspace = wspace;
-            add_client(loc.monitor, c, ptrx);
+            add_client(loc.monitor, c, PtrX);
             loc.monitor->cspace = prev;
         }
     }
@@ -232,12 +226,76 @@ void mons_lower(Monitor* mon, Client* c)
     mons_layer(mon);
 }
 
-static Monitor* pickmon(int ptrx, int ptry)
+void mons_colsplit(void)
 {
+    Monitor* mon = pickmon();
+    Column* col = pickcol(mon->cspace->columns, PtrX);
+    if (col->clients && col->width >= 2*MIN_COL_WIDTH)
+    {
+        Column* newcol = ecalloc(1, sizeof(Column));
+        newcol->width = col->width/2;
+        col->width -= newcol->width;
+        newcol->next = col->next;
+        col->next = newcol;
+        adjust_all(col, 0);
+    }
+}
+
+void mons_coljoin(void)
+{
+    Monitor* mon = pickmon();
+    Column* col = pickcol(mon->cspace->columns, PtrX);
+    if (col->next)
+    {
+        /* add the clients to the current col */
+        for (Client* c = col->next->clients; c;)
+        {
+            Client* next = c->next;
+            if (col->focused)
+            {
+                monocled_add(mon, col, c);
+            }
+            else
+            {
+                stacked_add(mon, col, c);
+            }
+            c = next;
+        }
+        Column* dead = col->next;
+        col->next = dead->next;
+        col->width += dead->width;
+        free(dead);
+        adjust_all(col, 0);
+    }
+}
+
+void mons_coladjust(Monitor* mon, Column* col, int leftedge, int wdiff)
+{
+    Column* neighbor = col->next;
+    if (leftedge)
+    {
+        for (neighbor = mon->cspace->columns; neighbor && neighbor->next != col; neighbor = neighbor->next);
+        neighbor->width += wdiff;
+        col->width -= wdiff;
+        adjust_all(col, wdiff);
+        adjust_all(neighbor, 0);
+    }
+    else
+    {
+        col->width += wdiff;
+        neighbor->width -= wdiff;
+        adjust_all(col, 0);
+        adjust_all(neighbor, wdiff);
+    }
+}
+
+static Monitor* pickmon(void)
+{
+    get_mouse(&PtrX, &PtrY);
     Monitor* mon = Monitors;
     for (; mon; mon = mon->next)
     {
-        if ((mon->x <= ptrx && ptrx < mon->x+mon->w) && (mon->y <= ptry && ptry < mon->y+mon->h))
+        if ((mon->x <= PtrX && PtrX < mon->x+mon->w) && (mon->y <= PtrY && PtrY < mon->y+mon->h))
         {
             break;
         }
@@ -353,3 +411,12 @@ static void remove_client(Location* loc, Client* c)
     }
 }
 
+static void adjust_all(Column* col, int xoff)
+{
+    for (Client* c = col->clients; c; c = c->next)
+    {
+        c->x += xoff;
+        c->w = col->width;
+        client_adjust(c);
+    }
+}
diff --git a/mouse.c b/mouse.c
index b02a2c55967099d4f318cfaf565244fcc34e732a..0a4ab12e17475f1c57dd70fcce8190169ee50f0a 100644 (file)
--- a/mouse.c
+++ b/mouse.c
@@ -62,7 +62,7 @@ static void stacked_click(XButtonEvent* ev, Location* loc)
 {
     if (ev->button == Button1)
     {
-        X.mode = (ev->y > MIN_HEIGHT ? M_COL_RESIZE : M_TILE_RESIZE);
+        X.mode = (ev->y > MIN_HEIGHT ?  (ev->x < BORDER_WIDTH ? M_COL_LEFT_RESIZE : M_COL_RIGHT_RESIZE) : M_TILE_RESIZE);
     }
     else if (ev->button == Button2)
     {
@@ -113,10 +113,9 @@ void mouse_up(XButtonEvent* ev, Location* loc)
     {
         stacked_addheight(loc->monitor, loc->column, loc->client, ev->y_root - X.start_y);
     }
-    else if (X.mode == M_COL_RESIZE)
+    else if (X.mode == M_COL_LEFT_RESIZE || X.mode == M_COL_RIGHT_RESIZE)
     {
-        puts("resize column");
-        /* TODO: resize column */
+        mons_coladjust(loc->monitor, loc->column, (X.mode == M_COL_LEFT_RESIZE), ev->x_root - X.start_x);
     }
     X.mode = M_IDLE;
 }
diff --git a/util.c b/util.c
index a8c559923d386bc1f46ff04a44b17fb2079df7b0..bfe134387b6a3fd451c4677d8879cb6d0e27ce40 100644 (file)
--- a/util.c
+++ b/util.c
@@ -77,3 +77,9 @@ Client* delclient(Client* list, Client* dead)
     }
 }
 
+void get_mouse(int* ptrx, int* ptry)
+{
+    Window root = 0, child = 0;
+    int winx = 0, winy = 0, mask = 0;
+    XQueryPointer(X.disp, X.root, &root, &child, ptrx, ptry, &winx, &winy, (unsigned int*)&mask);
+}