JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
More stacking cleanup, and fix the divide-by-zero reported by pyr.
[spectrwm.git] / scrotwm.c
index 6f891fe..cc01653 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -50,7 +50,7 @@
 
 static const char      *cvstag = "$scrotwm$";
 
-#define        SWM_VERSION     "0.7"
+#define        SWM_VERSION     "0.8"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -183,6 +183,7 @@ char                        *bar_fonts[] = {
 char                   *spawn_term[] = { "xterm", NULL };
 char                   *spawn_screenshot[] = { "screenshot.sh", NULL, NULL };
 char                   *spawn_lock[] = { "xlock", NULL };
+char                   *spawn_initscr[] = { "initscreen.sh", NULL };
 char                   *spawn_menu[] = { "dmenu_run", "-fn", NULL, "-nb", NULL,
                            "-nf", NULL, "-sb", NULL, "-sf", NULL, NULL };
 
@@ -316,10 +317,8 @@ union arg {
 #define SWM_ARG_ID_CYCLEWS_DOWN        (13)
 #define SWM_ARG_ID_CYCLESC_UP  (14)
 #define SWM_ARG_ID_CYCLESC_DOWN        (15)
-#define SWM_ARG_ID_COLINC      (16)
-#define SWM_ARG_ID_COLDEC      (17)
-#define SWM_ARG_ID_ROWINC      (16)
-#define SWM_ARG_ID_ROWDEL      (17)
+#define SWM_ARG_ID_STACKINC    (16)
+#define SWM_ARG_ID_STACKDEC    (17)
 #define SWM_ARG_ID_SS_ALL      (0)
 #define SWM_ARG_ID_SS_WINDOW   (1)
 #define SWM_ARG_ID_DONTCENTER  (0)
@@ -332,14 +331,16 @@ struct quirk {
        char                    *class;
        char                    *name;
        unsigned long           quirk;
-#define SWM_Q_FLOAT            (1<<0)
-#define SWM_Q_TRANSSZ          (1<<1)
+#define SWM_Q_FLOAT            (1<<0)  /* float this window */
+#define SWM_Q_TRANSSZ          (1<<1)  /* transiend window size too small */
+#define SWM_Q_ANYWHERE         (1<<2)  /* don't position this window */
 } quirks[] = {
        { "MPlayer",            "xv",           SWM_Q_FLOAT },
        { "OpenOffice.org 2.4", "VCLSalFrame",  SWM_Q_FLOAT },
        { "OpenOffice.org 3.0", "VCLSalFrame",  SWM_Q_FLOAT },
        { "Firefox-bin",        "firefox-bin",  SWM_Q_TRANSSZ},
-       { NULL,         NULL,           0},
+       { "Gimp",               "gimp",         SWM_Q_FLOAT | SWM_Q_ANYWHERE},
+       { NULL,                 NULL,           0},
 };
 
 /* events */
@@ -1345,6 +1346,8 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
 
        if (stacks > winno - mwin)
                stacks = winno - mwin;
+       if (stacks < 1)
+               stacks = 1;
 
        h_slice = r_g.h / SWM_H_SLICE;
        if (mwin && winno > mwin) {
@@ -1372,12 +1375,9 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
                if (flip) 
                        win_g.x += r_g.w - msize;
        } else {
-               if (stacks > 1) {
-                       colno = split = (winno - mwin) / stacks;
-               } else {
-                       split = 0;
-                       colno = winno;
-               }
+               msize = -2;
+               colno = split = winno / stacks;
+               win_g.w = ((r_g.w - (stacks * 2) + 2) / stacks);
        }
        hrh = r_g.h / colno;
        extra = r_g.h - (colno * hrh);
@@ -1390,9 +1390,9 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
                        continue;
 
                if (split && i == split) {
-                       colno = (winno - split) / s;
-                       if (stacks == 1)
-                               colno += (winno - split) % s;
+                       colno = (winno - mwin) / stacks;
+                       if (s <= (winno - mwin) % stacks)
+                               colno++;
                        split = split + colno;
                        hrh = (r_g.h / colno);
                        extra = r_g.h - (colno * hrh);
@@ -1400,7 +1400,10 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip)
                                win_g.x = r_g.x;
                        else
                                win_g.x += win_g.w + 2;
-                       win_g.w = (r_g.w - (msize + 2) - (stacks * 2)) / stacks;
+                       win_g.w = (r_g.w - msize - (stacks * 2)) / stacks;
+                       if (s == 1)
+                               win_g.w += (r_g.w - msize - (stacks * 2)) %
+                                   stacks;
                        s--;
                        j = 0;
                }
@@ -1494,10 +1497,11 @@ vertical_config(struct workspace *ws, int id)
        case SWM_ARG_ID_MASTERDEL:
                if (ws->l_state.vertical_mwin > 0)
                        ws->l_state.vertical_mwin--;
-       case SWM_ARG_ID_COLINC:
+               break;
+       case SWM_ARG_ID_STACKINC:
                ws->l_state.vertical_stacks++;
                break;
-       case SWM_ARG_ID_COLDEC:
+       case SWM_ARG_ID_STACKDEC:
                if (ws->l_state.vertical_stacks > 1)
                        ws->l_state.vertical_stacks--;
                break;
@@ -1541,12 +1545,13 @@ horizontal_config(struct workspace *ws, int id)
                if (ws->l_state.horizontal_mwin > 0)
                        ws->l_state.horizontal_mwin--;
                break;
-       case SWM_ARG_ID_COLINC:
+       case SWM_ARG_ID_STACKINC:
                ws->l_state.horizontal_stacks++;
                break;
-       case SWM_ARG_ID_COLDEC:
+       case SWM_ARG_ID_STACKDEC:
                if (ws->l_state.horizontal_stacks > 1)
                        ws->l_state.horizontal_stacks--;
+               break;
        default:
                return;
        }
@@ -1715,8 +1720,8 @@ struct key {
        { MODKEY,               XK_l,           stack_config,   {.id = SWM_ARG_ID_MASTERGROW} },
        { MODKEY,               XK_comma,       stack_config,   {.id = SWM_ARG_ID_MASTERADD} },
        { MODKEY,               XK_period,      stack_config,   {.id = SWM_ARG_ID_MASTERDEL} },
-       { MODKEY | ShiftMask,   XK_comma,       stack_config,   {.id = SWM_ARG_ID_COLINC} },
-       { MODKEY | ShiftMask,   XK_period,      stack_config,   {.id = SWM_ARG_ID_COLDEC} },
+       { MODKEY | ShiftMask,   XK_comma,       stack_config,   {.id = SWM_ARG_ID_STACKINC} },
+       { MODKEY | ShiftMask,   XK_period,      stack_config,   {.id = SWM_ARG_ID_STACKDEC} },
        { MODKEY,               XK_Return,      swapwin,        {.id = SWM_ARG_ID_SWAPMAIN} },
        { MODKEY,               XK_j,           focus,          {.id = SWM_ARG_ID_FOCUSNEXT} },
        { MODKEY,               XK_k,           focus,          {.id = SWM_ARG_ID_FOCUSPREV} },
@@ -1760,6 +1765,7 @@ struct key {
        { MODKEY,               XK_t,           floating_toggle,{0} },
        { MODKEY | ShiftMask,   XK_v,           version,        {0} },
        { MODKEY | ShiftMask,   XK_Delete,      spawn,          {.argv = spawn_lock} },
+       { MODKEY | ShiftMask,   XK_i,           spawn,          {.argv = spawn_initscr} },
 };
 
 void
@@ -2072,6 +2078,7 @@ manage_window(Window id)
        struct swm_region       *r;
        long                    mask;
        const char              *errstr;
+       XWindowChanges          wc;
 
        if ((win = find_window(id)) != NULL)
                        return (win);   /* already being managed */
@@ -2147,11 +2154,33 @@ manage_window(Window id)
                }
        }
 
+       /* alter window position if quirky */
+       if (win->quirks & SWM_Q_ANYWHERE) {
+               win->manual = 1; /* don't center the quirky windows */
+               bzero(&wc, sizeof wc);
+               mask = 0;
+               if (win->g.y < bar_height) {
+                       win->g.y = wc.y = bar_height;
+                       mask |= CWY;
+               }
+               if (win->g.w + win->g.x > WIDTH(r)) {
+                       win->g.x = wc.x = WIDTH(win->ws->r) - win->g.w - 2;
+                       mask |= CWX;
+               }
+               wc.border_width = 1;
+               mask |= CWBorderWidth;
+               XConfigureWindow(display, win->id, mask, &wc);
+       }
+
        XSelectInput(display, id, EnterWindowMask | FocusChangeMask |
            PropertyChangeMask | StructureNotifyMask);
 
        set_win_state(win, NormalState);
 
+       /* floaters need to be mapped if they are in the current workspace */
+       if (win->floating && (ws->idx == r->ws->idx))
+               XMapRaised(display, win->id);
+
        /* make new win focused */
        focus_win(win);
 
@@ -2242,8 +2271,8 @@ configurerequest(XEvent *e)
                                        ev->value_mask |= CWY | CWHeight;
                                }
                        }
-                       if ((ev->value_mask & (CWX|CWY)) &&
-                           !(ev->value_mask & (CWWidth|CWHeight)))
+                       if ((ev->value_mask & (CWX | CWY)) &&
+                           !(ev->value_mask & (CWWidth | CWHeight)))
                                config_win(win);
                        XMoveResizeWindow(display, win->id,
                            win->g.x, win->g.y, win->g.w, win->g.h);
@@ -2323,6 +2352,7 @@ maprequest(XEvent *e)
        if (wa.override_redirect)
                return;
        manage_window(e->xmaprequest.window);
+
        stack();
 }
 
@@ -2763,7 +2793,8 @@ main(int argc, char *argv[])
                                        handler[e.type](&e);
                                else
                                        DNPRINTF(SWM_D_EVENT,
-                                           "unkown event: %d\n", e.type);
+                                           "win: %lu unknown event: %d\n",
+                                           e.xany.window, e.type);
                        } else {
                                switch (e.type - xrandr_eventbase) {
                                case RRScreenChangeNotify:
@@ -2771,7 +2802,8 @@ main(int argc, char *argv[])
                                        break;
                                default:
                                        DNPRINTF(SWM_D_EVENT,
-                                           "unkown event: %d\n", e.type);
+                                           "win: %lu unknown xrandr event: "
+                                           "%d\n", e.xany.window, e.type);
                                        break;
                                }
                        }