char* ARGV0;
int Foreground = 0;
-Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE;
+Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE, XA_TIDE;
TWindow* Windows = NULL;
void* readprop(XConf* x, Window win, char* prop, Atom type, size_t* length) {
if (length) *length = datalen;
if (rtype != type) {
if (data) XFree(data);
- data = 0, *length = 0;
+ data = 0;
+ if (length) *length = 0;
}
return (void*)data;
}
-void win_add(XConf* x, Window id) {
+char* read_path(XConf* x, Window id) {
int nprops;
char* path = NULL;
Atom xa_file = XInternAtom(x->display, "FILE", False);
Atom* props = XListProperties(x->display, id, &nprops);
- if (!props) return;
+ if (!props) return NULL;
for (int i = 0; i < nprops; i++) {
if (props[i] == xa_file) {
path = readprop(x, id, "FILE", XA_STRING, 0);
}
}
XFree(props);
+ return path;
+}
+
+void win_add(XConf* x, Window id) {
+ char* path = read_path(x, id);
if (!path) return;
printf("ADD 0x%x: '%s'\n", (unsigned int)id, path);
TWindow* win = calloc(1, sizeof(TWindow));
/* search for an existing window */
for (TWindow* win = Windows; win; win = win->next) {
if (win->path && !strcmp(win->path, path)) {
- win_send(x, win->win, x->root, SubstructureRedirectMask|SubstructureNotifyMask, "_NET_ACTIVE_WINDOW", 0);
- XMapRaised(x->display, win->win);
- win_send(x, x->self, win->win, 0, "GOTO", strtoul(addr, NULL, 0));
- win_send(x, x->self, winid, 0, "DONE", 0);
- return;
+ printf("found open window: 0x%x '%s'\n", (unsigned int)win->win, win->path);
+ x11_error_clear();
+ char* type = readprop(x, win->win, "TIDE", XA_STRING, 0);
+ if (!type || x11_error_get()) {
+ puts("window invalid, marking for cleanup");
+ free(win->path);
+ win->path = NULL;
+ free(type);
+ break;
+ } else {
+ puts("window still valid, raising");
+ win_send(x, x->self, win->win, 0, "GOTO", strtoul(addr, NULL, 0));
+ win_send(x, x->self, winid, 0, "DONE", 0);
+ free(type);
+ return;
+ }
}
}
XGetWindowProperty(
x->display, x->self, XA_OPEN, 0, -1, True, XA_WINDOW,
&type, &format, &datalen, &nleft, &data);
+ /* handle all of the window requests */
for (Window* win = (Window*)data; datalen && win && *win; win++, datalen--) {
char* file = readprop(x, *win, "FILE", XA_STRING, NULL);
char* addr = readprop(x, *win, "ADDR", XA_STRING, NULL);
if(file) XFree(file);
if(addr) XFree(addr);
}
+ /* cleanup any invalid windows */
+ TWindow* wins = Windows;
+ Windows = NULL;
+ while (wins) {
+ TWindow* curr = wins;
+ wins = curr->next;
+ if (!wins->path) {
+ free(curr);
+ } else {
+ curr->next = Windows;
+ Windows = curr;
+ }
+ }
}
void find_windows(XConf* x) {
XA_DEL = XInternAtom(x.display, "DEL", 0);
XA_OPEN = XInternAtom(x.display, "OPEN", 0);
XA_DONE = XInternAtom(x.display, "DONE", 0);
+ XA_TIDE = XInternAtom(x.display, "TIDE", 0);
x.eventfns[SelectionClear] = selclear;
x.eventfns[ClientMessage] = clientmsg;
x.eventfns[PropertyNotify] = propnotify;