JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add new key binding: bar_toggle_ws (M-S-b)
[spectrwm.git] / spectrwm.c
index 0abdd65..af2fe15 100644 (file)
@@ -494,6 +494,7 @@ struct workspace {
        int                     idx;            /* workspace index */
        char                    *name;          /* workspace name */
        int                     always_raise;   /* raise windows on focus */
+       int                     bar_enabled;    /* bar visibility */
        struct layout           *cur_layout;    /* current layout handlers */
        struct ws_win           *focus;         /* may be NULL */
        struct ws_win           *focus_prev;    /* may be NULL */
@@ -587,6 +588,8 @@ union arg {
 #define SWM_ARG_ID_MOVEDOWN    (101)
 #define SWM_ARG_ID_MOVELEFT    (102)
 #define SWM_ARG_ID_MOVERIGHT   (103)
+#define SWM_ARG_ID_BAR_TOGGLE  (110)
+#define SWM_ARG_ID_BAR_TOGGLE_WS       (111)
        char                    **argv;
 };
 
@@ -712,6 +715,7 @@ struct spawn_list           spawns = TAILQ_HEAD_INITIALIZER(spawns);
 /* user/key callable function IDs */
 enum keyfuncid {
        KF_BAR_TOGGLE,
+       KF_BAR_TOGGLE_WS,
        KF_BUTTON2,
        KF_CYCLE_LAYOUT,
        KF_FLIP_LAYOUT,
@@ -2175,6 +2179,14 @@ bar_fmt_print(void)
                TAILQ_FOREACH(r, &screens[i].rl, entry) {
                        if (r->bar == NULL)
                                continue;
+
+                       if (r->ws->bar_enabled)
+                               xcb_map_window(conn, r->bar->id);
+                       else {
+                               xcb_unmap_window(conn, r->bar->id);
+                               continue;
+                       }
+
                        bar_fmt(fmtexp, fmtnew, r, sizeof fmtnew);
                        bar_replace(fmtnew, fmtrep, r, sizeof fmtrep);
                        if (bar_font_legacy)
@@ -2232,20 +2244,27 @@ bar_toggle(struct swm_region *r, union arg *args)
 
        DNPRINTF(SWM_D_BAR, "bar_toggle\n");
 
-       num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
-       if (bar_enabled) {
-               for (i = 0; i < num_screens; i++)
-                       TAILQ_FOREACH(tmpr, &screens[i].rl, entry)
-                               if (tmpr->bar)
-                                       xcb_unmap_window(conn, tmpr->bar->id);
-       } else {
-               for (i = 0; i < num_screens; i++)
-                       TAILQ_FOREACH(tmpr, &screens[i].rl, entry)
-                               if (tmpr->bar)
-                                       xcb_map_window(conn, tmpr->bar->id);
+       switch (args->id) {
+       case SWM_ARG_ID_BAR_TOGGLE_WS:
+               /* Only change if master switch is enabled. */
+               if (bar_enabled)
+                       r->ws->bar_enabled = !r->ws->bar_enabled;
+               break;
+       case SWM_ARG_ID_BAR_TOGGLE:
+               bar_enabled = !bar_enabled;
+               break;
        }
 
-       bar_enabled = !bar_enabled;
+       /* update bars as necessary */
+       num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+       for (i = 0; i < num_screens; i++)
+               TAILQ_FOREACH(tmpr, &screens[i].rl, entry)
+                       if (tmpr->bar) {
+                               if (bar_enabled && tmpr->ws->bar_enabled)
+                                       xcb_map_window(conn, tmpr->bar->id);
+                               else
+                                       xcb_unmap_window(conn, tmpr->bar->id);
+                       }
 
        stack();
 
@@ -3073,6 +3092,7 @@ unfocus_win(struct ws_win *win)
                kill_refs(win->ws->focus);
                win->ws->focus = NULL;
        }
+
        if (validate_win(win->ws->focus_prev)) {
                kill_refs(win->ws->focus_prev);
                win->ws->focus_prev = NULL;
@@ -3780,7 +3800,7 @@ stack(void) {
                        g = r->g;
                        g.w -= 2 * border_width;
                        g.h -= 2 * border_width;
-                       if (bar_enabled) {
+                       if (bar_enabled && r->ws->bar_enabled) {
                                if (!bar_at_bottom)
                                        g.y += bar_height;
                                g.h -= bar_height;
@@ -4073,7 +4093,8 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
                else
                        win_g.y += last_h + 2 * border_width;
 
-               if (disable_border && !bar_enabled && winno == 1){
+               if (disable_border && !(bar_enabled && ws->bar_enabled) &&
+                   winno == 1){
                        bordered = 0;
                        win_g.w += 2 * border_width;
                        win_g.h += 2 * border_width;
@@ -4290,7 +4311,7 @@ max_stack(struct workspace *ws, struct swm_geometry *g)
                if (X(w) != gg.x || Y(w) != gg.y || WIDTH(w) != gg.w ||
                    HEIGHT(w) != gg.h) {
                        w->g = gg;
-                       if (bar_enabled){
+                       if (bar_enabled && ws->bar_enabled){
                                w->bordered = 1;
                        } else {
                                w->bordered = 0;
@@ -5381,7 +5402,8 @@ struct keyfunc {
        union arg               args;
 } keyfuncs[KF_INVALID + 1] = {
        /* name                 function        argument */
-       { "bar_toggle",         bar_toggle,     {0} },
+       { "bar_toggle",         bar_toggle,     {.id = SWM_ARG_ID_BAR_TOGGLE} },
+       { "bar_toggle_ws",      bar_toggle,     {.id = SWM_ARG_ID_BAR_TOGGLE_WS} },
        { "button2",            pressbutton,    {2} },
        { "cycle_layout",       cycle_layout,   {0} },
        { "flip_layout",        stack_config,   {.id = SWM_ARG_ID_FLIPLAYOUT} },
@@ -6080,6 +6102,7 @@ setup_keys(void)
        setkeybinding(MODKEY_SHIFT,     XK_F11,         KF_MVWS_21,     NULL);
        setkeybinding(MODKEY_SHIFT,     XK_F12,         KF_MVWS_22,     NULL);
        setkeybinding(MODKEY,           XK_b,           KF_BAR_TOGGLE,  NULL);
+       setkeybinding(MODKEY_SHIFT,     XK_b,           KF_BAR_TOGGLE_WS,NULL);
        setkeybinding(MODKEY,           XK_Tab,         KF_FOCUS_NEXT,  NULL);
        setkeybinding(MODKEY_SHIFT,     XK_Tab,         KF_FOCUS_PREV,  NULL);
        setkeybinding(MODKEY_SHIFT,     XK_x,           KF_WIND_KILL,   NULL);
@@ -6182,7 +6205,7 @@ grabkeys(void)
 {
        struct key              *kp;
        int                     num_screens, k, j;
-       unsigned int            modifiers[3];
+       unsigned int            modifiers[4];
        xcb_keycode_t           *code;
 
        DNPRINTF(SWM_D_MISC, "grabkeys\n");
@@ -6190,7 +6213,8 @@ grabkeys(void)
 
        modifiers[0] = 0;
        modifiers[1] = numlockmask;
-       modifiers[2] = numlockmask | XCB_MOD_MASK_LOCK;
+       modifiers[2] = XCB_MOD_MASK_LOCK;
+       modifiers[3] = numlockmask | XCB_MOD_MASK_LOCK;
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        for (k = 0; k < num_screens; k++) {
@@ -6216,16 +6240,25 @@ grabkeys(void)
 void
 grabbuttons(struct ws_win *win)
 {
-       int             i;
+       unsigned int    modifiers[4];
+       int             i, j;
 
        DNPRINTF(SWM_D_MOUSE, "grabbuttons: win 0x%x\n", win->id);
+       updatenumlockmask();
+
+       modifiers[0] = 0;
+       modifiers[1] = numlockmask;
+       modifiers[2] = XCB_MOD_MASK_LOCK;
+       modifiers[3] = numlockmask | XCB_MOD_MASK_LOCK;
 
        for (i = 0; i < LENGTH(buttons); i++)
                if (buttons[i].action == client_click)
-                       xcb_grab_button(conn, 0, win->id, BUTTONMASK,
-                           XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
-                           XCB_WINDOW_NONE, XCB_CURSOR_NONE,
-                           buttons[i].button, buttons[i].mask);
+                       for (j = 0; j < LENGTH(modifiers); ++j)
+                               xcb_grab_button(conn, 0, win->id, BUTTONMASK,
+                                   XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
+                                   XCB_WINDOW_NONE, XCB_CURSOR_NONE,
+                                   buttons[i].button, buttons[i].mask |
+                                   modifiers[j]);
 }
 
 const char *quirkname[] = {
@@ -7473,7 +7506,7 @@ buttonpress(xcb_button_press_event_t *e)
        }
 
        if (win == NULL)
-               return;
+               goto out;
 
        last_event_time = e->time;
 
@@ -8594,6 +8627,7 @@ setup_screens(void)
                        ws = &screens[i].ws[j];
                        ws->idx = j;
                        ws->name = NULL;
+                       ws->bar_enabled = 1;
                        ws->focus = NULL;
                        ws->focus_prev = NULL;
                        ws->focus_pending = NULL;