From: Michael D. Lowis Date: Wed, 31 Oct 2018 15:08:22 +0000 (-0400) Subject: updated registrar to callback with client message when finished with a file X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=2be46e7c35ff9f6be14397e4eccff2f6580940cf;p=projs%2Ftide.git updated registrar to callback with client message when finished with a file --- diff --git a/src/edit.c b/src/edit.c index 5d11930..f3a2a27 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1,3 +1,4 @@ +#define _XOPEN_SOURCE 700 #include #include #include @@ -27,19 +28,24 @@ void prop_set(XConf* x, Window win, char* prop, char* value) { (const unsigned char *)value, strlen(value)+1); } -Window edit_file(XConf* x, Window registrar, char* path, char* addr) { +void edit_file(XConf* x, Window registrar, char* path, char* addr) { static char wdirbuf[32768] = {0}; char* wdir = getcwd(wdirbuf, sizeof(wdirbuf)); - if (!wdir) return None; - Window win = XCreateSimpleWindow(x->display, x->self, 0, 0, 1, 1, 0, 0, 0); - prop_set(x, win, "WDIR", wdir); - prop_set(x, win, "FILE", path); - prop_set(x, win, "ADDR", addr); + if (!wdir) return; + char* rpath = realpath(path, NULL); + prop_set(x, x->self, "WDIR", wdir); + prop_set(x, x->self, "FILE", (rpath ? rpath : path)); + prop_set(x, x->self, "ADDR", addr); + free(rpath); XChangeProperty( x->display, registrar, XA_OPEN, XA_WINDOW, 32, PropModeAppend, - (const unsigned char *)&win, 1); - XSelectInput(x->display, win, 0); - return win; + (const unsigned char *)&(x->self), 1); + /* wait for the "done" message */ + for (XEvent e;;) { + XNextEvent(x->display, &e); + if (e.type == ClientMessage && e.xclient.message_type == XA_DONE) + break; + } } void xclientmsg(XConf* x, XEvent* e) { @@ -56,7 +62,7 @@ int main(int argc, char** argv) { XA_DONE = XInternAtom(x.display, "DONE", 0); Window registrar = start_registrar(&x); if (argc == 1) { - spawn("tide"); + spawn("t2"); } else { /* Loop over files and send and OPEN message for each one. */ for (int i = 1; i < argc; i++) { @@ -66,6 +72,5 @@ int main(int argc, char** argv) { } } XSync(x.display, False); - x11_event_loop(&x); return 0; } diff --git a/src/registrar.c b/src/registrar.c index a4d82c4..324881f 100644 --- a/src/registrar.c +++ b/src/registrar.c @@ -7,7 +7,7 @@ typedef struct TWindow { char* path; } TWindow; -Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE, XA_FILE; +Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE, XA_WDIR, XA_FILE, XA_ADDR; TWindow* Windows = NULL; char* readprop(XConf* x, Window win, Atom prop, size_t* length) { @@ -56,28 +56,26 @@ void win_send(XConf* x, Window from, Window to, int mask, char* atom, size_t val ev.xclient.format = 32; ev.xclient.data.l[0] = val; XSendEvent(x->display, to, False, mask, &ev); + XFlush(x->display); } -void win_open(XConf* x, char* path) { - /* parse out address for later */ - char* addr = strrchr(path, ':'); - if (addr) *addr = '\0', addr++; - if (!addr) addr = "0"; - +void win_open(XConf* x, char* wdir, char* path, char* addr) { + if (!path) return; /* search for an existing window */ for (TWindow* win = Windows; win; win = win->next) { if (!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)); - XFlush(x->display); return; } } /* if we don't find it, spawn a new one */ - if (!fork()) - exit(execvp("tide", (char*[]){"tide", "-l", addr, path, 0})); + if (!fork()) { + if (wdir) chdir(wdir); + exit(execvp("t2", (char*[]){"t2", "-l", addr, path, 0})); + } } void selclear(XConf* x, XEvent* e) { @@ -102,19 +100,15 @@ void propnotify(XConf* x, XEvent* e) { x->display, x->self, XA_OPEN, 0, -1, True, XA_WINDOW, &type, &format, &datalen, &nleft, &data); for (Window* win = (Window*)data; datalen && win && *win; win++, datalen--) { - printf("%#lx\n", *win); + char* wdir = readprop(x, *win, XA_WDIR, NULL); + char* file = readprop(x, *win, XA_FILE, NULL); + char* addr = readprop(x, *win, XA_ADDR, NULL); + win_open(x, wdir, file, (addr ? addr : "0")); win_send(x, x->self, *win, 0, "DONE", 0); + if(wdir) XFree(wdir); + if(file) XFree(file); + if(addr) XFree(addr); } - -// size_t length; -// char* paths = readprop(x, x->self, XA_OPEN, &length); -// char* path = paths; -// while (length && *path) { -// size_t sz = strlen((char*)path)+1; -// win_open(x, (char*)path); -// path += sz, length -= sz; -// } -// XFree(paths); } int main(int argc, char** argv) { @@ -126,7 +120,9 @@ 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_WDIR = XInternAtom(x.display, "WDIR", 0); XA_FILE = XInternAtom(x.display, "FILE", 0); + XA_ADDR = XInternAtom(x.display, "ADDR", 0); x.eventfns[SelectionClear] = selclear; x.eventfns[ClientMessage] = clientmsg; x.eventfns[PropertyNotify] = propnotify;