X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=d2534d94272dff5b98a2630e20a588c04ff368b1;hb=90bd93770a7c82e9620689d74480ee23c6b7314a;hp=65cd807f96f641d626aea4a2551c208f9b39edce;hpb=e3fd7d898fc77484e1616e7d6e957828f3569993;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 65cd807..d2534d9 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -124,6 +124,7 @@ static const char *buildstr = SCROTWM_VERSION; #define SWM_D_SPAWN 0x0800 #define SWM_D_EVENTQ 0x1000 #define SWM_D_CONF 0x2000 +#define SWM_D_BAR 0x4000 u_int32_t swm_debug = 0 | SWM_D_MISC @@ -140,6 +141,7 @@ u_int32_t swm_debug = 0 | SWM_D_SPAWN | SWM_D_EVENTQ | SWM_D_CONF + | SWM_D_BAR ; #else #define DPRINTF(x...) @@ -214,6 +216,7 @@ struct search_window { TAILQ_ENTRY(search_window) entry; int idx; struct ws_win *win; + GC gc; Window indicator; }; TAILQ_HEAD(search_winlist, search_window); @@ -230,16 +233,27 @@ enum { }; /* dialog windows */ -double dialog_ratio = .6; +double dialog_ratio = 0.6; /* status bar */ #define SWM_BAR_MAX (256) #define SWM_BAR_JUSTIFY_LEFT (0) #define SWM_BAR_JUSTIFY_CENTER (1) #define SWM_BAR_JUSTIFY_RIGHT (2) #define SWM_BAR_OFFSET (4) +#define SWM_BAR_FONTS "-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*," \ + "-*-profont-*-*-*-*-*-*-*-*-*-*-*-*," \ + "-*-times-medium-r-*-*-*-*-*-*-*-*-*-*," \ + "-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*" + +#ifdef X_HAVE_UTF8_STRING +#define DRAWSTRING(x...) Xutf8DrawString(x) +#else +#define DRAWSTRING(x...) XmbDrawString(x) +#endif + char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; -char bar_ext[SWM_BAR_MAX]; +unsigned char bar_ext[SWM_BAR_MAX]; char bar_vertext[SWM_BAR_MAX]; int bar_version = 0; sig_atomic_t bar_alarm = 0; @@ -264,12 +278,10 @@ int disable_border = 0; int border_width = 1; int verbose_layout = 0; pid_t bar_pid; -GC bar_gc; -XGCValues bar_gcv; -int bar_fidx = 0; -XFontStruct *bar_fs; -char *bar_fonts[] = { NULL, NULL, NULL, NULL };/* XXX Make fully dynamic */ -char *spawn_term[] = { NULL, NULL }; /* XXX Make fully dynamic */ +XFontSet bar_fs; +XFontSetExtents *bar_fs_extents; +char *bar_fonts; +char *spawn_term[] = { NULL, NULL }; /* XXX fully dynamic */ struct passwd *pwd; #define SWM_MENU_FN (2) @@ -424,6 +436,8 @@ struct swm_screen { unsigned long color; char *name; } c[SWM_S_COLOR_MAX]; + + GC bar_gc; }; struct swm_screen *screens; int num_screens; @@ -535,9 +549,10 @@ struct ewmh_hint { {"_NET_WM_ACTION_CLOSE", None}, }; -void store_float_geom(struct ws_win *, struct swm_region *); -int floating_toggle_win(struct ws_win *); -void spawn_select(struct swm_region *, union arg *, char *, int *); +void store_float_geom(struct ws_win *, struct swm_region *); +int floating_toggle_win(struct ws_win *); +void spawn_select(struct swm_region *, union arg *, char *, int *); +unsigned char *get_win_name(Display *, Window, Atom, Atom, unsigned long *); int get_property(Window id, Atom atom, long count, Atom type, @@ -1249,31 +1264,33 @@ socket_setnonblock(int fd) void bar_print(struct swm_region *r, char *s) { - int textwidth, x = 0; - size_t len; + int x = 0; + size_t len; + XRectangle ibox, lbox; XClearWindow(display, r->bar_window); - XSetForeground(display, bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color); len = strlen(s); - textwidth = XTextWidth(bar_fs, s, len); + XmbTextExtents(bar_fs, s, len, &ibox, &lbox); switch (bar_justify) { case SWM_BAR_JUSTIFY_LEFT: x = SWM_BAR_OFFSET; break; case SWM_BAR_JUSTIFY_CENTER: - x = (WIDTH(r) - textwidth) / 2; + x = (WIDTH(r) - lbox.width) / 2; break; case SWM_BAR_JUSTIFY_RIGHT: - x = WIDTH(r) - textwidth - SWM_BAR_OFFSET; + x = WIDTH(r) - lbox.width - SWM_BAR_OFFSET; break; } if (x < SWM_BAR_OFFSET) x = SWM_BAR_OFFSET; - XDrawString(display, r->bar_window, bar_gc, x, bar_fs->ascent, s, len); + DRAWSTRING(display, r->bar_window, bar_fs, r->s->bar_gc, + x, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - + lbox.y, s, len); } void @@ -1287,7 +1304,7 @@ bar_extra_stop(void) kill(bar_pid, SIGTERM); bar_pid = 0; } - strlcpy(bar_ext, "", sizeof bar_ext); + strlcpy((char *)bar_ext, "", sizeof bar_ext); bar_extra = 0; } @@ -1316,21 +1333,28 @@ bar_class_name(char *s, ssize_t sz, struct ws_win *cur_focus) strlcat(s, " ", sz); } out: - if (xch) + if (xch) { + XFree(xch->res_name); + XFree(xch->res_class); XFree(xch); + } } void bar_window_name(char *s, ssize_t sz, struct ws_win *cur_focus) { - char *title; + unsigned char *title; + unsigned long len; if (window_name_enabled && cur_focus != NULL) { - XFetchName(display, cur_focus->id, &title); - if (title) { + if ((title = get_win_name(display, cur_focus->id, a_netwmname, + a_utf8_string, &len)) != NULL) { + DNPRINTF(SWM_D_BAR, "bar_window_name: title: %s\n", + title); + if (cur_focus->floating) strlcat(s, "(f) ", sz); - strlcat(s, title, sz); + strlcat(s, (char *)title, sz); strlcat(s, " ", sz); XFree(title); } @@ -1385,7 +1409,7 @@ bar_update(void) size_t len; char ws[SWM_BAR_MAX]; char s[SWM_BAR_MAX]; - char cn[SWM_BAR_MAX]; + unsigned char cn[SWM_BAR_MAX]; char loc[SWM_BAR_MAX]; char *b, *stack = ""; @@ -1396,7 +1420,7 @@ bar_update(void) while ((b = fgetln(stdin, &len)) != NULL) if (b && b[len - 1] == '\n') { b[len - 1] = '\0'; - strlcpy(bar_ext, b, sizeof bar_ext); + strlcpy((char *)bar_ext, b, sizeof bar_ext); } if (b == NULL && errno != EAGAIN) { fprintf(stderr, "bar_update: bar_extra failed: " @@ -1404,7 +1428,7 @@ bar_update(void) bar_extra_stop(); } } else - strlcpy(bar_ext, "", sizeof bar_ext); + strlcpy((char *)bar_ext, "", sizeof bar_ext); if (clock_enabled == 0) strlcpy(s, "", sizeof s); @@ -1418,12 +1442,14 @@ bar_update(void) for (i = 0; i < ScreenCount(display); i++) { x = 1; TAILQ_FOREACH(r, &screens[i].rl, entry) { - strlcpy(cn, "", sizeof cn); + strlcpy((char *)cn, "", sizeof cn); strlcpy(ws, "", sizeof ws); if (r && r->ws) { - bar_urgent(cn, sizeof cn); - bar_class_name(cn, sizeof cn, r->ws->focus); - bar_window_name(cn, sizeof cn, r->ws->focus); + bar_urgent((char *)cn, sizeof cn); + bar_class_name((char *)cn, sizeof cn, + r->ws->focus); + bar_window_name((char *)cn, sizeof cn, + r->ws->focus); if (r->ws->name) snprintf(ws, sizeof ws, "<%s>", r->ws->name); @@ -1452,7 +1478,7 @@ bar_toggle(struct swm_region *r, union arg *args) struct swm_region *tmpr; int i, sc = ScreenCount(display); - DNPRINTF(SWM_D_MISC, "bar_toggle\n"); + DNPRINTF(SWM_D_BAR, "bar_toggle\n"); if (bar_enabled) for (i = 0; i < sc; i++) @@ -1522,27 +1548,48 @@ bar_refresh(void) void bar_setup(struct swm_region *r) { + char *default_string; + char **missing_charsets; + int num_missing_charsets = 0; int i, x, y; if (bar_fs) { - XFreeFont(display, bar_fs); + XFreeFontSet(display, bar_fs); bar_fs = NULL; } - for (i = 0; bar_fonts[i] != NULL; i++) { - bar_fs = XLoadQueryFont(display, bar_fonts[i]); - if (bar_fs) { - bar_fidx = i; - break; - } + + DNPRINTF(SWM_D_BAR, "bar_setup: loading bar_fonts: %s\n", bar_fonts); + + bar_fs = XCreateFontSet(display, bar_fonts, &missing_charsets, + &num_missing_charsets, &default_string); + + if (num_missing_charsets > 0) { + warnx("Unable to load charset(s):"); + + for (i = 0; i < num_missing_charsets; ++i) + warnx("%s", missing_charsets[i]); + + XFreeStringList(missing_charsets); + + if (strcmp(default_string, "")) + warnx("Glyphs from those sets will be replaced " + "by '%s'.", default_string); + else + warnx("Glyphs from those sets won't be drawn."); } - if (bar_fonts[i] == NULL) - errx(1, "couldn't load font"); + if (bar_fs == NULL) - errx(1, "couldn't create font structure"); + errx(1, "Error creating font set structure."); + + bar_fs_extents = XExtentsOfFontSet(bar_fs); - bar_height = bar_fs->ascent + bar_fs->descent + 1 + + bar_height = bar_fs_extents->max_logical_extent.height + 2 * bar_border_width; + + if (bar_height < 1) + bar_height = 1; + x = X(r); y = bar_at_bottom ? (Y(r) + HEIGHT(r) - bar_height) : Y(r); @@ -1551,12 +1598,10 @@ bar_setup(struct swm_region *r) bar_height - 2 * bar_border_width, bar_border_width, r->s->c[SWM_S_COLOR_BAR_BORDER].color, r->s->c[SWM_S_COLOR_BAR].color); - bar_gc = XCreateGC(display, r->bar_window, 0, &bar_gcv); - XSetFont(display, bar_gc, bar_fs->fid); XSelectInput(display, r->bar_window, VisibilityChangeMask); if (bar_enabled) XMapRaised(display, r->bar_window); - DNPRINTF(SWM_D_MISC, "bar_setup: bar_window: 0x%lx\n", r->bar_window); + DNPRINTF(SWM_D_BAR, "bar_setup: bar_window: 0x%lx\n", r->bar_window); if (signal(SIGALRM, bar_signal) == SIG_ERR) err(1, "could not install bar_signal"); @@ -1643,33 +1688,31 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) if (win == NULL) return; + /* send notification of unchanged state. */ + ce.type = ConfigureNotify; + ce.x = X(win); + ce.y = Y(win); + ce.width = WIDTH(win); + ce.height = HEIGHT(win); + ce.override_redirect = False; if (ev == NULL) { /* EWMH */ - ce.type = ConfigureNotify; ce.display = display; ce.event = win->id; ce.window = win->id; - ce.x = X(win); - ce.y = Y(win); - ce.width = WIDTH(win); - ce.height = HEIGHT(win); ce.border_width = border_width; ce.above = None; - ce.override_redirect = False; } else { /* normal */ - ce.type = ConfigureNotify; ce.display = ev->display; ce.event = ev->window; ce.window = ev->window; - ce.x = ev->x; - ce.y = ev->y; - ce.width = ev->width; - ce.height = ev->height; + /* adjust x and y for requested border_width. */ + ce.x += border_width - ev->border_width; + ce.y += border_width - ev->border_width; ce.border_width = ev->border_width; ce.above = ev->above; - ce.override_redirect = False; } DNPRINTF(SWM_D_MISC, "config_win: ewmh: %s, window: 0x%lx, (x,y) w x h: " @@ -3363,6 +3406,7 @@ search_win_cleanup(void) while ((sw = TAILQ_FIRST(&search_wl)) != NULL) { XDestroyWindow(display, sw->indicator); + XFreeGC(display, sw->gc); TAILQ_REMOVE(&search_wl, sw, entry); free(sw); } @@ -3374,13 +3418,12 @@ search_win(struct swm_region *r, union arg *args) struct ws_win *win = NULL; struct search_window *sw = NULL; Window w; - GC gc; XGCValues gcv; int i; char s[8]; FILE *lfile; size_t len; - int textwidth; + XRectangle ibox, lbox; DNPRINTF(SWM_D_MISC, "search_win\n"); @@ -3412,23 +3455,25 @@ search_win(struct swm_region *r, union arg *args) snprintf(s, sizeof s, "%d", i); len = strlen(s); - textwidth = XTextWidth(bar_fs, s, len); + + XmbTextExtents(bar_fs, s, len, &ibox, &lbox); w = XCreateSimpleWindow(display, - win->id, 0, 0, textwidth + 12, - bar_fs->ascent + bar_fs->descent + 4, 1, + win->id, 0, 0,lbox.width + 4, + bar_fs_extents->max_logical_extent.height, 1, r->s->c[SWM_S_COLOR_UNFOCUS].color, r->s->c[SWM_S_COLOR_FOCUS].color); sw->indicator = w; TAILQ_INSERT_TAIL(&search_wl, sw, entry); - gc = XCreateGC(display, w, 0, &gcv); - XSetFont(display, gc, bar_fs->fid); + sw->gc = XCreateGC(display, w, 0, &gcv); XMapRaised(display, w); - XSetForeground(display, gc, r->s->c[SWM_S_COLOR_BAR].color); + XSetForeground(display, sw->gc, r->s->c[SWM_S_COLOR_BAR].color); - XDrawString(display, w, gc, 6, bar_fs->ascent + 2, s, len); + DRAWSTRING(display, w, bar_fs, sw->gc, 2, + (bar_fs_extents->max_logical_extent.height - + lbox.height) / 2 - lbox.y, s, len); fprintf(lfile, "%d\n", i); i++; @@ -4228,13 +4273,14 @@ struct keyfunc { { "invalid key func", NULL, {0} }, }; struct key { + TAILQ_ENTRY(key) entry; unsigned int mod; KeySym keysym; enum keyfuncid funcid; char *spawn_name; }; -int keys_size = 0, keys_length = 0; -struct key *keys = NULL; +TAILQ_HEAD(key_list, key); +struct key_list keys = TAILQ_HEAD_INITIALIZER(keys); /* mouse */ enum { client_click, root_click }; @@ -4255,13 +4301,14 @@ void update_modkey(unsigned int mod) { int i; + struct key *kp; mod_key = mod; - for (i = 0; i < keys_length; i++) - if (keys[i].mod & ShiftMask) - keys[i].mod = mod | ShiftMask; + TAILQ_FOREACH(kp, &keys, entry) + if (kp->mod & ShiftMask) + kp->mod = mod | ShiftMask; else - keys[i].mod = mod; + kp->mod = mod; for (i = 0; i < LENGTH(buttons); i++) if (buttons[i].mask & ShiftMask) @@ -4320,7 +4367,7 @@ spawn_expand(struct swm_region *r, union arg *args, char *spawn_name, == NULL) err(1, "spawn_custom bar color"); } else if (!strcasecmp(ap, "$bar_font")) { - if ((real_args[i] = strdup(bar_fonts[bar_fidx])) + if ((real_args[i] = strdup(bar_fonts)) == NULL) err(1, "spawn_custom bar fonts"); } else if (!strcasecmp(ap, "$bar_font_color")) { @@ -4633,84 +4680,76 @@ strdupsafe(char *str) } void +key_insert(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name) +{ + struct key *kp; + + DNPRINTF(SWM_D_KEY, "key_insert: enter %s [%s]\n", + keyfuncs[kfid].name, spawn_name); + + if ((kp = malloc(sizeof *kp)) == NULL) + err(1, "key_insert: malloc"); + + kp->mod = mod; + kp->keysym = ks; + kp->funcid = kfid; + kp->spawn_name = strdupsafe(spawn_name); + TAILQ_INSERT_TAIL(&keys, kp, entry); + + DNPRINTF(SWM_D_KEY, "key_insert: leave\n"); +} + +void +key_remove(struct key *kp) +{ + DNPRINTF(SWM_D_KEY, "key_remove: %s\n", keyfuncs[kp->funcid].name); + + TAILQ_REMOVE(&keys, kp, entry); + free(kp->spawn_name); + free(kp); + + DNPRINTF(SWM_D_KEY, "key_remove: leave\n"); +} + +void +key_replace(struct key *kp, unsigned int mod, KeySym ks, enum keyfuncid kfid, + char *spawn_name) +{ + DNPRINTF(SWM_D_KEY, "key_replace: %s [%s]\n", keyfuncs[kp->funcid].name, + spawn_name); + + key_remove(kp); + key_insert(mod, ks, kfid, spawn_name); + + DNPRINTF(SWM_D_KEY, "key_replace: leave\n"); +} + +void setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name) { - int i, j; + struct key *kp; + DNPRINTF(SWM_D_KEY, "setkeybinding: enter %s [%s]\n", keyfuncs[kfid].name, spawn_name); - /* find existing */ - for (i = 0; i < keys_length; i++) { - if (keys[i].mod == mod && keys[i].keysym == ks) { - if (kfid == kf_invalid) { - /* found: delete */ - DNPRINTF(SWM_D_KEY, - "setkeybinding: delete #%d %s\n", - i, keyfuncs[keys[i].funcid].name); - free(keys[i].spawn_name); - j = keys_length - 1; - if (i < j) - keys[i] = keys[j]; - keys_length--; - DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); - return; - } else { - /* found: replace */ - DNPRINTF(SWM_D_KEY, - "setkeybinding: replace #%d %s [%s]\n", - i, keyfuncs[keys[i].funcid].name, - spawn_name); - free(keys[i].spawn_name); - keys[i].mod = mod; - keys[i].keysym = ks; - keys[i].funcid = kfid; - keys[i].spawn_name = strdupsafe(spawn_name); - DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); - return; - } + + TAILQ_FOREACH(kp, &keys, entry) { + if (kp->mod == mod && kp->keysym == ks) { + if (kfid == kf_invalid) + key_remove(kp); + else + key_replace(kp, mod, ks, kfid, spawn_name); + DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); + return; } } if (kfid == kf_invalid) { - fprintf(stderr, - "error: setkeybinding: cannot find mod/key combination"); + warnx("error: setkeybinding: cannot find mod/key combination"); DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); return; } - /* not found: add */ - if (keys_size == 0 || keys == NULL) { - keys_size = 4; - DNPRINTF(SWM_D_KEY, "setkeybinding: init list %d\n", keys_size); - keys = malloc((size_t)keys_size * sizeof(struct key)); - if (keys == NULL) { - fprintf(stderr, "malloc failed\n"); - perror(" failed"); - quit(NULL, NULL); - } - } else if (keys_length == keys_size) { - keys_size *= 2; - DNPRINTF(SWM_D_KEY, "setkeybinding: grow list %d\n", keys_size); - keys = realloc(keys, (size_t)keys_size * sizeof(struct key)); - if (keys == NULL) { - fprintf(stderr, "realloc failed\n"); - perror(" failed"); - quit(NULL, NULL); - } - } - if (keys_length < keys_size) { - j = keys_length++; - DNPRINTF(SWM_D_KEY, "setkeybinding: add #%d %s [%s]\n", - j, keyfuncs[kfid].name, spawn_name); - keys[j].mod = mod; - keys[j].keysym = ks; - keys[j].funcid = kfid; - keys[j].spawn_name = strdupsafe(spawn_name); - } else { - fprintf(stderr, "keys array problem?\n"); - if (keys == NULL) { - fprintf(stderr, "keys array problem\n"); - quit(NULL, NULL); - } - } + + key_insert(mod, ks, kfid, spawn_name); DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); } @@ -4843,12 +4882,14 @@ setup_keys(void) void clear_keys(void) { - int i; + struct key *kp_loop, *kp_next; - /* clear all key bindings, if any */ - for (i = 0; i < keys_length; i++) - free(keys[i].spawn_name); - keys_length = 0; + kp_loop = TAILQ_FIRST(&keys); + while (kp_loop != NULL) { + kp_next = TAILQ_NEXT(kp_loop, entry); + key_remove(kp_loop); + kp_loop = kp_next; + } } int @@ -4892,10 +4933,11 @@ updatenumlockmask(void) void grabkeys(void) { - unsigned int i, j, k; + unsigned int j, k; KeyCode code; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; + struct key *kp; DNPRINTF(SWM_D_MISC, "grabkeys\n"); updatenumlockmask(); @@ -4904,11 +4946,11 @@ grabkeys(void) if (TAILQ_EMPTY(&screens[k].rl)) continue; XUngrabKey(display, AnyKey, AnyModifier, screens[k].root); - for (i = 0; i < keys_length; i++) { - if ((code = XKeysymToKeycode(display, keys[i].keysym))) + TAILQ_FOREACH(kp, &keys, entry) { + if ((code = XKeysymToKeycode(display, kp->keysym))) for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(display, code, - keys[i].mod | modifiers[j], + kp->mod | modifiers[j], screens[k].root, True, GrabModeAsync, GrabModeAsync); } @@ -5115,6 +5157,7 @@ int setconfvalue(char *selector, char *value, int flags) { int i; + char *b; switch (flags) { case SWM_S_BAR_DELAY: @@ -5193,9 +5236,12 @@ setconfvalue(char *selector, char *value, int flags) border_width = atoi(value); break; case SWM_S_BAR_FONT: - free(bar_fonts[0]); - if ((bar_fonts[0] = strdup(value)) == NULL) - err(1, "setconfvalue: bar_font"); + b = bar_fonts; + if (asprintf(&bar_fonts, "%s,%s", value, bar_fonts) == -1) + err(1, "setconfvalue: asprintf: failed to allocate " + "memory for bar_fonts."); + + free(b); break; case SWM_S_BAR_ACTION: free(bar_argv[0]); @@ -5548,6 +5594,7 @@ conf_load(char *filename, int keymapping) out: free(line); fclose(config); + DNPRINTF(SWM_D_CONF, "conf_load: end with error.\n"); return (1); } @@ -5907,6 +5954,8 @@ unmanage_window(struct ws_win *win) focus_prev(win); + XFree(win->hints); + TAILQ_REMOVE(&win->ws->winlist, win, entry); TAILQ_INSERT_TAIL(&win->ws->unmanagedlist, win, entry); @@ -5957,25 +6006,25 @@ expose(XEvent *e) void keypress(XEvent *e) { - unsigned int i; KeySym keysym; XKeyEvent *ev = &e->xkey; + struct key *kp; keysym = XKeycodeToKeysym(display, (KeyCode)ev->keycode, 0); - for (i = 0; i < keys_length; i++) - if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keyfuncs[keys[i].funcid].func) { - if (keys[i].funcid == kf_spawn_custom) + TAILQ_FOREACH(kp, &keys, entry) + if (keysym == kp->keysym + && CLEANMASK(kp->mod) == CLEANMASK(ev->state) + && keyfuncs[kp->funcid].func) { + if (kp->funcid == kf_spawn_custom) spawn_custom( root_to_region(ev->root), - &(keyfuncs[keys[i].funcid].args), - keys[i].spawn_name + &(keyfuncs[kp->funcid].args), + kp->spawn_name ); else - keyfuncs[keys[i].funcid].func( + keyfuncs[kp->funcid].func( root_to_region(ev->root), - &(keyfuncs[keys[i].funcid].args) + &(keyfuncs[kp->funcid].args) ); } } @@ -6295,9 +6344,13 @@ propertynotify(XEvent *e) { struct ws_win *win; XPropertyEvent *ev = &e->xproperty; - +#ifdef SWM_DEBUG + char *name; + name = XGetAtomName(display, ev->atom); DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%lx, atom: %s\n", - ev->window, XGetAtomName(display, ev->atom)); + ev->window, name); + XFree(name); +#endif win = find_window(ev->window); if (win == NULL) @@ -6694,6 +6747,7 @@ setup_screens(void) int i, j, k; int errorbase, major, minor; struct workspace *ws; + XGCValues gcv; if ((screens = calloc(ScreenCount(display), sizeof(struct swm_screen))) == NULL) @@ -6722,6 +6776,13 @@ setup_screens(void) setscreencolor("black", i + 1, SWM_S_COLOR_BAR); setscreencolor("rgb:a0/a0/a0", i + 1, SWM_S_COLOR_BAR_FONT); + /* create graphics context on screen with default font color */ + screens[i].bar_gc = XCreateGC(display, screens[i].root, 0, + &gcv); + + XSetForeground(display, screens[i].bar_gc, + screens[i].c[SWM_S_COLOR_BAR_FONT].color); + /* set default cursor */ XDefineCursor(display, screens[i].root, XCreateFontCursor(display, XC_left_ptr)); @@ -6757,19 +6818,14 @@ setup_screens(void) void setup_globals(void) { - if ((bar_fonts[0] = strdup("-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*")) - == NULL) - err(1, "setup_globals: strdup"); - if ((bar_fonts[1] = strdup("-*-times-medium-r-*-*-*-*-*-*-*-*-*-*")) - == NULL) - err(1, "setup_globals: strdup"); - if ((bar_fonts[2] = strdup("-misc-fixed-medium-r-*-*-*-*-*-*-*-*-*-*")) - == NULL) - err(1, "setup_globals: strdup"); + if ((bar_fonts = strdup(SWM_BAR_FONTS)) == NULL) + err(1, "setup_globals: strdup: failed to allocate memory."); + if ((spawn_term[0] = strdup("xterm")) == NULL) - err(1, "setup_globals: strdup"); + err(1, "setup_globals: strdup: failed to allocate memory."); + if ((clock_format = strdup("%a %b %d %R %Z %Y")) == NULL) - err(1, "strdup"); + err(1, "setup_globals: strdup: failed to allocate memory."); } void @@ -6819,6 +6875,9 @@ main(int argc, char *argv[]) !XSupportsLocale()) warnx("no locale support"); + if (!X_HAVE_UTF8_STRING) + warnx("no UTF-8 support"); + if (!(display = XOpenDisplay(0))) errx(1, "can not open display"); @@ -6854,8 +6913,8 @@ main(int argc, char *argv[]) if (pwd == NULL) errx(1, "invalid user: %d", getuid()); - setup_screens(); setup_globals(); + setup_screens(); setup_keys(); setup_quirks(); setup_spawn(); @@ -6872,8 +6931,12 @@ main(int argc, char *argv[]) if (S_ISREG(sb.st_mode)) cfile = conf; } - if (cfile) - conf_load(cfile, SWM_CONF_DEFAULT); + + /* load conf (if any) and refresh font color in bar graphics contexts */ + if (cfile && conf_load(cfile, SWM_CONF_DEFAULT) == 0) + for (i = 0; i < ScreenCount(display); ++i) + XSetForeground(display, screens[i].bar_gc, + screens[i].c[SWM_S_COLOR_BAR_FONT].color); setup_ewmh(); /* set some values to work around bad programs */ @@ -6970,7 +7033,12 @@ main(int argc, char *argv[]) done: teardown_ewmh(); bar_extra_stop(); - XFreeGC(display, bar_gc); + + for (i = 0; i < ScreenCount(display); ++i) + if (screens[i].bar_gc != NULL) + XFreeGC(display, screens[i].bar_gc); + + XFreeFontSet(display, bar_fs); XCloseDisplay(display); return (0);