From fd9fd1eafb19965a36520ad670b91b0baa40796e Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 22 Mar 2020 23:13:36 -0400 Subject: [PATCH] added logic to resize columns with bounds checking. --- anvil.c | 20 ++++++++++++++++++++ anvil.h | 17 ++++++++++++----- keys.c | 7 +++++-- mons.c | 26 +++++++++++++++++++++----- mouse.c | 6 +++--- tile.c | 1 + 6 files changed, 62 insertions(+), 15 deletions(-) diff --git a/anvil.c b/anvil.c index a6bf1fc..e3c4575 100644 --- a/anvil.c +++ b/anvil.c @@ -20,6 +20,26 @@ static void xbtnpress(XEvent* e) Client* c = client_get(e->xbutton.window, &loc); if (c && (ev->window == c->frame)) { + if (ev->y < MIN_HEIGHT) + { + X.edge = E_TOP; + } + else if (ev->y_root > (c->y + c->h - BORDER_WIDTH)) + { + X.edge = E_BOTTOM; + } + else if (ev->x < BORDER_WIDTH) + { + X.edge = E_LEFT; + } + else if (ev->x_root > (c->x + c->w - BORDER_WIDTH)) + { + X.edge = E_RIGHT; + } + else + { + X.edge = E_NONE; + } mouse_down(ev, &loc); } } diff --git a/anvil.h b/anvil.h index e1b6547..dd22797 100644 --- a/anvil.h +++ b/anvil.h @@ -24,14 +24,21 @@ enum { M_INIT, M_IDLE, M_RESIZE, + M_COL_RESIZE, M_TILE_RESIZE, - M_COL_RIGHT_RESIZE, - M_COL_LEFT_RESIZE +}; + +enum { + E_NONE, + E_TOP, + E_RIGHT, + E_BOTTOM, + E_LEFT }; typedef struct { Display* disp; - int screen, mode, start_x, start_y, last_x, last_y; + int screen, mode, edge, start_x, start_y, last_x, last_y; Window root; unsigned long black, white, gray; Cursor csr_root, csr_point; @@ -98,7 +105,7 @@ typedef struct { #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 MIN_COL_FACT 0.20 #define FONT_NAME "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1" /* anvil.c */ @@ -122,7 +129,7 @@ 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); +void mons_coladjust(Monitor* mon, Column* col, int wdiff); /* client.c */ extern Client* Focused; diff --git a/keys.c b/keys.c index c9668fc..72bd1e8 100644 --- a/keys.c +++ b/keys.c @@ -32,7 +32,10 @@ static void runcmd(Arg *arg) static void killwin(Arg *arg) { (void)arg; - client_close(Focused); + if (Focused) + { + client_close(Focused); + } } static void coljoin(Arg *arg) @@ -57,7 +60,7 @@ static char* pickexec[] = { "pickexec", NULL }; static char* terminal[] = { "xterm", NULL }; static char* locker[] = { "slock", NULL }; -/* TODO: Add shortcuts to add/del columns and resize them */ +/* TODO: Add shortcuts to resize columns */ /* TODO: Add shortcuts to transfer windows between monitors */ /* TODO: Add shortcuts to toggle between tiled and floating */ static Key keys[] = { diff --git a/mons.c b/mons.c index 0f978d8..f51f626 100644 --- a/mons.c +++ b/mons.c @@ -13,6 +13,11 @@ static void adjust_all(Column* col, int xoff); Monitor* Monitors = NULL; +static int min_col_width(Monitor* mon) +{ + return (int)(mon->w * MIN_COL_FACT); +} + void mons_init(void) { int nmons; @@ -230,7 +235,8 @@ void mons_colsplit(void) { Monitor* mon = pickmon(); Column* col = pickcol(mon->cspace->columns, PtrX); - if (col->clients && col->width >= 2*MIN_COL_WIDTH) + int next_empty = (col->next && !col->next->clients); + if (col->clients && !next_empty && col->width >= 2*min_col_width(mon)) { Column* newcol = ecalloc(1, sizeof(Column)); newcol->width = col->width/2; @@ -269,25 +275,35 @@ void mons_coljoin(void) } } -void mons_coladjust(Monitor* mon, Column* col, int leftedge, int wdiff) +void mons_coladjust(Monitor* mon, Column* col, int wdiff) { - /* TODO: range limit the adjustment here to ensure minimum column size upheld */ Column* neighbor = col->next; - if (leftedge) + int minwidth = min_col_width(mon); + if (X.edge == E_LEFT && mon->cspace->columns != col) { for (neighbor = mon->cspace->columns; neighbor && neighbor->next != col; neighbor = neighbor->next); + int minadj = -(neighbor->width - minwidth); + int maxadj = (col->width - minwidth); + wdiff = min(max(minadj, wdiff), maxadj); neighbor->width += wdiff; col->width -= wdiff; adjust_all(col, wdiff); adjust_all(neighbor, 0); } - else + else if (X.edge == E_RIGHT && col->next) { + int minadj = -(col->width - minwidth); + int maxadj = (neighbor->width - minwidth); + wdiff = min(max(minadj, wdiff), maxadj); col->width += wdiff; neighbor->width -= wdiff; adjust_all(col, 0); adjust_all(neighbor, wdiff); } + else + { + /* invalid edge */ + } } static Monitor* pickmon(void) diff --git a/mouse.c b/mouse.c index 0a4ab12..37c6555 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 ? (ev->x < BORDER_WIDTH ? M_COL_LEFT_RESIZE : M_COL_RIGHT_RESIZE) : M_TILE_RESIZE); + X.mode = (X.edge == E_TOP ? M_TILE_RESIZE : M_COL_RESIZE); } else if (ev->button == Button2) { @@ -113,9 +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_LEFT_RESIZE || X.mode == M_COL_RIGHT_RESIZE) + else if (X.mode == M_COL_RESIZE) { - mons_coladjust(loc->monitor, loc->column, (X.mode == M_COL_LEFT_RESIZE), ev->x_root - X.start_x); + mons_coladjust(loc->monitor, loc->column, ev->x_root - X.start_x); } X.mode = M_IDLE; } diff --git a/tile.c b/tile.c index cc0c7ae..3bd1ad0 100644 --- a/tile.c +++ b/tile.c @@ -12,6 +12,7 @@ void monocled_add(Monitor* mon, Column* col, Client* c) client_adjust(c); c->next = col->clients; col->clients = c; + col->focused = c; } void monocled_del(Monitor* mon, Column* col, Client* c) -- 2.52.0