#include "anvil.h"
#include <math.h>
-static Monitor* pickmon(void);
+static Monitor* pickmon(int ptrx, int ptry);
+static Column* pickcol(Column* cols, int relx);
static Workspace* pickws(Monitor* mon, int wsid);
static Client* delclient(Client* list, Client* dead);
static void client_visibility(Workspace* wspace, int show);
+static Client* client_find(Client* clients, Window win);
Monitor* Monitors = NULL;
for (int i = 0; i < nmons; i++)
{
Monitor* m = ecalloc(1, sizeof(Monitor));
- for (int i = 0; i < 10; i++)
- {
- Workspace* wspace = ecalloc(1, sizeof(Workspace));
- wspace->next = m->wspaces;
- m->wspaces = wspace;
- }
- m->cspace = m->wspaces;
m->x = mons[i].x_org;
m->y = mons[i].y_org;
m->w = mons[i].width;
m->midy = m->y + m->h/2;
m->next = Monitors;
Monitors = m;
+ for (int i = 0; i < 10; i++)
+ {
+ Column* col = ecalloc(1, sizeof(Column));
+ col->mode = TILE_STACKED,
+ col->width = m->w;
+ Workspace* wspace = ecalloc(1, sizeof(Workspace));
+ wspace->columns = col;
+ wspace->next = m->wspaces;
+ m->wspaces = wspace;
+ }
+ m->cspace = m->wspaces;
}
xfree(mons);
}
/* adds a new client to the most appropriate monitor */
void mons_addclient(Client* c)
{
- Monitor* mon = pickmon();
- c->next = mon->cspace->floating;
- mon->cspace->floating = c;
- int cw = c->w + 2*BORDER_WIDTH;
- int ch = c->h + 2*BORDER_WIDTH + TITLE_HEIGHT;
- c->x = mon->midx - cw/2;
- c->y = mon->midy - ch/2;
+ 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);
+ printf("add win to %p\n", mon);
+ if (X.mode == M_INIT)
+ {
+ c->next = mon->cspace->floating;
+ mon->cspace->floating = c;
+ int cw = c->w + 2*BORDER_WIDTH;
+ int ch = c->h + 2*BORDER_WIDTH + TITLE_HEIGHT;
+ c->x = mon->midx - cw/2;
+ c->y = mon->midy - ch/2;
+ }
+ else
+ {
+ Column* col = pickcol(mon->cspace->columns, ptrx - mon->x);
+ c->next = col->clients;
+ col->clients = c;
+ /* TODO: tile the window approriately */
+ }
+ assert(c != c->next);
}
void mons_delclient(Client* c)
{
+ assert(c != c->next);
Location loc = {0};
if (mons_find(c->win, &loc))
{
- loc.workspace->floating = delclient(loc.workspace->floating, c);
+ if (loc.column)
+ {
+ loc.column->clients = delclient(loc.column->clients, c);
+ }
+ else
+ {
+ loc.workspace->floating = delclient(loc.workspace->floating, c);
+ }
xfree(c->name);
XDestroyWindow(X.disp, c->frame);
free(c);
{
for (Workspace* wspace = mon->wspaces; wspace; wspace = wspace->next)
{
- for (Client* client = wspace->floating; client; client = client->next)
+ Column* column = NULL;
+ Client* client = client_find(wspace->floating, win);
+ if (!client)
{
- if (client->frame == win || client->win == win)
+ for (column = wspace->columns; column; column = column->next)
{
- loc->monitor = mon;
- loc->workspace = wspace;
- loc->client = client;
- return 1;
+ if ( (client = client_find(column->clients, win)) )
+ {
+ break;
+ }
}
}
+ /* return the client location if we found it */
+ if (client)
+ {
+ loc->monitor = mon;
+ loc->workspace = wspace;
+ loc->column = column;
+ loc->client = client;
+ return 1;
+ }
}
}
return 0;
int cright = (c->x + c->w + 2*BORDER_WIDTH);
int ctop = (c->y - BORDER_WIDTH);
int cbot = (c->y + c->h + 2*BORDER_WIDTH + TITLE_HEIGHT);
- if (mons_find(c->win, &loc))
+ if (mons_find(c->win, &loc) && !loc.column)
{
int maxarea = 0;
Monitor* closest = NULL;
void mons_wspace(int wsid)
{
- Monitor* mon = pickmon();
+ 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);
Workspace* wspace = pickws(mon, wsid);
if (mon->cspace != wspace)
{
}
}
-static Monitor* pickmon(void)
+static Monitor* pickmon(int ptrx, int ptry)
{
- 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 = Monitors;
for (; mon; mon = mon->next)
{
return mon;
}
+static Column* pickcol(Column* cols, int relx)
+{
+ Column* col = cols;
+ /* find first empty column, and fill that first */
+ for (; col && col->clients; col = col->next);
+ /* otherwise, return the current column */
+ if (!col)
+ {
+ puts("searching for active col");
+ int left = 0, right = 0;
+ for (col = cols; col; col = col->next)
+ {
+ left = right, right += col->width;
+ printf("%d <= %d < %d\n", left, relx, right);
+ if (left <= relx && relx < right)
+ {
+ break; /* we found the column holding the mouse */
+ }
+ }
+ }
+ else
+ {
+ puts("empty col");
+ }
+ assert(col);
+ return col;
+}
+
static Workspace* pickws(Monitor* mon, int wsid)
{
Workspace* wspace = mon->wspaces;
static Client* delclient(Client* list, Client* dead)
{
- if (list == dead)
+ if (!list)
{
- list = list->next;
+ return NULL;
+ }
+ else if (list == dead)
+ {
+ return list->next;
}
else
{
list->next = delclient(list->next, dead);
+ return list;
}
- return list;
}
static void client_visibility(Workspace* wspace, int show)
}
XSync(X.disp, False);
}
+
+static Client* client_find(Client* clients, Window win)
+{
+ Client* client = clients;
+ for (; client; client = client->next)
+ {
+ if (client->frame == win || client->win == win)
+ {
+ break;
+ }
+ }
+ return client;
+}