From: Reginald Kennedy Date: Mon, 5 Nov 2012 03:23:36 +0000 (+0800) Subject: Validate bound spawn programs after conf is loaded. X-Git-Url: https://jasonwoof.com/gitweb/?a=commitdiff_plain;h=cc956fe9e2e8a5a1cb46a013a521c94b95f597c6;p=spectrwm.git Validate bound spawn programs after conf is loaded. Validate screenshot_* and initscr bindings only when overridden. Simplify setspawn. Remove spawn_replace as it is no longer needed. --- diff --git a/spectrwm.c b/spectrwm.c index 132743f..1378638 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -707,12 +707,15 @@ struct cursors { {"top_right_corner", XC_top_right_corner, XCB_CURSOR_NONE}, }; +#define SWM_SPAWN_OPTIONAL 0x1 + /* spawn */ struct spawn_prog { TAILQ_ENTRY(spawn_prog) entry; char *name; int argc; char **argv; + int flags; }; TAILQ_HEAD(spawn_list, spawn_prog); struct spawn_list spawns = TAILQ_HEAD_INITIALIZER(spawns); @@ -857,8 +860,7 @@ void bar_print(struct swm_region *, const char *); void bar_print_legacy(struct swm_region *, const char *); void bar_replace(char *, char *, struct swm_region *, size_t); void bar_replace_pad(char *, int *, size_t); -char * bar_replace_seq(char *, char *, struct swm_region *, size_t *, - size_t); +char *bar_replace_seq(char *, char *, struct swm_region *, size_t *, size_t); void bar_setup(struct swm_region *); void bar_title_name(char *, size_t, struct swm_region *); void bar_toggle(struct swm_region *, union arg *); @@ -1009,7 +1011,7 @@ int setkeymapping(char *, char *, int); int setlayout(char *, char *, int); void setquirk(const char *, const char *, unsigned long); void setscreencolor(char *, int, int); -void setspawn(const char *, const char *); +void setspawn(const char *, const char *, int); void setup_ewmh(void); void setup_globals(void); void setup_keys(void); @@ -1026,15 +1028,15 @@ void sort_windows(struct ws_win_list *); void spawn(int, union arg *, int); void spawn_custom(struct swm_region *, union arg *, const char *); int spawn_expand(struct swm_region *, union arg *, const char *, char ***); -void spawn_insert(const char *, const char *); +void spawn_insert(const char *, const char *, int); void spawn_remove(struct spawn_prog *); -void spawn_replace(struct spawn_prog *, const char *, const char *); +void spawn_replace(struct spawn_prog *, const char *, const char *, int); void spawn_select(struct swm_region *, union arg *, const char *, int *); void stack_config(struct swm_region *, union arg *); void stack_floater(struct ws_win *, struct swm_region *); void stack_master(struct workspace *, struct swm_geometry *, int, int); void store_float_geom(struct ws_win *, struct swm_region *); -char * strdupsafe(const char *); +char *strdupsafe(const char *); void swapwin(struct swm_region *, union arg *); void switchws(struct swm_region *, union arg *); void teardown_ewmh(void); @@ -1047,6 +1049,7 @@ void unmap_window(struct ws_win *); void updatenumlockmask(void); void update_modkey(unsigned int); void update_window(struct ws_win *); +void validate_spawns(void); int validate_win(struct ws_win *); int validate_ws(struct workspace *); /*void visibilitynotify(xcb_visibility_notify_event_t *);*/ @@ -5926,7 +5929,7 @@ spawn_select(struct swm_region *r, union arg *args, const char *spawn_name, } void -spawn_insert(const char *name, const char *args) +spawn_insert(const char *name, const char *args, int flags) { char *arg, *cp, *ptr; struct spawn_prog *sp; @@ -5955,6 +5958,8 @@ spawn_insert(const char *name, const char *args) } free(cp); + sp->flags = flags; + TAILQ_INSERT_TAIL(&spawns, sp, entry); DNPRINTF(SWM_D_SPAWN, "spawn_insert: leave\n"); } @@ -5977,18 +5982,7 @@ spawn_remove(struct spawn_prog *sp) } void -spawn_replace(struct spawn_prog *sp, const char *name, const char *args) -{ - DNPRINTF(SWM_D_SPAWN, "spawn_replace: %s [%s]\n", sp->name, name); - - spawn_remove(sp); - spawn_insert(name, args); - - DNPRINTF(SWM_D_SPAWN, "spawn_replace: leave\n"); -} - -void -setspawn(const char *name, const char *args) +setspawn(const char *name, const char *args, int flags) { struct spawn_prog *sp; @@ -5997,22 +5991,18 @@ setspawn(const char *name, const char *args) if (name == NULL) return; - TAILQ_FOREACH(sp, &spawns, entry) { + /* Remove any old spawn under the same name. */ + TAILQ_FOREACH(sp, &spawns, entry) if (!strcmp(sp->name, name)) { - if (*args == '\0') - spawn_remove(sp); - else - spawn_replace(sp, name, args); - DNPRINTF(SWM_D_SPAWN, "setspawn: leave\n"); - return; + spawn_remove(sp); + break; } - } - if (*args == '\0') { + + if (*args != '\0') + spawn_insert(name, args, flags); + else warnx("error: setspawn: cannot find program: %s", name); - return; - } - spawn_insert(name, args); DNPRINTF(SWM_D_SPAWN, "setspawn: leave\n"); } @@ -6020,25 +6010,12 @@ int setconfspawn(char *selector, char *value, int flags) { char *args; - char which[PATH_MAX]; - size_t i; args = expand_tilde(value); DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args); - /* verify we have the goods */ - snprintf(which, sizeof which, "which %s", value); - for (i = strlen("which "); i < strlen(which); i++) - if (which[i] == ' ') { - which[i] = '\0'; - break; - } - if (flags == 0 && system(which) != 0) - add_startup_exception("could not find %s", - &which[strlen("which ")]); - - setspawn(selector, args); + setspawn(selector, args, flags); free(args); DNPRINTF(SWM_D_SPAWN, "setconfspawn: done.\n"); @@ -6046,16 +6023,57 @@ setconfspawn(char *selector, char *value, int flags) } void +validate_spawns(void) +{ + struct spawn_prog *sp; + char which[PATH_MAX]; + size_t i; + + struct key *kp; + + RB_FOREACH(kp, key_tree, &keys) { + if (kp->funcid != KF_SPAWN_CUSTOM) + continue; + + /* find program */ + TAILQ_FOREACH(sp, &spawns, entry) { + if (!strcasecmp(kp->spawn_name, sp->name)) + break; + } + + if (sp == NULL || sp->flags & SWM_SPAWN_OPTIONAL) + continue; + + /* verify we have the goods */ + snprintf(which, sizeof which, "which %s", sp->argv[0]); + DNPRINTF(SWM_D_CONF, "validate_spawns: which %s\n", + sp->argv[0]); + for (i = strlen("which "); i < strlen(which); i++) + if (which[i] == ' ') { + which[i] = '\0'; + break; + } + if (system(which) != 0) + add_startup_exception("could not find %s", + &which[strlen("which ")]); + } +} + +void setup_spawn(void) { + setconfspawn("lock", "xlock", 0); + setconfspawn("term", "xterm", 0); setconfspawn("spawn_term", "xterm", 0); + setconfspawn("menu", "dmenu_run" " -fn $bar_font" " -nb $bar_color" " -nf $bar_font_color" " -sb $bar_border" " -sf $bar_color", 0); + setconfspawn("search", "dmenu" " -i" " -fn $bar_font" @@ -6063,6 +6081,7 @@ setup_spawn(void) " -nf $bar_font_color" " -sb $bar_border" " -sf $bar_color", 0); + setconfspawn("name_workspace", "dmenu" " -p Workspace" " -fn $bar_font" @@ -6071,11 +6090,10 @@ setup_spawn(void) " -sb $bar_border" " -sf $bar_color", 0); - /* these are not verified for existence */ - setconfspawn("lock", "xlock", 1); - setconfspawn("screenshot_all", "screenshot.sh full", 1); - setconfspawn("screenshot_wind", "screenshot.sh window", 1); - setconfspawn("initscr", "initscreen.sh", 1); + /* These are not verified for existence, even with a binding set. */ + setconfspawn("screenshot_all", "screenshot.sh full", SWM_SPAWN_OPTIONAL); + setconfspawn("screenshot_wind", "screenshot.sh window", SWM_SPAWN_OPTIONAL); + setconfspawn("initscr", "initscreen.sh", SWM_SPAWN_OPTIONAL); } /* key bindings */ @@ -6266,6 +6284,8 @@ setconfbinding(char *selector, char *value, int flags) if (parsekeys(value, mod_key, &mod, &ks) == 0) { setkeybinding(mod, ks, KF_SPAWN_CUSTOM, sp->name); + /* Custom binding; validate spawn. */ + sp->flags ^= SWM_SPAWN_OPTIONAL; return (0); } else return (1); @@ -9348,6 +9368,8 @@ noconfig: if (cfile) conf_load(cfile, SWM_CONF_DEFAULT); + validate_spawns(); + setup_ewmh(); /* set some values to work around bad programs */ workaround();