]> git.mdlowis.com Git - projs/tide.git/commitdiff
added detection of invalid window cleanup to registrar
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 10 Jan 2019 03:34:19 +0000 (22:34 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 10 Jan 2019 03:34:19 +0000 (22:34 -0500)
TODO.md
inc/x11.h
src/lib/x11.c
src/registrar.c
src/tide.c

diff --git a/TODO.md b/TODO.md
index 05821e26d4ed1d34ab031f327d859bb525f85098..1c66a919b8b1ac1330305f0e94581e43fa98d120 100644 (file)
--- 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
index a89a8b1162b80527b2c73acee68cbc4119b9113b..131670f970df0445cc7734bf8b8d6979175d8522 100644 (file)
--- 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);
index cb36742b247f0547f72f980161fb5ed2b72c62f3..9a1730d74a4b0caabb3c45a8d8ec1ea4aa91a2c9 100644 (file)
@@ -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));
 }
index 29d5895a41333c7ed5e4d58cd5c0263cfdbdc9e4..b7f3a0f1d36c0b516d4b8e0495f97797c69950ca 100644 (file)
@@ -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;
index ce1874429b51a8341dafe6ebff9b825122238c69..13b2c7a6fd72445104340a01661020f2a1418b03 100644 (file)
@@ -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) {