]> git.mdlowis.com Git - proto/anvil.git/commitdiff
added logic to resize windows within a column
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 20 Mar 2020 16:28:51 +0000 (12:28 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 20 Mar 2020 16:28:51 +0000 (12:28 -0400)
anvil.c
anvil.h
build.sh
client.c
mouse.c
tile.c
util.c

diff --git a/anvil.c b/anvil.c
index 95feb8e74d482b0b07515417392f446e5591611a..a6bf1fc7a4d6a01f9a9f6be0526de3ff4455f1d3 100644 (file)
--- a/anvil.c
+++ b/anvil.c
@@ -14,19 +14,25 @@ static void check_for_wm(void)
 static void xbtnpress(XEvent* e)
 {
     XButtonEvent* ev = &(e->xbutton);
-    X.start_x = ev->x_root;
-    X.start_y = ev->y_root;
+    X.start_x = ev->x_root, X.start_y = ev->y_root;
+    X.last_x  = ev->x_root, X.last_y  = ev->y_root;
     Location loc;
     Client* c = client_get(e->xbutton.window, &loc);
     if (c && (ev->window == c->frame))
     {
-        mouse_click(ev, &loc);
+        mouse_down(ev, &loc);
     }
 }
 
 static void xbtnrelease(XEvent* e)
 {
-    (void)e;
+    XButtonEvent* ev = &(e->xbutton);
+    Location loc;
+    Client* c = client_get(e->xbutton.window, &loc);
+    if (c && (ev->window == c->frame))
+    {
+        mouse_up(ev, &loc);
+    }
     X.mode = M_IDLE;
 }
 
@@ -41,8 +47,7 @@ static void xbtnmotion(XEvent* e)
     {
         mouse_drag(ev, &loc);
     }
-    X.start_x = ev->x_root;
-    X.start_y = ev->y_root;
+    X.last_x = ev->x_root, X.last_y  = ev->y_root;
 }
 
 static void xconfigrequest(XEvent* e)
diff --git a/anvil.h b/anvil.h
index 2d5471a647384fcfe3c34903c4dc4dbd8cc21066..4ede3efa46ec41690774a1a045fc18a0a372bcaf 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -28,7 +28,7 @@ enum {
 
 typedef struct {
     Display* disp;
-    int screen, mode, start_x, start_y;
+    int screen, mode, start_x, start_y, last_x, last_y;
     Window root;
     unsigned long black, white, gray;
     Cursor csr_root, csr_point;
@@ -130,9 +130,11 @@ void client_focus(Client* c);
 void client_show(Client* c, int show);
 void client_readprops(Client* c);
 void client_shade(Client* c);
+void client_setshade(Client* c, int shade);
 
 /* mouse.c */
-void mouse_click(XButtonEvent* ev, Location* loc);
+void mouse_down(XButtonEvent* ev, Location* loc);
+void mouse_up(XButtonEvent* ev, Location* loc);
 void mouse_drag(XMotionEvent* ev, Location* loc);
 
 /* tile.c */
@@ -142,6 +144,7 @@ void monocled_set(Monitor* mon, Column* col, Client* c);
 void stacked_add(Monitor* mon, Column* col, Client* c);
 void stacked_del(Monitor* mon, Column* col, Client* c);
 void stacked_set(Monitor* mon, Column* col, Client* c);
+void stacked_addheight(Monitor* mon, Column* col, Client* c, int amount);
 
 /* error.c */
 extern int (*error_default)(Display* disp, XErrorEvent* ev);
index fcdf532889bd8573a756f7a17a0b3f930ff0c395..6270dd1f730bba50c1f1ceadf130c5a303e17492 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -1,4 +1,6 @@
 #!/bin/sh
 cc -g -Wall -Wextra -Werror -I/usr/X11R6/include -L/usr/X11R6/lib -o anvil *.c -lX11 -lXinerama -lm
+error="$?"
 ctags *
 grep -n 'TODO' *.c | sed -e 's/: \+/: /' -e 's/\/\* *//g' -e 's/ *\*\/$//' -e 's/TODO: *//'
+exit "$error"
index 5d1d93ba2265a07bbbe24355574e903c8de32115..79c1dfd356e645a37d5872c251cde8dc952ddd8a 100644 (file)
--- a/client.c
+++ b/client.c
@@ -42,8 +42,7 @@ Client* client_add(Window win, XWindowAttributes* attr)
     wa.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
     XChangeWindowAttributes(X.disp, c->win, CWEventMask | CWDontPropagate, &wa);
     XReparentWindow(X.disp, c->win, c->frame,
-        BORDER_WIDTH, BORDER_WIDTH + TITLE_HEIGHT
-    );
+        BORDER_WIDTH, BORDER_WIDTH + TITLE_HEIGHT);
 
     /* Map the window and draw the frame */
     XAddToSaveSet(X.disp, c->win);
@@ -106,8 +105,8 @@ void client_resize(Client* c, int xdiff, int ydiff)
 {
     c->w += xdiff;
     c->h += ydiff;
-    if (c->w < 50) c->w = 50;
-    if (c->h < 50) c->h = 50;
+    if (c->w < TITLE_HEIGHT+BORDER_WIDTH) c->w = TITLE_HEIGHT+BORDER_WIDTH;
+    if (c->h < TITLE_HEIGHT+BORDER_WIDTH) c->h = TITLE_HEIGHT+BORDER_WIDTH;
     if (c->flags & F_SHADED)
     {
         XResizeWindow(X.disp, c->frame, c->w, TITLE_HEIGHT+BORDER_WIDTH);
@@ -192,14 +191,26 @@ void client_readprops(Client* c)
 void client_shade(Client* c)
 {
     if (c->flags & F_SHADED)
+    {
+        client_setshade(c, 0);
+    }
+    else
+    {
+        client_setshade(c, 1);
+    }
+    client_adjust(c);
+}
+
+void client_setshade(Client* c, int shade)
+{
+    if (!shade && (c->flags & F_SHADED))
     {
         c->flags &= ~F_SHADED;
         XMapWindow(X.disp, c->win);
     }
-    else
+    else if (shade && !(c->flags & F_SHADED))
     {
         c->flags |= F_SHADED;
         XUnmapWindow(X.disp, c->win);
     }
-    client_adjust(c);
 }
diff --git a/mouse.c b/mouse.c
index 8773d1dd18cea5c7c29405f4a8f36cfdcbff9ffb..a1dd7abcb752e67b570580025ea4231805d6a3f7 100644 (file)
--- a/mouse.c
+++ b/mouse.c
@@ -60,7 +60,6 @@ static void monocled_click(XButtonEvent* ev, Location* loc)
 
 static void stacked_click(XButtonEvent* ev, Location* loc)
 {
-    /* TODO: handle button 1 drag to resize, reposition, and move windows */
     if (ev->button == Button2)
     {
         client_close(loc->client);
@@ -71,7 +70,7 @@ static void stacked_click(XButtonEvent* ev, Location* loc)
     }
 }
 
-void mouse_click(XButtonEvent* ev, Location* loc)
+void mouse_down(XButtonEvent* ev, Location* loc)
 {
     if (!loc->column)
     {
@@ -93,16 +92,27 @@ static void float_drag(XMotionEvent* ev, Location* loc)
     {
         if (X.mode != M_RESIZE)
         {
-            client_move(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+            client_move(loc->client, ev->x_root - X.last_x, ev->y_root - X.last_y);
         }
         else
         {
-            client_resize(loc->client, ev->x_root - X.start_x, ev->y_root - X.start_y);
+            client_resize(loc->client, ev->x_root - X.last_x, ev->y_root - X.last_y);
         }
         XSync(X.disp, False);
     }
 }
 
+void mouse_up(XButtonEvent* ev, Location* loc)
+{
+    (void)ev, (void)loc;
+    /* TODO: handle button 1 drag to resize, reposition, and move windows */
+    /* TODO: check if we clicked in frame originally or if we clicked in titlebar */
+    if (!loc->column->focused)
+    {
+        stacked_addheight(loc->monitor, loc->column, loc->client, ev->y_root - X.start_y);
+    }
+}
+
 static void monocled_drag(XMotionEvent* ev, Location* loc)
 {
     (void)ev, (void)loc;
diff --git a/tile.c b/tile.c
index 1432c0fd3bc71de9fe7f4a94255c9aab21af3cc3..3abf7f1592ef47ebd6e2de2f18fcceaa39068d07 100644 (file)
--- a/tile.c
+++ b/tile.c
@@ -95,5 +95,29 @@ void stacked_set(Monitor* mon, Column* col, Client* c)
     /* TODO: implement switch back to stacked mode */
 }
 
-
-
+void stacked_addheight(Monitor* mon, Column* col, Client* c, int amount)
+{
+    Client* prev = col->clients;
+    for (; prev && prev->next != c; prev = prev->next);
+    if (prev)
+    {
+        amount = (amount == 0 ? (int)(-c->h * 0.25) : amount);
+        int miny = (prev->y + TITLE_HEIGHT+BORDER_WIDTH);
+        int maxy = min((mon->y + mon->h) , (c->y + c->h)) - TITLE_HEIGHT+BORDER_WIDTH;
+        if (amount < 0)
+        {
+            c->y = max(miny, c->y + amount);
+            prev->h = c->y - prev->y;
+        }
+        else if (amount > 0)
+        {
+            c->y = min(maxy, c->y + amount);
+            prev->h = c->y - prev->y;
+        }
+        c->h = (c->next ? c->next->y : mon->y + mon->h) - c->y;
+        client_setshade(prev, (prev->h <= TITLE_HEIGHT+BORDER_WIDTH));
+        client_setshade(c, (c->h <= TITLE_HEIGHT+BORDER_WIDTH));
+        client_adjust(prev);
+        client_adjust(c);
+    }
+}
diff --git a/util.c b/util.c
index 4c8efd893fc6c30dc1d412753ab510c82c278fca..a8c559923d386bc1f46ff04a44b17fb2079df7b0 100644 (file)
--- a/util.c
+++ b/util.c
@@ -56,8 +56,8 @@ 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;
+    X.last_x = c->x + new_w;
+    X.last_y = c->y + new_h;
 }
 
 Client* delclient(Client* list, Client* dead)