From 01bdc77b94ea64664bb79400d72bbaa92b99936b Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 9 Jan 2019 22:34:19 -0500 Subject: [PATCH] added detection of invalid window cleanup to registrar --- TODO.md | 1 - inc/x11.h | 2 +- src/lib/x11.c | 2 +- src/registrar.c | 50 ++++++++++++++++++++++++++++++++++++++++--------- src/tide.c | 1 + 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/TODO.md b/TODO.md index 05821e2..1c66a91 100644 --- a/TODO.md +++ b/TODO.md @@ -6,7 +6,6 @@ * registrar: doesnt match open windows when new file created and is then opened for edit or line number * registrar: group by hostname or group env var in registrar -* registrar: should remove invalid windows from registry when detected * tide: gap buffer does not handle UTF-8 currently ## BACKLOG diff --git a/inc/x11.h b/inc/x11.h index a89a8b1..131670f 100644 --- a/inc/x11.h +++ b/inc/x11.h @@ -27,7 +27,7 @@ enum { }; int x11_init(XConf* x); -void x11_clear_error(void); +void x11_error_clear(void); XErrorEvent* x11_error_get(void); void x11_mkwin(XConf* x, int width, int height, int evmask); diff --git a/src/lib/x11.c b/src/lib/x11.c index cb36742..9a1730d 100644 --- a/src/lib/x11.c +++ b/src/lib/x11.c @@ -32,7 +32,7 @@ int x11_init(XConf* x) { return 0; } -void x11_clear_error(void) { +void x11_error_clear(void) { Has_Error = False; memset(&Error, 0, sizeof(Error)); } diff --git a/src/registrar.c b/src/registrar.c index 29d5895..b7f3a0f 100644 --- a/src/registrar.c +++ b/src/registrar.c @@ -11,7 +11,7 @@ typedef struct TWindow { 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) { @@ -25,17 +25,18 @@ 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); @@ -43,6 +44,11 @@ void win_add(XConf* x, Window id) { } } 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)); @@ -86,11 +92,22 @@ void win_open(XConf* x, Window winid, char* path, char* addr) { /* 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; + } } } @@ -122,6 +139,7 @@ void propnotify(XConf* x, XEvent* e) { 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); @@ -129,6 +147,19 @@ void propnotify(XConf* x, XEvent* e) { 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) { @@ -181,6 +212,7 @@ int main(int argc, char** argv) { 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; diff --git a/src/tide.c b/src/tide.c index ce18744..13b2c7a 100644 --- a/src/tide.c +++ b/src/tide.c @@ -326,6 +326,7 @@ void win_init(KeyBinding* bindings) { View* view = win_view(TAGS); view_putstr(view, TagString); buf_logclear(&(view->buffer)); + win_prop_set("TIDE", "", "tide"); } void win_title(char* path) { -- 2.49.0