X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=3b7bfce0a0b3a014188d27ffafcad8fbacda6b41;hb=014589e60503fee99276da4252258e553d62b055;hp=2d10ceb0ccfc717807c3fe5d655659a777f85c37;hpb=5f8a010ab295ed72a1f432a3c47fe804dc87e76d;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 2d10ceb..3b7bfce 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -54,7 +54,7 @@ static const char *cvstag = "$scrotwm$"; -#define SWM_VERSION "0.9.31" +#define SWM_VERSION "0.9.32" #include #include @@ -332,8 +332,10 @@ struct layout { { NULL, NULL, 0, NULL }, }; -/* position of max_stack mode in the layouts array */ -#define SWM_MAX_STACK 2 +/* position of max_stack mode in the layouts array, index into layouts! */ +#define SWM_V_STACK (0) +#define SWM_H_STACK (1) +#define SWM_MAX_STACK (2) #define SWM_H_SLICE (32) #define SWM_V_SLICE (32) @@ -1063,6 +1065,9 @@ find_pid(long pid) DNPRINTF(SWM_D_MISC, "find_pid: %lu\n", pid); + if (pid == 0) + return (NULL); + TAILQ_FOREACH(p, &pidlist, entry) { if (p->pid == pid) return (p); @@ -4521,8 +4526,9 @@ setautorun(char *selector, char *value, int flags) { int ws_id; char s[1024]; + char *ap, *sp = s; union arg a; - char *real_args[] = { NULL, NULL }; + int argc = 0; long pid; struct pid_e *p; @@ -4530,11 +4536,11 @@ setautorun(char *selector, char *value, int flags) return (0); bzero(s, sizeof s); - if (sscanf(value, "ws[%d]:%1023s", &ws_id, s) != 2) - errx(1, "invalid autorun entry, should be 'ws:command'\n"); + if (sscanf(value, "ws[%d]:%1023c", &ws_id, s) != 2) + errx(1, "invalid autorun entry, should be 'ws[]:command'\n"); ws_id--; if (ws_id < 0 || ws_id >= SWM_WS_MAX) - errx(1, "invalid workspace %d\n", ws_id + 1); + errx(1, "autorun: invalid workspace %d\n", ws_id + 1); /* * This is a little intricate @@ -4543,13 +4549,27 @@ setautorun(char *selector, char *value, int flags) * used before AND not claimed by manage_window. We get away with * altering it in the parent after INSERT because this can not be a race */ - real_args[0] = s; - a.argv = real_args; /* XXX this sucks and should have args for real */ + a.argv = NULL; + while ((ap = strsep(&sp, " \t")) != NULL) { + if (*ap == '\0') + continue; + DNPRINTF(SWM_D_SPAWN, "setautorun: arg [%s]\n", ap); + argc++; + if ((a.argv = realloc(a.argv, argc * sizeof(char *))) == NULL) + err(1, "setautorun: realloc"); + a.argv[argc - 1] = ap; + } + + if ((a.argv = realloc(a.argv, (argc + 1) * sizeof(char *))) == NULL) + err(1, "setautorun: realloc"); + a.argv[argc] = NULL; + if ((pid = fork()) == 0) { spawn(ws_id, &a, 1); /* NOTREACHED */ _exit(1); } + free(a.argv); /* parent */ p = find_pid(pid); @@ -4566,11 +4586,70 @@ setautorun(char *selector, char *value, int flags) return (0); } +int +setlayout(char *selector, char *value, int flags) +{ + int ws_id, st, i, x, mg, ma, si; + char s[1024]; + struct workspace *ws; + + if (getenv("SWM_STARTED")) + return (0); + + bzero(s, sizeof s); + if (sscanf(value, "ws[%d]:%d:%d:%d:%1023c", + &ws_id, &mg, &ma, &si, s) != 5) + errx(1, "invalid layout entry, should be 'ws[]:'\n"); + ws_id--; + if (ws_id < 0 || ws_id >= SWM_WS_MAX) + errx(1, "layout: invalid workspace %d\n", ws_id + 1); + + if (!strcasecmp(s, "vertical")) + st = SWM_V_STACK; + else if (!strcasecmp(s, "horizontal")) + st = SWM_H_STACK; + else if (!strcasecmp(s, "fullscreen")) + st = SWM_MAX_STACK; + else + errx(1, "invalid layout entry, should be 'ws[]:'\n"); + + for (i = 0; i < ScreenCount(display); i++) { + ws = (struct workspace *)&screens[i].ws; + ws[ws_id].cur_layout = &layouts[st]; + if (st == SWM_MAX_STACK) + continue; + + /* master grow */ + for (x = 0; x < abs(mg); x++) { + ws[ws_id].cur_layout->l_config(&ws[ws_id], + mg >= 0 ? SWM_ARG_ID_MASTERGROW : + SWM_ARG_ID_MASTERSHRINK); + stack(); + } + /* master add */ + for (x = 0; x < abs(ma); x++) { + ws[ws_id].cur_layout->l_config(&ws[ws_id], + ma >= 0 ? SWM_ARG_ID_MASTERADD : + SWM_ARG_ID_MASTERDEL); + stack(); + } + /* stack inc */ + for (x = 0; x < abs(si); x++) { + ws[ws_id].cur_layout->l_config(&ws[ws_id], + si >= 0 ? SWM_ARG_ID_STACKINC : + SWM_ARG_ID_STACKDEC); + stack(); + } + } + + return (0); +} + /* config options */ struct config_option { char *optname; - int (*func)(char*, char*, int); - int funcflags; + int (*func)(char*, char*, int); + int funcflags; }; struct config_option configopt[] = { { "bar_enabled", setconfvalue, SWM_S_BAR_ENABLED }, @@ -4606,6 +4685,7 @@ struct config_option configopt[] = { { "disable_border", setconfvalue, SWM_S_DISABLE_BORDER }, { "border_width", setconfvalue, SWM_S_BORDER_WIDTH }, { "autorun", setautorun, 0 }, + { "layout", setlayout, 0 }, }; @@ -4761,20 +4841,43 @@ window_get_pid(Window win) int actual_format_return = 0; unsigned long nitems_return = 0; unsigned long bytes_after_return = 0; - long *pid = 0; + long *pid = NULL; long ret = 0; + const char *errstr; + unsigned char *prop = NULL; if (XGetWindowProperty(display, win, XInternAtom(display, "_NET_WM_PID", False), 0, 1, False, XA_CARDINAL, &actual_type_return, &actual_format_return, &nitems_return, &bytes_after_return, (unsigned char**)(void*)&pid) != Success) - return (0); + goto tryharder; + if (actual_type_return != XA_CARDINAL) + goto tryharder; + if (pid == NULL) + goto tryharder; - ret = pid[0]; + ret = *pid; XFree(pid); return (ret); + +tryharder: + if (XGetWindowProperty(display, win, + XInternAtom(display, "_SWM_PID", False), 0, SWM_PROPLEN, False, + XA_STRING, &actual_type_return, &actual_format_return, + &nitems_return, &bytes_after_return, &prop) != Success) + return (0); + if (actual_type_return != XA_STRING) + return (0); + if (prop == NULL) + return (0); + + ret = strtonum(prop, 0, UINT_MAX, &errstr); + /* ignore error because strtonum returns 0 anyway */ + XFree(prop); + + return (ret); } struct ws_win *