main.c (3122B)
1 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail> 2 * See LICENSE file for license details. 3 */ 4 #define EXTERN 5 #include "dat.h" 6 #include <X11/Xproto.h> 7 #include <locale.h> 8 #include <string.h> 9 #include <time.h> 10 #include "fns.h" 11 12 static Window* testwin; 13 static ulong testtime[2]; 14 15 static const char version[] = "wistrut-"VERSION", "COPYRIGHT"\n"; 16 17 static void manage(ulong); 18 19 static void 20 usage(void) { 21 fatal("usage: %s [-HV] <window|class>...\n", argv0); 22 } 23 24 static void 25 search_wins(char *pattern) { 26 ulong *wins; 27 ulong n, num; 28 int i; 29 char **class; 30 Reprog *regexp; 31 Window *win; 32 33 regexp = regcomp(pattern); 34 35 num = getprop_ulong(&scr.root, "_NET_CLIENT_LIST", "WINDOW", 0L, &wins, 1024L); 36 for(i = 0; i < num; i++) { 37 win = window(wins[i]); 38 39 n = getprop_textlist(win, "WM_CLASS", &class); 40 bufclear(); 41 bufprint("%s:%s:%s", 42 (n > 0 ? class[0] : "<nil>"), 43 (n > 1 ? class[1] : "<nil>"), 44 freelater(windowname(win))); 45 freestringlist(class); 46 if(regexec(regexp, buffer, nil, 0)) 47 manage(wins[i]); 48 } 49 free(wins); 50 } 51 52 static Window 53 findframe(Window *w) { 54 XWindow *children; 55 XWindow xw, par, root; 56 Window ret = {0, }; 57 uint n; 58 59 xw = w->xid; 60 for(par=w->xid; par != scr.root.xid; ) { 61 xw = par; 62 XQueryTree(display, xw, &root, &par, &children, &n); 63 XFree(children); 64 } 65 ret.type = WWindow; 66 ret.xid = xw; 67 ret.parent = &scr.root; 68 return ret; 69 } 70 71 static void 72 getwinsize(Window *win) { 73 int x, y; 74 uint w, h; 75 XWindow root; 76 uint border, depth; 77 78 XGetGeometry(display, win->xid, &root, 79 &x, &y, &w, &h, 80 &border, &depth); 81 win->r = rectaddpt(Rect(0, 0, w, h), 82 Pt(x+border, y+border)); 83 } 84 85 static bool 86 managable(ulong xid) { 87 ulong *ret; 88 ulong n; 89 bool retval; 90 91 n = getprop_ulong(window(xid), "_WMII_STRUT", "WINDOW", 0L, &ret, 1L); 92 if(n < 0) 93 retval = true; 94 else { 95 if(ret[0] == xid) 96 retval = ret[0] != testtime[0] || ret[1] != testtime[1]; 97 else 98 retval = managable(ret[0]); 99 } 100 free(ret); 101 return retval; 102 } 103 104 static void 105 manage(ulong xid) { 106 Window *frame; 107 Window *win; 108 109 if(!managable(xid)) 110 return; 111 112 win = emallocz(sizeof *win); 113 frame = emalloc(sizeof *frame); 114 115 win->type = WWindow; 116 win->xid = xid; 117 *frame = findframe(win); 118 frame->aux = win; 119 120 getwinsize(frame); 121 restrut(frame); 122 sethandler(frame, &handlers); 123 selectinput(frame, StructureNotifyMask); 124 125 changeprop_ulong(frame, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime)); 126 } 127 128 int 129 main(int argc, char *argv[]) { 130 ulong win; 131 char *s; 132 133 setlocale(LC_CTYPE, ""); 134 fmtinstall('E', fmtevent); 135 136 ARGBEGIN{ 137 case 'H': 138 direction = DHorizontal; 139 break; 140 case 'V': 141 direction = DVertical; 142 break; 143 case 'v': 144 lprint(1, "%s", version); 145 return 0; 146 default: 147 usage(); 148 }ARGEND; 149 150 initdisplay(); 151 152 testwin = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, 153 InputOnly, nil, 0); 154 testtime[0] = testwin->xid; 155 testtime[1] = time(nil); 156 157 while(argc) { 158 s = ARGF(); 159 if(getulong(s, &win)) 160 manage(win); 161 else 162 search_wins(s); 163 } 164 165 changeprop_ulong(testwin, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime)); 166 167 if(windowmap.nmemb > 0) 168 event_loop(); 169 170 XCloseDisplay(display); 171 return 0; 172 } 173