#include #include #include #include #include "dat.h" #include "fns.h" #include "config.h" 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) { XRRMonitorInfo m; int cx, cy, i, p; cx = cy = 0; /* we check which monitor the center of the window is in */ if (c) { cx = c->x + c->dx / 2; cy = c->y + c->dy / 2; } p = 0; for (i = 0; i < nmonitors; i++) { m = monitorinfo[i]; if ( c && cx >= m.x && cx < m.x + m.width && cy >= m.y && cy < m.y + m.height) { return i; } if (m.primary) { p = i; } } /* if center is not within any monitor, return primary */ return p; } int getmonitorbymouse() { Window w; int x, y, i; unsigned int mask; XRRMonitorInfo m; XQueryPointer(dpy, DefaultRootWindow(dpy), &w, &w, &x, &y, &x, &y, &mask); for (i = 0; i < nmonitors; i++) { m = monitorinfo[i]; if (x >= m.x && x < m.x + m.width && y >= m.y && y < m.y + m.height) { return i; } } /* should never reach here, but return first monitor if we do */ return 0; } void wrangle(Client* c, XRRMonitorInfo monitor) { if (!c) return; /* If it's bigger than the screen, try to set it maximized */ if (c->dx >= monitor.width && c->dy >= monitor.height) { quickreshape(c, monitor.x, monitor.y, monitor.width, monitor.height, 1); /* and if it's got an edge out of bounds, nudge it into bounds */ } else { if (c->x < monitor.x + BORDER) { quickreshape( c, monitor.x, c->y - BORDER, c->dx + 2 * BORDER, c->dy + 2 * BORDER, 0); } if (c->y < monitor.y + BORDER) { quickreshape( c, c->x - BORDER, monitor.y, c->dx + 2 * BORDER, c->dy + 2 * BORDER, 0); } if (c->x + c->dx + BORDER > monitor.x + monitor.width) { quickreshape( c, monitor.x + monitor.width - (c->dx + 2 * BORDER), c->y - BORDER, c->dx + 2 * BORDER, c->dy + 2 * BORDER, 0); } if (c->y + c->dy + BORDER > monitor.y + monitor.height) { quickreshape( c, c->x - BORDER, monitor.y + monitor.height - (c->dy + 2 * BORDER), c->dx + 2 * BORDER, c->dy + 2 * BORDER, 0); } } }