From: Michael D. Lowis Date: Sun, 22 Mar 2020 02:15:11 +0000 (-0400) Subject: added logic to resize columns X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=fa4a140e62d38aac5c11d8ce83916a65188534c5;p=proto%2Fanvil.git added logic to resize columns --- diff --git a/anvil.h b/anvil.h index a4719d2..e1b6547 100644 --- 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); diff --git a/build.sh b/build.sh index 6270dd1..ca67477 100755 --- 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 887208c..c9668fc 100644 --- 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 08fdacd..0f66a50 100644 --- a/mons.c +++ b/mons.c @@ -1,13 +1,15 @@ #include "anvil.h" #include -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 b02a2c5..0a4ab12 100644 --- 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 a8c5599..bfe1343 100644 --- 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); +}