diff --git a/config.def.h b/config.def.h index 3b2221d..af57c7a 100644 --- a/config.def.h +++ b/config.def.h @@ -102,6 +102,11 @@ * BEHAVIOR * [Everything in this section is optional unless otherwise noted] ***********/ +/* If this is at least 2, pretty cascading is enabled, and newly spawned windows + * will try to respect it instead of centering */ + +#define CASCADE_DENSITY 4 + /* This sets the size ratio for windows spawned via keyboard or * center-snapped; CENTERNUM should be >= 2, so use 2/4 instead of 1/2 */ diff --git a/dat.h b/dat.h index 7547aeb..d55e7e9 100644 --- a/dat.h +++ b/dat.h @@ -198,3 +198,6 @@ extern int kbLaunch; extern int nmonitors; extern XRRMonitorInfo* monitorinfo; + +extern int* xstep; +extern int* ystep; \ No newline at end of file diff --git a/event.c b/event.c index 881f0cd..2aca92b 100644 --- a/event.c +++ b/event.c @@ -211,10 +211,16 @@ void configurereq(XConfigureRequestEvent* e) { void mapreq(XMapRequestEvent* e) { Client* c; - int i; + int i, m; XRRMonitorInfo monitor; - monitor = monitorinfo[getmonitorbymouse()]; +#ifdef MONITORFOLLOWSMOUSE + m = getmonitorbymouse(); +#else + m = getmonitorbyclient(current); +#endif + + monitor = monitorinfo[m]; curtime = CurrentTime; c = getclient(e->window, 0); @@ -236,7 +242,7 @@ void mapreq(XMapRequestEvent* e) { } } - if (kbLaunch) { + if (kbLaunch && CASCADE_DENSITY < 2) { // usleep(MICROSLEEP_DELAY); #ifdef CENTERVMAX centerclient(c, monitor, 1); @@ -244,6 +250,8 @@ void mapreq(XMapRequestEvent* e) { centerclient(c, monitor, 0); #endif kbLaunch = 0; + } else if (CASCADE_DENSITY >= 2 && c->trans == None) { + getcascadecoords(c->window, m, &(c->x), &(c->y)); } switch (c->state) { case WithdrawnState: diff --git a/fns.h b/fns.h index 87deb8a..4014aa8 100644 --- a/fns.h +++ b/fns.h @@ -130,3 +130,4 @@ void fetchmonitorinfo(); int getmonitorbyclient(Client*); int getmonitorbymouse(); void wrangle(Client*, XRRMonitorInfo); +void getcascadecoords(Window, int, int*, int*); \ No newline at end of file diff --git a/monitor.c b/monitor.c index 8f784c2..5c27fa5 100644 --- a/monitor.c +++ b/monitor.c @@ -8,12 +8,58 @@ int nmonitors = 0; XRRMonitorInfo* monitorinfo; +int* xstep; +int* ystep; void fetchmonitorinfo() { if (monitorinfo) XRRFreeMonitors(monitorinfo); + if (xstep) + free(xstep); + if (ystep) + free(ystep); monitorinfo = XRRGetMonitors(dpy, DefaultRootWindow(dpy), 1, &nmonitors); + xstep = malloc(nmonitors * sizeof(int)); + ystep = malloc(nmonitors * sizeof(int)); + for (int i = 0; i < nmonitors; i++) { + xstep[i] = monitorinfo[i].width / CASCADE_DENSITY; + ystep[i] = monitorinfo[i].height / CASCADE_DENSITY; + } +} + +void getcascadecoords(Window w, int monitor, int* x, int* y) { + int mappedclients = 0; + Client* c; + int ox = monitorinfo[monitor].x; + int oy = monitorinfo[monitor].y; + + if (w == 0) + return; + for (c = clients; c; c = c->next) { + if ( + c->window != w && c->state == NormalState && + getmonitorbyclient(c) == monitor) { + mappedclients++; + } + } + for (;;) { + if (mappedclients < CASCADE_DENSITY) { + *x = ox + mappedclients * xstep[monitor]; + *y = oy + mappedclients * ystep[monitor]; + return; + } else if (mappedclients < 1.5 * CASCADE_DENSITY) { + *x = ox + (mappedclients - CASCADE_DENSITY + 1) * xstep[monitor]; + *y = oy + (mappedclients - CASCADE_DENSITY) * ystep[monitor]; + return; + } else if (mappedclients < 2 * CASCADE_DENSITY) { + *x = ox + (mappedclients - 1.5 * CASCADE_DENSITY) * xstep[monitor]; + *y = oy + (mappedclients - 1.5 * CASCADE_DENSITY + 1) * ystep[monitor]; + return; + } else { + mappedclients -= 2 * CASCADE_DENSITY; + } + } } int getmonitorbyclient(Client* c) {