]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Fix segfault when attempting to switch workspace during startup.
[spectrwm] / spectrwm.c
index b81985e08c5a435df7253cadb89bfad437a65bd9..48591d907e74fc31aa27b1d0b21f01740214a02a 100644 (file)
@@ -9,6 +9,7 @@
  * Copyright (c) 2011-2012 Lawrence Teo <lteo@lteo.net>
  * Copyright (c) 2011-2012 Tiago Cunha <tcunha@gmx.com>
  * Copyright (c) 2012-2015 David Hill <dhill@mindcry.org>
+ * Copyright (c) 2014-2015 Yuri D'Elia <yuri.delia@eurac.edu>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -332,9 +333,9 @@ bool                        cycle_visible = false;
 int                    term_width = 0;
 int                    font_adjusted = 0;
 unsigned int           mod_key = MODKEY;
+bool                   warp_focus = false;
 bool                   warp_pointer = false;
-unsigned int           mouse_button_move = XCB_BUTTON_INDEX_1;
-unsigned int           mouse_button_resize = XCB_BUTTON_INDEX_3;
+bool                   workspace_clamp = false;
 
 /* dmenu search */
 struct swm_region      *search_r;
@@ -888,19 +889,19 @@ enum keyfuncid {
        KF_RG_7,
        KF_RG_8,
        KF_RG_9,
-       KF_RG_NEXT,
-       KF_RG_PREV,
        KF_RG_MOVE_NEXT,
        KF_RG_MOVE_PREV,
+       KF_RG_NEXT,
+       KF_RG_PREV,
        KF_SCREEN_NEXT,
        KF_SCREEN_PREV,
        KF_SEARCH_WIN,
        KF_SEARCH_WORKSPACE,
        KF_SPAWN_CUSTOM,
+       KF_STACK_BALANCE,
        KF_STACK_INC,
        KF_STACK_DEC,
        KF_STACK_RESET,
-       KF_STACK_BALANCE,
        KF_SWAP_MAIN,
        KF_SWAP_NEXT,
        KF_SWAP_PREV,
@@ -1129,8 +1130,6 @@ int        setautorun(const char *, const char *, int);
 int     setconfbinding(const char *, const char *, int);
 int     setconfcolor(const char *, const char *, int);
 int     setconfmodkey(const char *, const char *, int);
-int     setconfmousebuttonmove(const char *, const char *, int);
-int     setconfmousebuttonresize(const char *, const char *, int);
 int     setconfquirk(const char *, const char *, int);
 int     setconfregion(const char *, const char *, int);
 int     setconfspawn(const char *, const char *, int);
@@ -1178,7 +1177,6 @@ void       unmap_window(struct ws_win *);
 void    updatenumlockmask(void);
 void    update_floater(struct ws_win *);
 void    update_modkey(unsigned int);
-unsigned char  update_mousebutton(unsigned char, unsigned int);
 void    update_win_stacking(struct ws_win *);
 void    update_window(struct ws_win *);
 void    update_window_color(struct ws_win *);
@@ -2226,6 +2224,8 @@ bar_urgent(char *s, size_t sz)
                        strlcat(s, "- ", sz);
                }
        }
+       if(urgent_collapse && s[0])
+               s[strlen(s) - 1] = 0;
 }
 
 void
@@ -3885,6 +3885,20 @@ switchws(struct swm_region *r, union arg *args)
        if (new_ws == old_ws)
                return;
 
+       other_r = new_ws->r;
+       if (other_r && workspace_clamp) {
+               DNPRINTF(SWM_D_WS, "switchws: ws clamped.\n");
+
+               if (warp_focus) {
+                       DNPRINTF(SWM_D_WS, "switchws: warping focus to region "
+                           "with ws %d.\n", wsid);
+                       focus_region(other_r);
+                       center_pointer(other_r);
+                       focus_flush();
+               }
+               return;
+       }
+
        if ((win = old_ws->focus) != NULL) {
                update_window_color(win);
 
@@ -3893,17 +3907,17 @@ switchws(struct swm_region *r, union arg *args)
                    &none);
        }
 
-       other_r = new_ws->r;
-       if (other_r == NULL) {
-               /* the other workspace is hidden, hide this one */
-               old_ws->r = NULL;
-               unmap_old = true;
-       } else {
+       if (other_r) {
                /* the other ws is visible in another region, exchange them */
                other_r->ws_prior = new_ws;
                other_r->ws = old_ws;
                old_ws->r = other_r;
+       } else {
+               /* the other workspace is hidden, hide this one */
+               old_ws->r = NULL;
+               unmap_old = true;
        }
+
        this_r->ws_prior = old_ws;
        this_r->ws = new_ws;
        new_ws->r = this_r;
@@ -4970,9 +4984,6 @@ vertical_config(struct workspace *ws, int id)
                ws->l_state.vertical_mwin = 1;
                ws->l_state.vertical_stacks = 1;
                break;
-       case SWM_ARG_ID_STACKBALANCE:
-               ws->l_state.vertical_msize = SWM_V_SLICE / (ws->l_state.vertical_stacks + 1);
-               break;
        case SWM_ARG_ID_MASTERSHRINK:
                if (ws->l_state.vertical_msize > 1)
                        ws->l_state.vertical_msize--;
@@ -4988,6 +4999,9 @@ vertical_config(struct workspace *ws, int id)
                if (ws->l_state.vertical_mwin > 0)
                        ws->l_state.vertical_mwin--;
                break;
+       case SWM_ARG_ID_STACKBALANCE:
+               ws->l_state.vertical_msize = SWM_V_SLICE / (ws->l_state.vertical_stacks + 1);
+               break;
        case SWM_ARG_ID_STACKINC:
                ws->l_state.vertical_stacks++;
                break;
@@ -5023,9 +5037,6 @@ horizontal_config(struct workspace *ws, int id)
                ws->l_state.horizontal_msize = SWM_H_SLICE / 2;
                ws->l_state.horizontal_stacks = 1;
                break;
-       case SWM_ARG_ID_STACKBALANCE:
-               ws->l_state.horizontal_msize = SWM_H_SLICE / (ws->l_state.horizontal_stacks + 1);
-               break;
        case SWM_ARG_ID_MASTERSHRINK:
                if (ws->l_state.horizontal_msize > 1)
                        ws->l_state.horizontal_msize--;
@@ -5041,6 +5052,9 @@ horizontal_config(struct workspace *ws, int id)
                if (ws->l_state.horizontal_mwin > 0)
                        ws->l_state.horizontal_mwin--;
                break;
+       case SWM_ARG_ID_STACKBALANCE:
+               ws->l_state.horizontal_msize = SWM_H_SLICE / (ws->l_state.horizontal_stacks + 1);
+               break;
        case SWM_ARG_ID_STACKINC:
                ws->l_state.horizontal_stacks++;
                break;
@@ -5844,10 +5858,13 @@ ewmh_update_current_desktop(void)
        int                     num_screens, i;
 
        num_screens = get_screen_count();
-       for (i = 0; i < num_screens; ++i)
-               xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
-                   screens[i].root, ewmh[_NET_CURRENT_DESKTOP].atom,
-                   XCB_ATOM_CARDINAL, 32, 1, &screens[i].r_focus->ws->idx);
+       for (i = 0; i < num_screens; ++i) {
+               if (screens[i].r_focus)
+                       xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
+                           screens[i].root, ewmh[_NET_CURRENT_DESKTOP].atom,
+                           XCB_ATOM_CARDINAL, 32, 1,
+                           &screens[i].r_focus->ws->idx);
+       }
 }
 
 void
@@ -6730,19 +6747,19 @@ struct keyfunc {
        { "rg_7",               focusrg,        {.id = 6} },
        { "rg_8",               focusrg,        {.id = 7} },
        { "rg_9",               focusrg,        {.id = 8} },
-       { "rg_next",            cyclerg,        {.id = SWM_ARG_ID_CYCLERG_UP} },
-       { "rg_prev",            cyclerg,        {.id = SWM_ARG_ID_CYCLERG_DOWN} },
        { "rg_move_next",       cyclerg,        {.id = SWM_ARG_ID_CYCLERG_MOVE_UP} },
        { "rg_move_prev",       cyclerg,        {.id = SWM_ARG_ID_CYCLERG_MOVE_DOWN} },
+       { "rg_next",            cyclerg,        {.id = SWM_ARG_ID_CYCLERG_UP} },
+       { "rg_prev",            cyclerg,        {.id = SWM_ARG_ID_CYCLERG_DOWN} },
        { "screen_next",        cyclerg,        {.id = SWM_ARG_ID_CYCLERG_UP} },
        { "screen_prev",        cyclerg,        {.id = SWM_ARG_ID_CYCLERG_DOWN} },
        { "search_win",         search_win,     {0} },
        { "search_workspace",   search_workspace,       {0} },
        { "spawn_custom",       NULL,           {0} },
+       { "stack_balance",      stack_config,   {.id = SWM_ARG_ID_STACKBALANCE} },
        { "stack_inc",          stack_config,   {.id = SWM_ARG_ID_STACKINC} },
        { "stack_dec",          stack_config,   {.id = SWM_ARG_ID_STACKDEC} },
        { "stack_reset",        stack_config,   {.id = SWM_ARG_ID_STACKRESET} },
-       { "stack_balance",      stack_config,   {.id = SWM_ARG_ID_STACKBALANCE} },
        { "swap_main",          swapwin,        {.id = SWM_ARG_ID_SWAPMAIN} },
        { "swap_next",          swapwin,        {.id = SWM_ARG_ID_SWAPNEXT} },
        { "swap_prev",          swapwin,        {.id = SWM_ARG_ID_SWAPPREV} },
@@ -6838,31 +6855,6 @@ update_modkey(unsigned int mod)
                        buttons[i].mask = mod;
 }
 
-unsigned char
-update_mousebutton(unsigned char type, unsigned int but)
-{
-       int                     i;
-
-       switch (type) {
-               case 0:
-                       mouse_button_move = but;
-                       break;
-               case 1:
-                       mouse_button_resize = but;
-                       break;
-       }
-
-       for (i = 0; i < LENGTH(buttons); i++) {
-               if (buttons[i].func == move)
-                       buttons[i].button = mouse_button_move;
-
-               if (buttons[i].func == resize)
-                       buttons[i].button = mouse_button_resize;
-       }
-
-       return(1);
-}
-
 int
 spawn_expand(struct swm_region *r, union arg *args, const char *spawn_name,
     char ***ret_args)
@@ -7533,8 +7525,6 @@ setup_keys(void)
        setkeybinding(MODKEY,           XK_KP_Up,       KF_RG_8,        NULL);
        setkeybinding(MODKEY,           XK_KP_Prior,    KF_RG_9,        NULL);
        setkeybinding(MODKEY_SHIFT,     XK_Right,       KF_RG_NEXT,     NULL);
-       setkeybinding(MODKEY,           XK_c,           KF_RG_MOVE_NEXT,NULL);
-       setkeybinding(MODKEY_SHIFT,     XK_c,           KF_RG_MOVE_PREV,NULL);
        setkeybinding(MODKEY_SHIFT,     XK_Left,        KF_RG_PREV,     NULL);
        setkeybinding(MODKEY,           XK_f,           KF_SEARCH_WIN,  NULL);
        setkeybinding(MODKEY,           XK_slash,       KF_SEARCH_WORKSPACE,NULL);
@@ -7547,7 +7537,6 @@ setup_keys(void)
        setkeybinding(MODKEY_SHIFT,     XK_comma,       KF_STACK_INC,   NULL);
        setkeybinding(MODKEY_SHIFT,     XK_period,      KF_STACK_DEC,   NULL);
        setkeybinding(MODKEY_SHIFT,     XK_space,       KF_STACK_RESET, NULL);
-       setkeybinding(MODKEY_SHIFT,     XK_h,           KF_STACK_BALANCE, NULL);
        setkeybinding(MODKEY,           XK_Return,      KF_SWAP_MAIN,   NULL);
        setkeybinding(MODKEY_SHIFT,     XK_j,           KF_SWAP_NEXT,   NULL);
        setkeybinding(MODKEY_SHIFT,     XK_k,           KF_SWAP_PREV,   NULL);
@@ -8073,10 +8062,12 @@ enum {
        SWM_S_URGENT_COLLAPSE,
        SWM_S_URGENT_ENABLED,
        SWM_S_VERBOSE_LAYOUT,
+       SWM_S_WARP_FOCUS,
        SWM_S_WARP_POINTER,
        SWM_S_WINDOW_CLASS_ENABLED,
        SWM_S_WINDOW_INSTANCE_ENABLED,
        SWM_S_WINDOW_NAME_ENABLED,
+       SWM_S_WORKSPACE_CLAMP,
        SWM_S_WORKSPACE_LIMIT,
        SWM_S_WORKSPACE_NAME,
 };
@@ -8291,6 +8282,9 @@ setconfvalue(const char *selector, const char *value, int flags)
                                layouts[i].l_string = plain_stacker;
                }
                break;
+       case SWM_S_WARP_FOCUS:
+               warp_focus = (atoi(value) != 0);
+               break;
        case SWM_S_WARP_POINTER:
                warp_pointer = (atoi(value) != 0);
                break;
@@ -8303,6 +8297,9 @@ setconfvalue(const char *selector, const char *value, int flags)
        case SWM_S_WINDOW_NAME_ENABLED:
                window_name_enabled = (atoi(value) != 0);
                break;
+       case SWM_S_WORKSPACE_CLAMP:
+               workspace_clamp = (atoi(value) != 0);
+               break;
        case SWM_S_WORKSPACE_LIMIT:
                workspace_limit = atoi(value);
                if (workspace_limit > SWM_WS_MAX)
@@ -8366,48 +8363,6 @@ setconfmodkey(const char *selector, const char *value, int flags)
        return (0);
 }
 
-int
-setconfmousebuttonmove(const char *selector, const char *value, int flags)
-{
-       /* suppress unused warnings since vars are needed */
-       (void)selector;
-       (void)flags;
-
-       if (strncasecmp(value, "But1", strlen("But1")) == 0) {
-               if (!update_mousebutton(0, XCB_BUTTON_INDEX_1))
-                       return (1);
-       } else if (strncasecmp(value, "But2", strlen("But2")) == 0) {
-               if (!update_mousebutton(0, XCB_BUTTON_INDEX_2))
-                       return (1);
-       } else if (strncasecmp(value, "But3", strlen("But3")) == 0) {
-               if (!update_mousebutton(0, XCB_BUTTON_INDEX_3))
-                       return (1);
-       } else
-               return (1);
-       return (0);
-}
-
-int
-setconfmousebuttonresize(const char *selector, const char *value, int flags)
-{
-       /* suppress unused warnings since vars are needed */
-       (void)selector;
-       (void)flags;
-
-       if (strncasecmp(value, "But1", strlen("But1")) == 0) {
-               if (!update_mousebutton(1, XCB_BUTTON_INDEX_1))
-                       return (1);
-       } else if (strncasecmp(value, "But2", strlen("But2")) == 0) {
-               if (!update_mousebutton(1, XCB_BUTTON_INDEX_2))
-                       return (1);
-       } else if (strncasecmp(value, "But3", strlen("But3")) == 0) {
-               if (!update_mousebutton(1, XCB_BUTTON_INDEX_3))
-                       return (1);
-       } else
-               return (1);
-       return (0);
-}
-
 int
 setconfcolor(const char *selector, const char *value, int flags)
 {
@@ -8653,12 +8608,10 @@ struct config_option configopt[] = {
        { "focus_mode",                 setconfvalue,   SWM_S_FOCUS_MODE },
        { "iconic_enabled",             setconfvalue,   SWM_S_ICONIC_ENABLED },
        { "java_workaround",            setconfvalue,   SWM_S_JAVA_WORKAROUND },
-       { "maximize_hide_bar",          setconfvalue,   SWM_S_MAXIMIZE_HIDE_BAR },
        { "keyboard_mapping",           setkeymapping,  0 },
        { "layout",                     setlayout,      0 },
+       { "maximize_hide_bar",          setconfvalue,   SWM_S_MAXIMIZE_HIDE_BAR },
        { "modkey",                     setconfmodkey,  0 },
-       { "move_button",                setconfmousebuttonmove, 0 },
-       { "resize_button",              setconfmousebuttonresize, 0 },
        { "program",                    setconfspawn,   0 },
        { "quirk",                      setconfquirk,   0 },
        { "region",                     setconfregion,  0 },
@@ -8675,10 +8628,12 @@ struct config_option configopt[] = {
        { "urgent_collapse",            setconfvalue,   SWM_S_URGENT_COLLAPSE },
        { "urgent_enabled",             setconfvalue,   SWM_S_URGENT_ENABLED },
        { "verbose_layout",             setconfvalue,   SWM_S_VERBOSE_LAYOUT },
+       { "warp_focus",                 setconfvalue,   SWM_S_WARP_FOCUS },
        { "warp_pointer",               setconfvalue,   SWM_S_WARP_POINTER },
        { "window_class_enabled",       setconfvalue,   SWM_S_WINDOW_CLASS_ENABLED },
        { "window_instance_enabled",    setconfvalue,   SWM_S_WINDOW_INSTANCE_ENABLED },
        { "window_name_enabled",        setconfvalue,   SWM_S_WINDOW_NAME_ENABLED },
+       { "workspace_clamp",            setconfvalue,   SWM_S_WORKSPACE_CLAMP },
        { "workspace_limit",            setconfvalue,   SWM_S_WORKSPACE_LIMIT },
        { "name",                       setconfvalue,   SWM_S_WORKSPACE_NAME },
 };
@@ -8824,12 +8779,6 @@ conf_load(const char *filename, int keymapping)
        if (line)
                free(line);
        fclose(config);
-
-       if (mouse_button_move == mouse_button_resize) {
-               add_startup_exception("%s: move and resize mouse buttons match",
-                   filename);
-       }
-
        DNPRINTF(SWM_D_CONF, "conf_load: end\n");
 
        return (0);