]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Rename variables that shadow global declarations.
[spectrwm] / spectrwm.c
index 83b31a0ebc46c4995f6b3105f52ee47c0c3c38e6..238b12189492729f7adb35a038eb8a14c4c43cdc 100644 (file)
@@ -572,7 +572,9 @@ enum {
        SWM_S_COLOR_BAR_BORDER_UNFOCUS,
        SWM_S_COLOR_BAR_FONT,
        SWM_S_COLOR_FOCUS,
+       SWM_S_COLOR_FOCUS_MAXIMIZED,
        SWM_S_COLOR_UNFOCUS,
+       SWM_S_COLOR_UNFOCUS_MAXIMIZED,
        SWM_S_COLOR_MAX
 };
 
@@ -592,6 +594,7 @@ struct swm_screen {
        struct {
                uint32_t        pixel;
                char            *name;
+               int             manual;
        } c[SWM_S_COLOR_MAX];
 
        xcb_gcontext_t          bar_gc;
@@ -1152,6 +1155,7 @@ void       update_floater(struct ws_win *);
 void    update_modkey(unsigned int);
 void    update_win_stacking(struct ws_win *);
 void    update_window(struct ws_win *);
+void    update_window_color(struct ws_win *);
 void    update_wm_state(struct  ws_win *win);
 void    validate_spawns(void);
 int     validate_win(struct ws_win *);
@@ -1632,6 +1636,8 @@ ewmh_apply_flags(struct ws_win *win, uint32_t pending)
                                        ws->focus_pending = win;
                        }
                }
+
+               update_window_color(win);
                raise_window(win);
        }
 
@@ -3468,8 +3474,7 @@ unfocus_win(struct ws_win *win)
                win->ws->focus_prev = NULL;
        }
 
-       xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
-           &win->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+       update_window_color(win);
 
        xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
            ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none);
@@ -3486,13 +3491,7 @@ focus_win(struct ws_win *win)
 
        DNPRINTF(SWM_D_FOCUS, "focus_win: win %#x\n", WINID(win));
 
-       if (win == NULL)
-               goto out;
-
-       if (win->ws == NULL)
-               goto out;
-
-       if (!win->mapped)
+       if (win == NULL || win->ws == NULL || !win->mapped)
                goto out;
 
        ws = win->ws;
@@ -3513,7 +3512,9 @@ focus_win(struct ws_win *win)
                                /* Change border to unfocused color. */
                                xcb_change_window_attributes(conn, cfw->id,
                                    XCB_CW_BORDER_PIXEL,
-                                   &cfw->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+                                   &cfw->s->c[(MAXIMIZED(cfw) ?
+                                   SWM_S_COLOR_UNFOCUS_MAXIMIZED :
+                                   SWM_S_COLOR_UNFOCUS)].pixel);
                        } else {
                                unfocus_win(cfw);
                        }
@@ -3559,9 +3560,6 @@ focus_win(struct ws_win *win)
                                client_msg(win, a_takefocus, last_event_time);
                }
 
-               xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
-                   &win->s->c[SWM_S_COLOR_FOCUS].pixel);
-
                if (ws->cur_layout->flags & SWM_L_MAPONFOCUS ||
                    ws->always_raise) {
                        /* If a parent exists, map it first. */
@@ -3595,6 +3593,8 @@ focus_win(struct ws_win *win)
 
                set_region(ws->r);
 
+               update_window_color(win);
+
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
                    ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1,
                    &win->id);
@@ -3750,8 +3750,7 @@ switchws(struct swm_region *r, union arg *args)
                return;
 
        if ((win = old_ws->focus) != NULL) {
-               xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
-                   &win->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+               update_window_color(win);
 
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
                    ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1,
@@ -3820,7 +3819,7 @@ cyclews(struct swm_region *r, union arg *args)
        union                   arg a;
        struct swm_screen       *s = r->s;
        int                     cycle_all = 0;
-       int                     move = 0;
+       int                     mv = 0;
 
        DNPRINTF(SWM_D_WS, "cyclews: id: %d, screen[%d]:%dx%d+%d+%d, ws: %d\n",
            args->id, r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx);
@@ -3830,7 +3829,7 @@ cyclews(struct swm_region *r, union arg *args)
        do {
                switch (args->id) {
                case SWM_ARG_ID_CYCLEWS_MOVE_UP:
-                       move = 1;
+                       mv = 1;
                        /* FALLTHROUGH */
                case SWM_ARG_ID_CYCLEWS_UP_ALL:
                        cycle_all = 1;
@@ -3839,7 +3838,7 @@ cyclews(struct swm_region *r, union arg *args)
                        a.id = (a.id < workspace_limit - 1) ? a.id + 1 : 0;
                        break;
                case SWM_ARG_ID_CYCLEWS_MOVE_DOWN:
-                       move = 1;
+                       mv = 1;
                        /* FALLTHROUGH */
                case SWM_ARG_ID_CYCLEWS_DOWN_ALL:
                        cycle_all = 1;
@@ -3857,7 +3856,7 @@ cyclews(struct swm_region *r, union arg *args)
                if (!cycle_visible && s->ws[a.id].r != NULL)
                        continue;
 
-               if (move)
+               if (mv)
                        send_to_ws(r, &a);
 
                switchws(r, &a);
@@ -5555,7 +5554,7 @@ ewmh_update_desktop_names(void)
                        ++len;
                }
 
-               if((name_list = calloc(sizeof(char *), len)) == NULL)
+               if((name_list = calloc(len, sizeof(char))) == NULL)
                        err(1, "update_desktop_names: calloc: failed to "
                            "allocate memory.");
 
@@ -5638,7 +5637,7 @@ ewmh_update_client_list(void)
                if (count == 0)
                        continue;
 
-               wins = calloc(sizeof(xcb_window_t), count);
+               wins = calloc(count, sizeof(xcb_window_t));
                if (wins == NULL)
                        err(1, "ewmh_update_client_list: calloc: failed to "
                            "allocate memory.");
@@ -5673,7 +5672,7 @@ ewmh_update_desktops(void)
        int                     num_screens, i, j;
        uint32_t                *vals;
 
-       vals = calloc(sizeof(uint32_t), workspace_limit * 2);
+       vals = calloc(workspace_limit * 2, sizeof(uint32_t));
        if (vals == NULL)
                err(1, "ewmh_update_desktops: calloc: failed to allocate "
                    "memory.");
@@ -6011,6 +6010,24 @@ constrain_window(struct ws_win *win, struct swm_geometry *b, int *opts)
        }
 }
 
+void
+update_window_color(struct ws_win *win)
+{
+       uint32_t        *pixel;
+
+       if (WS_FOCUSED(win->ws) && win->ws->focus == win)
+               pixel = MAXIMIZED(win) ?
+                   &win->s->c[SWM_S_COLOR_FOCUS_MAXIMIZED].pixel :
+                   &win->s->c[SWM_S_COLOR_FOCUS].pixel;
+       else
+               pixel = MAXIMIZED(win) ?
+                   &win->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].pixel :
+                   &win->s->c[SWM_S_COLOR_UNFOCUS].pixel;
+
+       xcb_change_window_attributes(conn, win->id,
+           XCB_CW_BORDER_PIXEL, pixel);
+}
+
 void
 update_window(struct ws_win *win)
 {
@@ -6683,11 +6700,21 @@ spawn_expand(struct swm_region *r, union arg *args, const char *spawn_name,
                            strdup(r->s->c[SWM_S_COLOR_FOCUS].name))
                            == NULL)
                                err(1, "spawn_custom color focus");
+               } else if (strcasecmp(ap, "$color_focus_maximized") == 0) {
+                       if ((real_args[c] =
+                           strdup(r->s->c[SWM_S_COLOR_FOCUS_MAXIMIZED].name))
+                           == NULL)
+                               err(1, "spawn_custom color focus maximized");
                } else if (strcasecmp(ap, "$color_unfocus") == 0) {
                        if ((real_args[c] =
                            strdup(r->s->c[SWM_S_COLOR_UNFOCUS].name))
                            == NULL)
                                err(1, "spawn_custom color unfocus");
+               } else if (strcasecmp(ap, "$color_unfocus_maximized") == 0) {
+                       if ((real_args[c] =
+                           strdup(r->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].name))
+                           == NULL)
+                               err(1, "spawn_custom color unfocus maximized");
                } else if (strcasecmp(ap, "$region_index") == 0) {
                        if (asprintf(&real_args[c], "%d",
                            get_region_index(r) + 1) < 1)
@@ -6831,7 +6858,7 @@ void
 spawn_insert(const char *name, const char *args, int flags)
 {
        struct spawn_prog       *sp;
-       char                    *arg, *dup, *ptr;
+       char                    *arg, *cp, *ptr;
 
        DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s[%s]\n", name, args);
 
@@ -6844,7 +6871,7 @@ spawn_insert(const char *name, const char *args, int flags)
                err(1, "spawn_insert: strdup");
 
        /* Convert the arguments to an argument list. */
-       if ((ptr = dup = strdup(args)) == NULL)
+       if ((ptr = cp = strdup(args)) == NULL)
                err(1, "spawn_insert: strdup");
        while ((arg = argsep(&ptr)) != NULL) {
                /* Null argument; skip it. */
@@ -6858,7 +6885,7 @@ 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(dup);
+       free(cp);
 
        sp->flags = flags;
 
@@ -8075,9 +8102,36 @@ setconfmodkey(const char *selector, const char *value, int flags)
 int
 setconfcolor(const char *selector, const char *value, int flags)
 {
-       setscreencolor(value,
-           (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector),
-           flags);
+       int     sid, i, num_screens;
+
+       sid = (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector);
+
+       /*
+        * When setting focus/unfocus colors, we need to also
+        * set maximize colors to match if they haven't been customized.
+        */
+       i = sid < 0 ? 0 : sid;
+       if (flags == SWM_S_COLOR_FOCUS &&
+           !screens[i].c[SWM_S_COLOR_FOCUS_MAXIMIZED].manual)
+               setscreencolor(value, sid, SWM_S_COLOR_FOCUS_MAXIMIZED);
+       else if (flags == SWM_S_COLOR_UNFOCUS &&
+           !screens[i].c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].manual)
+               setscreencolor(value, sid, SWM_S_COLOR_UNFOCUS_MAXIMIZED);
+
+       setscreencolor(value, sid, flags);
+
+       /* Track override of color. */
+       num_screens = get_screen_count();
+       if (sid > 0 && sid <= num_screens) {
+               screens[i].c[flags].manual = 1;
+       } else if (sid == -1) {
+               for (i = 0; i < num_screens; ++i)
+                       screens[i].c[flags].manual = 1;
+       } else {
+               errx(1, "invalid screen index: %d out of bounds (maximum %d)",
+                   sid, num_screens);
+       }
+
        return (0);
 }
 
@@ -8276,7 +8330,9 @@ struct config_option configopt[] = {
        { "clock_enabled",              setconfvalue,   SWM_S_CLOCK_ENABLED },
        { "clock_format",               setconfvalue,   SWM_S_CLOCK_FORMAT },
        { "color_focus",                setconfcolor,   SWM_S_COLOR_FOCUS },
+       { "color_focus_maximized",      setconfcolor,   SWM_S_COLOR_FOCUS_MAXIMIZED },
        { "color_unfocus",              setconfcolor,   SWM_S_COLOR_UNFOCUS },
+       { "color_unfocus_maximized",    setconfcolor,   SWM_S_COLOR_UNFOCUS_MAXIMIZED },
        { "cycle_empty",                setconfvalue,   SWM_S_CYCLE_EMPTY },
        { "cycle_visible",              setconfvalue,   SWM_S_CYCLE_VISIBLE },
        { "dialog_ratio",               setconfvalue,   SWM_S_DIALOG_RATIO },
@@ -10289,6 +10345,8 @@ setup_screens(void)
                    SWM_S_COLOR_BAR_BORDER_UNFOCUS);
                setscreencolor("black", i + 1, SWM_S_COLOR_BAR);
                setscreencolor("rgb:a0/a0/a0", i + 1, SWM_S_COLOR_BAR_FONT);
+               setscreencolor("red", i + 1, SWM_S_COLOR_FOCUS_MAXIMIZED);
+               setscreencolor("rgb:88/88/88", i + 1, SWM_S_COLOR_UNFOCUS_MAXIMIZED);
 
                /* create graphics context on screen */
                screens[i].bar_gc = xcb_generate_id(conn);