X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=2ecc60f77162f6fd97c608cac2a15fe4992bff2b;hb=09526664b2bce144ef3cade500a70786a5aeaeff;hp=7a0ccf2b17051dca0f1182a47b362ddfd55c746a;hpb=8ce185e7ff585c29649990f20cc6e69d918cab64;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 7a0ccf2..2ecc60f 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -1304,7 +1304,7 @@ socket_setnonblock(int fd) } void -bar_print(struct swm_region *r, char *s) +bar_print(struct swm_region *r, const char *s) { int x = 0; size_t len; @@ -1381,7 +1381,6 @@ bar_window_name(char *s, size_t sz, struct swm_region *r) if (r->ws->focus->floating) strlcat(s, "(f) ", sz); strlcat(s, (char *)title, sz); - strlcat(s, " ", sz); XFree(title); } @@ -1430,7 +1429,7 @@ bar_workspace_name(char *s, size_t sz, struct swm_region *r) /* build the default bar format according to the defined enabled options */ void -bar_fmt(char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz) +bar_fmt(const char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz) { /* if format provided, just copy the buffers */ if (bar_format != NULL) { @@ -1460,90 +1459,131 @@ bar_fmt(char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz) if (urgent_enabled) strlcat(fmtnew, "* +U* ", sz); - if (title_class_enabled) + if (title_class_enabled) { strlcat(fmtnew, "+C", sz); + if (title_name_enabled == 0) + strlcat(fmtnew, " ", sz); + } + if (title_name_enabled) { /* add a colon if showing the class and something is focused */ if (title_class_enabled && r != NULL && r->ws != NULL && r->ws->focus != NULL) strlcat(fmtnew, ":", sz); - strlcat(fmtnew, "+T", sz); + strlcat(fmtnew, "+T ", sz); } - strlcat(fmtnew, " ", sz); if (window_name_enabled) - strlcat(fmtnew, "+W", sz); + strlcat(fmtnew, "+64W ", sz); /* finally add the action script output and the version */ - strlcat(fmtnew, " +A +V", sz); + strlcat(fmtnew, " +A +V", sz); } /* replaces the bar format character sequences (like in tmux(1)) */ -void -bar_replace(char *fmt, char *fmtrep, int nscreen, struct swm_region *r, +char * +bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep, size_t sz) { char *ptr; - char tmp[SWM_BAR_MAX]; + char num[8], tmp[SWM_BAR_MAX]; + int limit; + size_t len, numoff = 0; + + /* reset strlcat(3) buffer */ + *tmp = '\0'; + + /* get number, if any */ + fmt++; + while (*fmt != '\0' && isdigit((unsigned char) *fmt)) { + if (numoff >= sizeof num - 1) + break; + num[numoff++] = *fmt++; + } + num[numoff] = '\0'; + + if ((limit = strtonum(num, 1, sizeof tmp - 1, NULL)) == 0) + limit = sizeof tmp - 1; + + /* if number is too big, skip to the first non-digit */ + if (numoff >= sizeof num - 1) { + while (*fmt != '\0' && isdigit((unsigned char) *fmt)) + fmt++; + } + /* there is nothing to replace (ie EOL) */ + if (*fmt == '\0') + return (fmt); + + switch (*fmt) { + case 'A': + snprintf(tmp, sizeof tmp, "%s", bar_ext); + break; + case 'C': + bar_class_name(tmp, sizeof tmp, r); + break; + case 'D': + bar_workspace_name(tmp, sizeof tmp, r); + break; + case 'I': + snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1); + break; + case 'N': + snprintf(tmp, sizeof tmp, "%d", r->s->idx + 1); + break; + case 'S': + snprintf(tmp, sizeof tmp, "%s", r->ws->stacker); + break; + case 'T': + bar_title_name(tmp, sizeof tmp, r); + break; + case 'U': + bar_urgent(tmp, sizeof tmp); + break; + case 'V': + snprintf(tmp, sizeof tmp, "%s", bar_vertext); + break; + case 'W': + bar_window_name(tmp, sizeof tmp, r); + break; + default: + /* unknown character sequence; copy as-is */ + snprintf(tmp, sizeof tmp, "+%c", *fmt); + break; + } + + len = strlen(tmp); + ptr = tmp; + if (len < limit) + limit = len; + while (limit-- > 0) { + if (*offrep >= sz - 1) + break; + fmtrep[(*offrep)++] = *ptr++; + } + + fmt++; + return (fmt); +} + +void +bar_replace(char *fmt, char *fmtrep, struct swm_region *r, size_t sz) +{ size_t off; off = 0; - ptr = fmt; - while (*ptr != '\0') { - if (*ptr != '+') { + while (*fmt != '\0') { + if (*fmt != '+') { /* skip ordinary characters */ if (off >= sz - 1) break; - fmtrep[off++] = *ptr++; + fmtrep[off++] = *fmt++; continue; } /* character sequence found; replace it */ - *tmp = '\0'; - - switch (*++ptr) { - case 'A': - snprintf(tmp, sizeof tmp, "%s", bar_ext); - break; - case 'C': - bar_class_name(tmp, sizeof tmp, r); - break; - case 'D': - bar_workspace_name(tmp, sizeof tmp, r); - break; - case 'I': - snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1); + fmt = bar_replace_seq(fmt, fmtrep, r, &off, sz); + if (off >= sz - 1) break; - case 'N': - snprintf(tmp, sizeof tmp, "%d", nscreen + 1); - break; - case 'S': - snprintf(tmp, sizeof tmp, "%s", r->ws->stacker); - break; - case 'T': - bar_title_name(tmp, sizeof tmp, r); - break; - case 'U': - bar_urgent(tmp, sizeof tmp); - break; - case 'V': - snprintf(tmp, sizeof tmp, "%s", bar_vertext); - break; - case 'W': - bar_window_name(tmp, sizeof tmp, r); - break; - default: - /* unknown character sequence; copy as-is */ - snprintf(tmp, sizeof tmp, "+%c", *ptr); - break; - } - - off += snprintf(fmtrep + off, sz - off, "%s", tmp); - if (off >= sz - 1) { - off = sz; - break; - } - ptr++; } fmtrep[off] = '\0'; @@ -1576,7 +1616,8 @@ bar_fmt_expand(char *fmtexp, size_t sz) strlcpy(fmtexp, fmt, sz); /* finally pass the string through strftime(3) */ #ifndef SWM_DENY_CLOCK_FORMAT - len = strftime(fmtexp, sz, fmt, &tm); + if ((len = strftime(fmtexp, sz, fmt, &tm)) == 0) + warnx("format too long"); fmtexp[len] = '\0'; #endif } @@ -1595,7 +1636,7 @@ bar_fmt_print(void) for (i = 0; i < ScreenCount(display); i++) { TAILQ_FOREACH(r, &screens[i].rl, entry) { bar_fmt(fmtexp, fmtnew, r, sizeof fmtnew); - bar_replace(fmtnew, fmtrep, i, r, sizeof fmtrep); + bar_replace(fmtnew, fmtrep, r, sizeof fmtrep); bar_print(r, fmtrep); } } @@ -4533,7 +4574,7 @@ struct key { enum keyfuncid funcid; char *spawn_name; }; -RB_HEAD(key_list, key); +RB_HEAD(key_tree, key); int key_cmp(struct key *kp1, struct key *kp2) @@ -4551,8 +4592,8 @@ key_cmp(struct key *kp1, struct key *kp2) return (0); } -RB_GENERATE_STATIC(key_list, key, entry, key_cmp); -struct key_list keys; +RB_GENERATE(key_tree, key, entry, key_cmp); +struct key_tree keys; /* mouse */ enum { client_click, root_click }; @@ -4576,7 +4617,7 @@ update_modkey(unsigned int mod) struct key *kp; mod_key = mod; - RB_FOREACH(kp, key_list, &keys) + RB_FOREACH(kp, key_tree, &keys) if (kp->mod & ShiftMask) kp->mod = mod | ShiftMask; else @@ -4944,7 +4985,7 @@ key_insert(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name) kp->keysym = ks; kp->funcid = kfid; kp->spawn_name = strdupsafe(spawn_name); - RB_INSERT(key_list, &keys, kp); + RB_INSERT(key_tree, &keys, kp); DNPRINTF(SWM_D_KEY, "key_insert: leave\n"); } @@ -4957,7 +4998,7 @@ key_lookup(unsigned int mod, KeySym ks) kp.keysym = ks; kp.mod = mod; - return (RB_FIND(key_list, &keys, &kp)); + return (RB_FIND(key_tree, &keys, &kp)); } void @@ -4965,7 +5006,7 @@ key_remove(struct key *kp) { DNPRINTF(SWM_D_KEY, "key_remove: %s\n", keyfuncs[kp->funcid].name); - RB_REMOVE(key_list, &keys, kp); + RB_REMOVE(key_tree, &keys, kp); free(kp->spawn_name); free(kp); @@ -5228,7 +5269,7 @@ grabkeys(void) if (TAILQ_EMPTY(&screens[k].rl)) continue; XUngrabKey(display, AnyKey, AnyModifier, screens[k].root); - RB_FOREACH(kp, key_list, &keys) { + RB_FOREACH(kp, key_tree, &keys) { if ((code = XKeysymToKeycode(display, kp->keysym))) for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(display, code,