wmii/cmd/strut/main.c

178 lines
3.1 KiB
C

/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
* See LICENSE file for license details.
*/
#define EXTERN
#include "dat.h"
#include <X11/Xproto.h>
#include <locale.h>
#include <string.h>
#include <time.h>
#include "fns.h"
char *argv0;
Display *display;
Screen scr;
static Window* testwin;
static ulong testtime[2];
static const char version[] = "wistrut-"VERSION", "COPYRIGHT"\n";
static void manage(ulong);
static void
usage(void) {
fatal("usage: %s [-HV] <window|class>...\n", argv0);
}
static void
search_wins(char *pattern) {
ulong *wins;
ulong n, num;
int i;
char **class;
Reprog *regexp;
Window *win;
regexp = regcomp(pattern);
num = getprop_ulong(&scr.root, "_NET_CLIENT_LIST", "WINDOW", 0L, &wins, 1024L);
for(i = 0; i < num; i++) {
win = window(wins[i]);
n = getprop_textlist(win, "WM_CLASS", &class);
bufclear();
bufprint("%s:%s:%s",
(n > 0 ? class[0] : "<nil>"),
(n > 1 ? class[1] : "<nil>"),
freelater(windowname(win)));
freestringlist(class);
if(regexec(regexp, buffer, nil, 0))
manage(wins[i]);
}
free(wins);
}
static Window
findframe(Window *w) {
XWindow *children;
XWindow xw, par, root;
Window ret = {0, };
uint n;
xw = w->xid;
for(par=w->xid; par != scr.root.xid; ) {
xw = par;
XQueryTree(display, xw, &root, &par, &children, &n);
XFree(children);
}
ret.type = WWindow;
ret.xid = xw;
ret.parent = &scr.root;
return ret;
}
static void
getwinsize(Window *win) {
int x, y;
uint w, h;
XWindow root;
uint border, depth;
XGetGeometry(display, win->xid, &root,
&x, &y, &w, &h,
&border, &depth);
win->r = rectaddpt(Rect(0, 0, w, h),
Pt(x+border, y+border));
}
static bool
managable(ulong xid) {
ulong *ret;
ulong n;
bool retval;
n = getprop_ulong(window(xid), "_WMII_STRUT", "WINDOW", 0L, &ret, 1L);
if(n < 0)
retval = true;
else {
if(ret[0] == xid)
retval = ret[0] != testtime[0] || ret[1] != testtime[1];
else
retval = managable(ret[0]);
}
free(ret);
return retval;
}
static void
manage(ulong xid) {
Window *frame;
Window *win;
if(!managable(xid))
return;
win = emallocz(sizeof *win);
frame = emalloc(sizeof *frame);
win->type = WWindow;
win->xid = xid;
*frame = findframe(win);
frame->aux = win;
getwinsize(frame);
restrut(frame);
sethandler(frame, &handlers);
selectinput(frame, StructureNotifyMask);
changeprop_ulong(frame, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime));
}
int
main(int argc, char *argv[]) {
ulong win;
char *s;
setlocale(LC_CTYPE, "");
fmtinstall('E', fmtevent);
ARGBEGIN{
case 'H':
direction = DHorizontal;
break;
case 'V':
direction = DVertical;
break;
case 'v':
lprint(1, "%s", version);
return 0;
default:
usage();
}ARGEND;
initdisplay();
testwin = createwindow(&scr.root, Rect(0, 0, 1, 1), 0,
InputOnly, nil, 0);
testtime[0] = testwin->xid;
testtime[1] = time(nil);
while(argc) {
s = ARGF();
if(getulong(s, &win))
manage(win);
else
search_wins(s);
}
changeprop_ulong(testwin, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime));
if(windowmap.nmemb > 0)
event_loop();
XCloseDisplay(display);
return 0;
}