X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=3fb090f92ade9aec81c6473d5758fe1c32ff51a1;hb=3c99b00a532db0b6276b46b91efe48033fbdbfbf;hp=148bc79b25451a632c141a6283c729e5c2e01b2d;hpb=08390e53a1a807879e3c6fa5a40524be93ee3cb9;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index 148bc79..3fb090f 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -267,8 +267,10 @@ struct workspace { struct { int horizontal_msize; int horizontal_mwin; + int horizontal_stacks; int vertical_msize; int vertical_mwin; + int vertical_stacks; } l_state; }; @@ -314,6 +316,10 @@ 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_SS_ALL (0) #define SWM_ARG_ID_SS_WINDOW (1) #define SWM_ARG_ID_DONTCENTER (0) @@ -864,7 +870,7 @@ restart(struct swm_region *r, union arg *args) struct swm_region * root_to_region(Window root) { - struct swm_region *r; + struct swm_region *r = NULL; Window rr, cr; int i, x, y, wx, wy; unsigned int mask; @@ -874,20 +880,17 @@ root_to_region(Window root) break; if (XQueryPointer(display, screens[i].root, - &rr, &cr, &x, &y, &wx, &wy, &mask) == False) { - /* if we can't query the pointer, grab the first region */ - r = TAILQ_FIRST(&screens[i].rl); - } else { - /* otherwise, choose a region based on pointer location */ - TAILQ_FOREACH(r, &screens[i].rl, entry) { + &rr, &cr, &x, &y, &wx, &wy, &mask) != False) { + /* choose a region based on pointer location */ + TAILQ_FOREACH(r, &screens[i].rl, entry) if (x >= X(r) && x <= X(r) + WIDTH(r) && y >= Y(r) && y <= Y(r) + HEIGHT(r)) break; - } - - if (r == NULL) - r = TAILQ_FIRST(&screens[i].rl); } + + if (r == NULL) + r = TAILQ_FIRST(&screens[i].rl); + return (r); } @@ -1307,7 +1310,7 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) XWindowChanges wc; struct swm_geometry win_g, r_g = *g; struct ws_win *win, *winfocus; - int i, j, w_inc, h_inc, w_base, h_base; + int i, j, s, w_inc, h_inc, w_base, h_base, stacks; int hrh, extra, h_slice, last_h = 0; int split, colno, winno, mwin, msize, mscale; int remain, missing, v_slice;; @@ -1329,22 +1332,27 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) w_base = win->sh.base_width; mwin = ws->l_state.horizontal_mwin; mscale = ws->l_state.horizontal_msize; + stacks = ws->l_state.horizontal_stacks; SWAPXY(&r_g); } else { w_inc = win->sh.height_inc; w_base = win->sh.base_height; mwin = ws->l_state.vertical_mwin; mscale = ws->l_state.vertical_msize; + stacks = ws->l_state.vertical_stacks; } win_g = r_g; + if (stacks > winno - mwin) + stacks = winno - mwin; + h_slice = r_g.h / SWM_H_SLICE; if (mwin && winno > mwin) { v_slice = r_g.w / SWM_V_SLICE; split = mwin; colno = split; - msize = v_slice * mscale; + win_g.w = v_slice * mscale; if (w_inc > 1 && w_inc < v_slice) { /* adjust for window's requested size increment */ @@ -1360,32 +1368,44 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) } } - win_g.w = msize; + msize = win_g.w; if (flip) win_g.x += r_g.w - msize; } else { - colno = winno; - split = 0; + if (stacks > 1) { + colno = split = (winno - mwin) / stacks; + } else { + split = 0; + colno = winno; + } } hrh = r_g.h / colno; extra = r_g.h - (colno * hrh); win_g.h = hrh - 2; /* stack all the tiled windows */ - i = j = 0; + i = j = 0, s = stacks; TAILQ_FOREACH(win, &ws->winlist, entry) { if (win->transient != 0 || win->floating != 0) continue; if (split && i == split) { - colno = winno - split; + colno = (winno - mwin) / stacks; + if (s <= (winno - mwin) % stacks) + colno++; + split = split + colno; hrh = (r_g.h / colno); extra = r_g.h - (colno * hrh); if (flip) win_g.x = r_g.x; else - win_g.x += msize + 2; - win_g.w = r_g.w - (msize + 2); + win_g.x += win_g.w + 2; + win_g.w = (((r_g.w - (msize + 2)) - + ((stacks - 1) * 2)) / stacks); + if (s == 1) + win_g.w += (((r_g.w - (msize + 2)) - + ((stacks - 1) * 2)) % stacks); + s--; j = 0; } win_g.h = hrh - 2; @@ -1462,6 +1482,7 @@ vertical_config(struct workspace *ws, int id) case SWM_ARG_ID_STACKINIT: ws->l_state.vertical_msize = SWM_V_SLICE / 2; ws->l_state.vertical_mwin = 1; + ws->l_state.vertical_stacks = 1; break; case SWM_ARG_ID_MASTERSHRINK: if (ws->l_state.vertical_msize > 1) @@ -1477,6 +1498,12 @@ 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: + ws->l_state.vertical_stacks++; + break; + case SWM_ARG_ID_COLDEC: + if (ws->l_state.vertical_stacks > 1) + ws->l_state.vertical_stacks--; break; default: return; @@ -1501,6 +1528,7 @@ horizontal_config(struct workspace *ws, int id) case SWM_ARG_ID_STACKINIT: ws->l_state.horizontal_mwin = 1; ws->l_state.horizontal_msize = SWM_H_SLICE / 2; + ws->l_state.horizontal_stacks = 1; break; case SWM_ARG_ID_MASTERSHRINK: if (ws->l_state.horizontal_msize > 1) @@ -1517,6 +1545,12 @@ 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: + ws->l_state.horizontal_stacks++; + break; + case SWM_ARG_ID_COLDEC: + if (ws->l_state.horizontal_stacks > 1) + ws->l_state.horizontal_stacks--; default: return; } @@ -1685,6 +1719,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, 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} }, @@ -2136,6 +2172,7 @@ unmanage_window(struct ws_win *win) DNPRINTF(SWM_D_MISC, "unmanage_window: %lu\n", win->id); + /* don't unmanage if we are switching workspaces */ ws = win->ws; if (ws->restack) return; @@ -2412,7 +2449,7 @@ void new_region(struct swm_screen *s, int x, int y, int w, int h) { struct swm_region *r, *n; - struct workspace *ws; + struct workspace *ws = NULL; int i; DNPRINTF(SWM_D_MISC, "new region: screen[%d]:%dx%d+%d+%d\n", @@ -2427,7 +2464,6 @@ new_region(struct swm_screen *s, int x, int y, int w, int h) (X(r) + WIDTH(r)) > x && Y(r) < (y + h) && (Y(r) + HEIGHT(r)) > y) { - r->ws->r = NULL; XDestroyWindow(display, r->bar_window); TAILQ_REMOVE(&s->rl, r, entry); TAILQ_INSERT_TAIL(&s->orl, r, entry); @@ -2463,10 +2499,11 @@ new_region(struct swm_screen *s, int x, int y, int w, int h) ws = &s->ws[i]; break; } - if (ws == NULL) - errx(1, "no free workspaces\n"); } + if (ws == NULL) + errx(1, "no free workspaces\n"); + X(r) = x; Y(r) = y; WIDTH(r) = w; @@ -2485,12 +2522,15 @@ scan_xrandr(int i) XRRCrtcInfo *ci; XRRScreenResources *sr; int c; + int ncrtc = 0; #endif /* SWM_XRR_HAS_CRTC */ struct swm_region *r; - int ncrtc = 0; - /* remove any old regions */ + if (i >= ScreenCount(display)) + errx(1, "invalid screen"); + + /* remove any old regions */ while ((r = TAILQ_FIRST(&screens[i].rl)) != NULL) { r->ws->r = NULL; XDestroyWindow(display, r->bar_window); @@ -2534,14 +2574,13 @@ scan_xrandr(int i) } void -screenchange(XEvent *e) -{ +screenchange(XEvent *e) { XRRScreenChangeNotifyEvent *xe = (XRRScreenChangeNotifyEvent *)e; struct swm_region *r; struct ws_win *win; int i; - DNPRINTF(SWM_D_EVENT, "screenchange: %d\n", xe->root); + DNPRINTF(SWM_D_EVENT, "screenchange: %lu\n", xe->root); if (!XRRUpdateConfiguration(e)) return; @@ -2568,7 +2607,6 @@ setup_screens(void) { Window d1, d2, *wins = NULL; XWindowAttributes wa; - struct swm_region *r; unsigned int no; int i, j, k; int errorbase, major, minor; @@ -2624,37 +2662,34 @@ setup_screens(void) if (!XQueryTree(display, screens[i].root, &d1, &d2, &wins, &no)) continue; + scan_xrandr(i); + if (xrandr_support) XRRSelectInput(display, screens[i].root, RRScreenChangeNotifyMask); - scan_xrandr(i); - /* attach windows to a region */ /* normal windows */ - if ((r = TAILQ_FIRST(&screens[i].rl)) == NULL) - errx(1, "no regions on screen %d", i); - - for (i = 0; i < no; i++) { - XGetWindowAttributes(display, wins[i], &wa); - if (!XGetWindowAttributes(display, wins[i], &wa) || + for (j = 0; j < no; j++) { + XGetWindowAttributes(display, wins[j], &wa); + if (!XGetWindowAttributes(display, wins[j], &wa) || wa.override_redirect || - XGetTransientForHint(display, wins[i], &d1)) + XGetTransientForHint(display, wins[j], &d1)) continue; if (wa.map_state == IsViewable || - getstate(wins[i]) == NormalState) - manage_window(wins[i]); + getstate(wins[j]) == NormalState) + manage_window(wins[j]); } /* transient windows */ - for (i = 0; i < no; i++) { - if (!XGetWindowAttributes(display, wins[i], &wa)) + for (j = 0; j < no; j++) { + if (!XGetWindowAttributes(display, wins[j], &wa)) continue; - if (XGetTransientForHint(display, wins[i], &d1) && - (wa.map_state == IsViewable || getstate(wins[i]) == + if (XGetTransientForHint(display, wins[j], &d1) && + (wa.map_state == IsViewable || getstate(wins[j]) == NormalState)) - manage_window(wins[i]); + manage_window(wins[j]); } if (wins) { XFree(wins); @@ -2725,7 +2760,7 @@ main(int argc, char *argv[]) bar_alarm = 0; bar_update(); } - while(XPending(display)) { + while (XPending(display)) { XNextEvent(display, &e); if (e.type < LASTEvent) { if (handler[e.type]) @@ -2735,7 +2770,6 @@ main(int argc, char *argv[]) "unkown event: %d\n", e.type); } else { switch (e.type - xrandr_eventbase) { - case RRNotify: case RRScreenChangeNotify: screenchange(&e); break;