JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Cycle through all workspaces (empty or not) with M-<Up> and M-<Down>.
[spectrwm.git] / scrotwm.c
index 47e7319..dfbdefc 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
  * DEALINGS IN THE SOFTWARE.
  */
 
-static const char      *cvstag =
-    "$scrotwm$";
-
-#define        SWM_VERSION     "0.9.34"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <err.h>
@@ -92,6 +87,14 @@ static const char    *cvstag =
 #include <osx.h>
 #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
@@ -206,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];
@@ -221,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;
@@ -417,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)
@@ -1144,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);
@@ -1156,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
@@ -1208,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
@@ -1324,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;
@@ -1361,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);
                }
        }
@@ -1540,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();
@@ -2115,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,
@@ -2123,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--;
@@ -2139,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;
@@ -3214,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);
@@ -3246,6 +3286,7 @@ search_do_resp(void)
                free(s);
        }
 done:
+       close(select_resp_pipe[0]);
        free(resp);
 }
 
@@ -3661,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,
@@ -3747,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} },
@@ -4347,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);
@@ -4656,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);
@@ -4676,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;
@@ -4943,6 +5001,7 @@ 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 },
@@ -6321,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)))