M_IDLE,
M_RESIZE,
M_TILE_RESIZE,
- M_COL_RESIZE
+ M_COL_RIGHT_RESIZE,
+ M_COL_LEFT_RESIZE
};
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;
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;
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);
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
{ 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 } },
#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;
/* 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)
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)
{
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)
{
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;
}
}
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;
}
}
}
+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);
+ }
+}