X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=251b74643acc18cc60a27e010187534b8190ec91;hb=844157986de0e1fb9a50c7674eaae527eec23349;hp=0335ffa58c1c858111174caeba59da875e04f40f;hpb=75649b6a4b4c9349764c5655c6421e593117a95f;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 0335ffa..251b746 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -870,6 +870,7 @@ RB_HEAD(key_tree, key); /* function prototypes */ void adjust_font(struct ws_win *); +char *argsep(char **); void bar_cleanup(struct swm_region *); void bar_extra_setup(void); void bar_extra_stop(void); @@ -6255,24 +6256,73 @@ spawn_select(struct swm_region *r, union arg *args, const char *spawn_name, free(real_args); } +/* Argument tokenizer. */ +char * +argsep(char **sp) { + int single_quoted = 0, double_quoted = 0; + char *arg, *cp, *next; + + if (*sp == NULL) + return NULL; + + /* Eat and move characters until end of argument is found. */ + for (arg = next = cp = *sp; *cp != '\0'; ++cp) { + if (!double_quoted && *cp == '\'') { + /* Eat single-quote. */ + single_quoted = !single_quoted; + } else if (!single_quoted && *cp == '"') { + /* Eat double-quote. */ + double_quoted = !double_quoted; + } else if (!single_quoted && *cp == '\\' && *(cp + 1) == '"') { + /* Eat backslash; copy escaped character to arg. */ + *next++ = *(++cp); + } else if (!single_quoted && !double_quoted && *cp == '\\' && + (*(cp + 1) == '\'' || *(cp + 1) == ' ')) { + /* Eat backslash; move escaped character. */ + *next++ = *(++cp); + } else if (!single_quoted && !double_quoted && + (*cp == ' ' || *cp == '\t')) { + /* Terminate argument. */ + *next++ = '\0'; + /* Point sp to beginning of next argument. */ + *sp = ++cp; + break; + } else { + /* Move regular character. */ + *next++ = *cp; + } + } + + /* Terminate argument if end of string. */ + if (*cp == '\0') { + *next = '\0'; + *sp = NULL; + } + + return arg; +} + void spawn_insert(const char *name, const char *args, int flags) { - char *arg, *cp, *ptr; struct spawn_prog *sp; + char *arg, *dup, *ptr; - DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s\n", name); + DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s[%s]\n", name, args); + + if (args == NULL || *args == '\0') + return; if ((sp = calloc(1, sizeof *sp)) == NULL) err(1, "spawn_insert: calloc"); if ((sp->name = strdup(name)) == NULL) err(1, "spawn_insert: strdup"); - /* convert the arguments to an argument list */ - if ((ptr = cp = strdup(args)) == NULL) + /* Convert the arguments to an argument list. */ + if ((ptr = dup = strdup(args)) == NULL) err(1, "spawn_insert: strdup"); - while ((arg = strsep(&ptr, " \t")) != NULL) { - /* empty field; skip it */ + while ((arg = argsep(&ptr)) != NULL) { + /* Null argument; skip it. */ if (*arg == '\0') continue; @@ -6283,10 +6333,11 @@ spawn_insert(const char *name, const char *args, int flags) if ((sp->argv[sp->argc - 1] = strdup(arg)) == NULL) err(1, "spawn_insert: strdup"); } - free(cp); + free(dup); sp->flags = flags; + DNPRINTF(SWM_D_SPAWN, "arg %d: [%s]\n", sp->argc, sp->argv[sp->argc-1]); TAILQ_INSERT_TAIL(&spawns, sp, entry); DNPRINTF(SWM_D_SPAWN, "spawn_insert: leave\n"); } @@ -6347,6 +6398,9 @@ setconfspawn(const char *selector, const char *value, int flags) { char *args; + if (selector == NULL || strlen(selector) == 0) + return (1); + args = expand_tilde(value); DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args); @@ -6595,8 +6649,9 @@ setconfbinding(const char *selector, const char *value, int flags) /* suppress unused warning since var is needed */ (void)flags; - DNPRINTF(SWM_D_KEY, "setconfbinding: enter\n"); - if (selector == NULL) { + DNPRINTF(SWM_D_KEY, "setconfbinding: enter selector: [%s], " + "value: [%s]\n", selector, value); + if (selector == NULL || strlen(selector) == 0) { DNPRINTF(SWM_D_KEY, "setconfbinding: unbind %s\n", value); if (parsekeys(value, mod_key, &mod, &ks) == 0) { kfid = KF_INVALID; @@ -6818,9 +6873,11 @@ updatenumlockmask(void) + j]; keycode = xcb_key_symbols_get_keycode(syms, XK_Num_Lock); - if (kc == *keycode) - numlockmask = (1 << i); - free(keycode); + if (keycode) { + if (kc == *keycode) + numlockmask = (1 << i); + free(keycode); + } } } free(modmap_r); @@ -7111,7 +7168,7 @@ setconfquirk(const char *selector, const char *value, int flags) /* suppress unused warning since var is needed */ (void)flags; - if (selector == NULL) + if (selector == NULL || strlen(selector) == 0) return (0); if ((str = strdup(selector)) == NULL) @@ -7159,19 +7216,19 @@ setconfquirk(const char *selector, const char *value, int flags) void setup_quirks(void) { - setquirk("MPlayer", "xv", "", SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV); - setquirk("OpenOffice.org 3.2", "VCLSalFrame", "", SWM_Q_FLOAT); - setquirk("Firefox-bin", "firefox-bin", "", SWM_Q_TRANSSZ); - setquirk("Firefox", "Dialog", "", SWM_Q_FLOAT); - setquirk("Gimp", "gimp", "", SWM_Q_FLOAT | SWM_Q_ANYWHERE); - setquirk("XTerm", "xterm", "", SWM_Q_XTERM_FONTADJ); - setquirk("xine", "Xine Window", "", SWM_Q_FLOAT | SWM_Q_ANYWHERE); - setquirk("Xitk", "Xitk Combo", "", SWM_Q_FLOAT | SWM_Q_ANYWHERE); - setquirk("xine", "xine Panel", "", SWM_Q_FLOAT | SWM_Q_ANYWHERE); - setquirk("Xitk", "Xine Window", "", SWM_Q_FLOAT | SWM_Q_ANYWHERE); - setquirk("xine", "xine Video Fullscreen Window", "", SWM_Q_FULLSCREEN | SWM_Q_FLOAT); - setquirk("pcb", "pcb", "", SWM_Q_FLOAT); - setquirk("SDL_App", "SDL_App", "", SWM_Q_FLOAT | SWM_Q_FULLSCREEN); + setquirk("MPlayer", "xv", ".*", SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV); + setquirk("OpenOffice.org 3.2", "VCLSalFrame", ".*", SWM_Q_FLOAT); + setquirk("Firefox-bin", "firefox-bin", ".*", SWM_Q_TRANSSZ); + setquirk("Firefox", "Dialog", ".*", SWM_Q_FLOAT); + setquirk("Gimp", "gimp", ".*", SWM_Q_FLOAT | SWM_Q_ANYWHERE); + setquirk("XTerm", "xterm", ".*", SWM_Q_XTERM_FONTADJ); + setquirk("xine", "Xine Window", ".*", SWM_Q_FLOAT | SWM_Q_ANYWHERE); + setquirk("Xitk", "Xitk Combo", ".*", SWM_Q_FLOAT | SWM_Q_ANYWHERE); + setquirk("xine", "xine Panel", ".*", SWM_Q_FLOAT | SWM_Q_ANYWHERE); + setquirk("Xitk", "Xine Window", ".*", SWM_Q_FLOAT | SWM_Q_ANYWHERE); + setquirk("xine", "xine Video Fullscreen Window", ".*", SWM_Q_FULLSCREEN | SWM_Q_FLOAT); + setquirk("pcb", "pcb", ".*", SWM_Q_FLOAT); + setquirk("SDL_App", "SDL_App", ".*", SWM_Q_FLOAT | SWM_Q_FULLSCREEN); } /* conf file stuff */ @@ -7224,9 +7281,6 @@ setconfvalue(const char *selector, const char *value, int flags) int i, ws_id, num_screens; char *b, *str; - /* suppress unused warning since var is needed */ - (void)selector; - switch (flags) { case SWM_S_BAR_ACTION: free(bar_argv[0]); @@ -7466,7 +7520,9 @@ setconfmodkey(const char *selector, const char *value, int flags) int setconfcolor(const char *selector, const char *value, int flags) { - setscreencolor(value, ((selector == NULL)?-1:atoi(selector)), flags); + setscreencolor(value, + (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector), + flags); return (0); } @@ -8771,10 +8827,22 @@ mapnotify(xcb_map_notify_event_t *e) void mappingnotify(xcb_mapping_notify_event_t *e) { + struct ws_win *w; + int i, j, num_screens; + xcb_refresh_keyboard_mapping(syms, e); - if (e->request == XCB_MAPPING_KEYBOARD) + if (e->request == XCB_MAPPING_KEYBOARD) { grabkeys(); + + /* Regrab buttons on all managed windows. */ + num_screens = get_screen_count(); + for (i = 0; i < num_screens; i++) + for (j = 0; j < workspace_limit; j++) + TAILQ_FOREACH(w, &screens[i].ws[j].winlist, + entry) + grabbuttons(w); + } } void @@ -8960,6 +9028,10 @@ propertynotify(xcb_property_notify_event_t *e) focus_flush(); } } else if (e->state == XCB_PROPERTY_DELETE) { + /* Reload floating geometry in case region changed. */ + if (win->floating) + load_float_geom(win); + /* The window is no longer iconic, restack ws. */ if (focus_mode != SWM_FOCUS_FOLLOW) ws->focus_pending = get_focus_magic(win);