#include <x11.h>
#include <unistd.h>
+#include <stdc.h>
Atom XA_REGISTRAR, XA_OPEN;
return XGetSelectionOwner(x->display, XA_REGISTRAR);
}
+void edit_file(XConf* x, Window registrar, char* path, size_t lnnum) {
+ char number[32] = {0};
+ snprintf(number, 32, ":%lu", lnnum);
+ char* rpath = realpath(path, NULL);
+ if (rpath)
+ path = strmcat(rpath, number, 0);
+ else
+ path = strmcat(path, number, 0);
+ XChangeProperty(
+ x->display, registrar, XA_OPEN, XA_STRING, 8, PropModeAppend,
+ (const unsigned char *)path, strlen(path)+1);
+ free(path);
+}
+
int main(int argc, char** argv) {
XConf x = {0};
x11_init(&x);
} else {
/* Loop over files and send and OPEN message for each one. */
for (int i = 1; i < argc; i++) {
- XChangeProperty(
- x.display, registrar, XA_OPEN, XA_STRING, 8, PropModeAppend,
- (const unsigned char *)argv[i], strlen(argv[i])+1);
+ char* addr = strrchr(argv[i], ':');
+ if (addr) *addr = '\0', addr++;
+ edit_file(&x, registrar, argv[i], strtoul((addr ? addr : ""), NULL, 0));
}
}
}
}
+void win_send(XConf* x, Window from, Window to, int mask, char* atom, size_t val) {
+ XEvent ev = {0};
+ ev.xclient.type = ClientMessage;
+ ev.xclient.send_event = True;
+ ev.xclient.message_type = XInternAtom(x->display, atom, False);
+ ev.xclient.window = from;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = val;
+ XSendEvent(x->display, to, False, mask, &ev);
+}
+
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";
+
/* search for an existing window */
for (TWindow* win = Windows; win; win = win->next) {
if (!strcmp(win->path, path)) {
- XEvent ev = {0};
- ev.xclient.type = ClientMessage;
- ev.xclient.send_event = True;
- ev.xclient.message_type = XInternAtom(x->display, "_NET_ACTIVE_WINDOW", False);
- ev.xclient.window = win->win;
- ev.xclient.format = 32;
- XSendEvent(x->display, x->root, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev);
+ 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", path, 0}));
+ exit(execvp("tide", (char*[]){"tide", "-l", addr, path, 0}));
}
void selclear(XConf* x, XEvent* e) {
size_t length;
char* paths = readprop(x, x->self, XA_OPEN, &length);
char* path = paths;
- while (length) {
+ while (length && *path) {
size_t sz = strlen((char*)path)+1;
win_open(x, (char*)path);
path += sz, length -= sz;