X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=dfbdefc2d88788e055ab9583daf7d47033866aed;hb=1c354dfac092c948cee6aa0c04ec13380e15a8bb;hp=f03445bb64c89c5a163689ab47089f445e6716a8;hpb=f31159407e2b8ceebfed9330fdf36db5d9ab54d0;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index f03445b..dfbdefc 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -1,4 +1,3 @@ -/* $scrotwm$ */ /* * Copyright (c) 2009-2010-2011 Marco Peereboom * Copyright (c) 2009-2010-2011 Ryan McBride @@ -52,11 +51,6 @@ * DEALINGS IN THE SOFTWARE. */ -static const char *cvstag = - "$scrotwm$"; - -#define SWM_VERSION "0.9.34" - #include #include #include @@ -93,6 +87,14 @@ static const char *cvstag = #include #endif +#include "version.h" + +#ifdef SCROTWM_BUILDSTR +static const char *buildstr = SCROTWM_BUILDSTR; +#else +static const char *buildstr = SCROTWM_VERSION; +#endif + #if RANDR_MAJOR < 1 # error XRandR versions less than 1.0 are not supported #endif @@ -163,6 +165,9 @@ u_int32_t swm_debug = 0 #define SWM_FOCUS_SYNERGY (1) #define SWM_FOCUS_FOLLOW (2) +#define SWM_CONF_DEFAULT (0) +#define SWM_CONF_KEYMAPPING (1) + #ifndef SWM_LIB #define SWM_LIB "/usr/local/lib/libswmhack.so" #endif @@ -204,7 +209,11 @@ volatile sig_atomic_t search_resp; /* dialog windows */ double dialog_ratio = .6; /* status bar */ -#define SWM_BAR_MAX (256) +#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) char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; char bar_ext[SWM_BAR_MAX]; @@ -219,6 +228,7 @@ int bar_extra = 1; int bar_extra_running = 0; int bar_verbose = 1; int bar_height = 0; +int bar_justify = SWM_BAR_JUSTIFY_LEFT; int stack_enabled = 1; int clock_enabled = 1; int urgent_enabled = 0; @@ -237,6 +247,7 @@ 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 */ +struct passwd *pwd; #define SWM_MENU_FN (2) #define SWM_MENU_NB (4) @@ -322,6 +333,8 @@ void new_region(struct swm_screen *, int, int, int, int); void unmanage_window(struct ws_win *); long getstate(Window); +int conf_load(char *, int); + struct layout { void (*l_stack)(struct workspace *, struct swm_geometry *); void (*l_config)(struct workspace *, int); @@ -412,6 +425,8 @@ union arg { #define SWM_ARG_ID_CYCLEWS_DOWN (41) #define SWM_ARG_ID_CYCLESC_UP (42) #define SWM_ARG_ID_CYCLESC_DOWN (43) +#define SWM_ARG_ID_CYCLEWS_UP_ALL (44) +#define SWM_ARG_ID_CYCLEWS_DOWN_ALL (45) #define SWM_ARG_ID_STACKINC (50) #define SWM_ARG_ID_STACKDEC (51) #define SWM_ARG_ID_SS_ALL (60) @@ -1139,7 +1154,7 @@ setscreencolor(char *val, int i, int c) void fancy_stacker(struct workspace *ws) { - strcpy(ws->stacker, "[ ]"); + strlcpy(ws->stacker, "[ ]", sizeof ws->stacker); if (ws->cur_layout->l_stack == vertical_stack) snprintf(ws->stacker, sizeof ws->stacker, "[%d|%d]", ws->l_state.vertical_mwin, ws->l_state.vertical_stacks); @@ -1151,11 +1166,11 @@ fancy_stacker(struct workspace *ws) void plain_stacker(struct workspace *ws) { - strcpy(ws->stacker, "[ ]"); + strlcpy(ws->stacker, "[ ]", sizeof ws->stacker); if (ws->cur_layout->l_stack == vertical_stack) - strcpy(ws->stacker, "[|]"); + strlcpy(ws->stacker, "[|]", sizeof ws->stacker); if (ws->cur_layout->l_stack == horizontal_stack) - strcpy(ws->stacker, "[-]"); + strlcpy(ws->stacker, "[-]", sizeof ws->stacker); } void @@ -1203,10 +1218,31 @@ socket_setnonblock(int fd) void bar_print(struct swm_region *r, char *s) { + int textwidth, x; + size_t len; + XClearWindow(display, r->bar_window); XSetForeground(display, bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color); - XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, s, - strlen(s)); + + len = strlen(s); + textwidth = XTextWidth(bar_fs, s, len); + + switch (bar_justify) { + case SWM_BAR_JUSTIFY_LEFT: + x = SWM_BAR_OFFSET; + break; + case SWM_BAR_JUSTIFY_CENTER: + x = (WIDTH(r) - textwidth) / 2; + break; + case SWM_BAR_JUSTIFY_RIGHT: + x = WIDTH(r) - textwidth - 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); } void @@ -1319,7 +1355,7 @@ bar_update(void) char s[SWM_BAR_MAX]; char cn[SWM_BAR_MAX]; char loc[SWM_BAR_MAX]; - char *b; + char *b, *stack = ""; if (bar_enabled == 0) return; @@ -1356,10 +1392,11 @@ bar_update(void) bar_class_name(cn, sizeof cn, r->ws->focus); bar_window_name(cn, sizeof cn, r->ws->focus); } + if (stack_enabled) + stack = r->ws->stacker; snprintf(loc, sizeof loc, "%d:%d %s %s%s %s %s", - x++, r->ws->idx + 1, r->ws->stacker, s, cn, bar_ext, - bar_vertext); + x++, r->ws->idx + 1, stack, s, cn, bar_ext, bar_vertext); bar_print(r, loc); } } @@ -1535,8 +1572,8 @@ version(struct swm_region *r, union arg *args) { bar_version = !bar_version; if (bar_version) - snprintf(bar_vertext, sizeof bar_vertext, "Version: %s CVS: %s", - SWM_VERSION, cvstag); + snprintf(bar_vertext, sizeof bar_vertext, "Version: %s Build: %s", + SCROTWM_VERSION, buildstr); else strlcpy(bar_vertext, "", sizeof bar_vertext); bar_update(); @@ -2110,6 +2147,7 @@ cyclews(struct swm_region *r, union arg *args) { union arg a; struct swm_screen *s = r->s; + int cycle_all = 0; DNPRINTF(SWM_D_WS, "cyclews id %d " "in screen[%d]:%dx%d+%d+%d ws %d\n", args->id, @@ -2118,12 +2156,18 @@ cyclews(struct swm_region *r, union arg *args) a.id = r->ws->idx; do { switch (args->id) { + case SWM_ARG_ID_CYCLEWS_UP_ALL: + cycle_all = 1; + /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_UP: if (a.id < SWM_WS_MAX - 1) a.id++; else a.id = 0; break; + case SWM_ARG_ID_CYCLEWS_DOWN_ALL: + cycle_all = 1; + /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_DOWN: if (a.id > 0) a.id--; @@ -2134,7 +2178,8 @@ cyclews(struct swm_region *r, union arg *args) return; }; - if (cycle_empty == 0 && TAILQ_EMPTY(&s->ws[a.id].winlist)) + if (!cycle_all && + (cycle_empty == 0 && TAILQ_EMPTY(&s->ws[a.id].winlist))) continue; if (cycle_visible == 0 && s->ws[a.id].r != NULL) continue; @@ -3209,7 +3254,7 @@ search_do_resp(void) if ((resp = calloc(1, MAX_RESP_LEN + 1)) == NULL) { fprintf(stderr, "search: calloc\n"); - return; + goto done; } rbytes = read(select_resp_pipe[0], resp, MAX_RESP_LEN); @@ -3241,6 +3286,7 @@ search_do_resp(void) free(s); } done: + close(select_resp_pipe[0]); free(resp); } @@ -3353,10 +3399,13 @@ resize(struct ws_win *win, union arg *args) { XEvent ev; Time time = 0; - struct swm_region *r = win->ws->r; + struct swm_region *r = NULL; int relx, rely; int resize_step = 0; + if (win == NULL) + return; + r = win->ws->r; DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %lu\n", win->id, win->floating, win->transient); @@ -3471,7 +3520,7 @@ resize_step(struct swm_region *r, union arg *args) { struct ws_win *win = NULL; - if (r && r->ws) + if (r && r->ws && r->ws->focus) win = r->ws->focus; else return; @@ -3508,7 +3557,11 @@ move(struct ws_win *win, union arg *args) XEvent ev; Time time = 0; int move_step = 0; - struct swm_region *r = win->ws->r; + struct swm_region *r = NULL; + + if (win == NULL) + return; + r = win->ws->r; DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %lu\n", win->id, win->floating, win->transient); @@ -3605,7 +3658,7 @@ move_step(struct swm_region *r, union arg *args) { struct ws_win *win = NULL; - if (r && r->ws) + if (r && r->ws && r->ws->focus) win = r->ws->focus; else return; @@ -3649,6 +3702,8 @@ enum keyfuncid { kf_ws_10, kf_ws_next, kf_ws_prev, + kf_ws_next_all, + kf_ws_prev_all, kf_ws_prior, kf_screen_next, kf_screen_prev, @@ -3735,6 +3790,8 @@ struct keyfunc { { "ws_10", switchws, {.id = 9} }, { "ws_next", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP} }, { "ws_prev", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN} }, + { "ws_next_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP_ALL} }, + { "ws_prev_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN_ALL} }, { "ws_prior", priorws, {0} }, { "screen_next", cyclescr, {.id = SWM_ARG_ID_CYCLESC_UP} }, { "screen_prev", cyclescr, {.id = SWM_ARG_ID_CYCLESC_DOWN} }, @@ -4335,6 +4392,8 @@ setup_keys(void) setkeybinding(MODKEY, XK_0, kf_ws_10, NULL); setkeybinding(MODKEY, XK_Right, kf_ws_next, NULL); setkeybinding(MODKEY, XK_Left, kf_ws_prev, NULL); + setkeybinding(MODKEY, XK_Up, kf_ws_next_all, NULL); + setkeybinding(MODKEY, XK_Down, kf_ws_prev_all, NULL); setkeybinding(MODKEY, XK_a, kf_ws_prior, NULL); setkeybinding(MODKEY|ShiftMask, XK_Right, kf_screen_next, NULL); setkeybinding(MODKEY|ShiftMask, XK_Left, kf_screen_prev, NULL); @@ -4377,6 +4436,37 @@ setup_keys(void) } void +clear_keys(void) +{ + int i; + + /* clear all key bindings, if any */ + for (i = 0; i < keys_length; i++) + free(keys[i].spawn_name); + keys_length = 0; +} + +int +setkeymapping(char *selector, char *value, int flags) +{ + char keymapping_file[PATH_MAX]; + DNPRINTF(SWM_D_KEY, "setkeymapping: enter\n"); + if (value[0] == '~') + snprintf(keymapping_file, sizeof keymapping_file, "%s/%s", + pwd->pw_dir, &value[1]); + else + strlcpy(keymapping_file, value, sizeof keymapping_file); + clear_keys(); + /* load new key bindings; if it fails, revert to default bindings */ + if (conf_load(keymapping_file, SWM_CONF_KEYMAPPING)) { + clear_keys(); + setup_keys(); + } + DNPRINTF(SWM_D_KEY, "setkeymapping: leave\n"); + return (0); +} + +void updatenumlockmask(void) { unsigned int i, j; @@ -4613,13 +4703,14 @@ enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_BAR_BORDER_WIDTH, SWM_S_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, SWM_S_BAR_FONT, SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_SS_APP, SWM_S_DIALOG_RATIO, SWM_S_BAR_AT_BOTTOM, - SWM_S_VERBOSE_LAYOUT + SWM_S_VERBOSE_LAYOUT, SWM_S_BAR_JUSTIFY }; int setconfvalue(char *selector, char *value, int flags) { - int i; + int i; + switch (flags) { case SWM_S_BAR_DELAY: bar_delay = atoi(value); @@ -4633,6 +4724,16 @@ setconfvalue(char *selector, char *value, int flags) case SWM_S_BAR_AT_BOTTOM: bar_at_bottom = atoi(value); break; + case SWM_S_BAR_JUSTIFY: + if (!strcmp(value, "left")) + bar_justify = SWM_BAR_JUSTIFY_LEFT; + else if (!strcmp(value, "center")) + bar_justify = SWM_BAR_JUSTIFY_CENTER; + else if (!strcmp(value, "right")) + bar_justify = SWM_BAR_JUSTIFY_RIGHT; + else + errx(1, "invalid bar_justify"); + break; case SWM_S_STACK_ENABLED: stack_enabled = atoi(value); break; @@ -4821,7 +4922,8 @@ setautorun(char *selector, char *value, int flags) int setlayout(char *selector, char *value, int flags) { - int ws_id, st, i, x, mg, ma, si, raise; + int ws_id, i, x, mg, ma, si, raise; + int st = SWM_V_STACK; char s[1024]; struct workspace *ws; @@ -4899,6 +5001,8 @@ struct config_option configopt[] = { { "bar_font", setconfvalue, SWM_S_BAR_FONT }, { "bar_action", setconfvalue, SWM_S_BAR_ACTION }, { "bar_delay", setconfvalue, SWM_S_BAR_DELAY }, + { "bar_justify", setconfvalue, SWM_S_BAR_JUSTIFY }, + { "keyboard_mapping", setkeymapping, 0 }, { "bind", setconfbinding, 0 }, { "stack_enabled", setconfvalue, SWM_S_STACK_ENABLED }, { "clock_enabled", setconfvalue, SWM_S_CLOCK_ENABLED }, @@ -4930,7 +5034,7 @@ struct config_option configopt[] = { int -conf_load(char *filename) +conf_load(char *filename, int keymapping) { FILE *config; char *line, *cp, *optsub, *optval; @@ -4945,7 +5049,7 @@ conf_load(char *filename) return (1); } if ((config = fopen(filename, "r")) == NULL) { - warn("conf_load: fopen"); + warn("conf_load: fopen: %s", filename); return (1); } @@ -4985,6 +5089,11 @@ conf_load(char *filename) filename, lineno, wordlen, cp); return (1); } + if (keymapping && strcmp(opt->optname, "bind")) { + warnx("%s: line %zd: invalid option %.*s", + filename, lineno, wordlen, cp); + return (1); + } cp += wordlen; cp += strspn(cp, " \t\n"); /* eat whitespace */ /* get [selector] if any */ @@ -5461,7 +5570,6 @@ buttonpress(XEvent *e) DNPRINTF(SWM_D_EVENT, "buttonpress: window: %lu\n", ev->window); - action = root_click; if ((win = find_window(ev->window)) == NULL) return; @@ -6260,7 +6368,6 @@ workaround(void) int main(int argc, char *argv[]) { - struct passwd *pwd; struct swm_region *r, *rr; struct ws_win *winfocus = NULL; struct timeval tv; @@ -6273,9 +6380,10 @@ main(int argc, char *argv[]) struct sigaction sact; start_argv = argv; - fprintf(stderr, "Welcome to scrotwm V%s cvs tag: %s\n", - SWM_VERSION, cvstag); - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fprintf(stderr, "Welcome to scrotwm V%s Build: %s\n", + SCROTWM_VERSION, buildstr); + if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, "") || + !XSupportsLocale()) warnx("no locale support"); if (!(display = XOpenDisplay(0))) @@ -6331,7 +6439,7 @@ main(int argc, char *argv[]) cfile = conf; } if (cfile) - conf_load(cfile); + conf_load(cfile, SWM_CONF_DEFAULT); setup_ewmh(); /* set some values to work around bad programs */