From 3425d4bda4641a1ca3082361ba756947f029fa8a Mon Sep 17 00:00:00 2001 From: Bryson Steck Date: Mon, 7 Feb 2022 11:54:51 -0700 Subject: [PATCH] saving changes before redoing --- .gitignore | 2 +- config.def.h | 9 ++ config.h | 41 ++++++-- drw.c | 1 + dwm | Bin 66192 -> 0 bytes dwm.1 | 33 +++++-- dwm.c | 263 ++++++++++++++++++++++++++++++++++++++++++--------- 7 files changed, 286 insertions(+), 63 deletions(-) delete mode 100755 dwm diff --git a/.gitignore b/.gitignore index 874c63c..0564216 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ *.o - +/patches diff --git a/config.def.h b/config.def.h index 08cfbd4..9f840d6 100644 --- a/config.def.h +++ b/config.def.h @@ -6,6 +6,13 @@ static const unsigned int gappx = 6; /* gaps between windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ +/* Display modes of the tab bar: never shown, always shown, shown only in */ +/* monocle mode in the presence of several windows. */ +/* Modes after showtab_nmodes are disabled. */ +enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; +static const int showtab = showtab_auto; /* Default tab bar show mode */ +static const int toptab = False; /* False means bottom tab bar */ + static const char *fonts[] = { "monospace:size=10" }; static const char dmenufont[] = "monospace:size=10"; static const char col_gray1[] = "#222222"; @@ -66,6 +73,7 @@ static Key keys[] = { { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_w, tabmode, {-1} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_i, incnmaster, {.i = +1 } }, @@ -113,5 +121,6 @@ static Button buttons[] = { { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, }; diff --git a/config.h b/config.h index ffd2d4c..cb2f1b3 100644 --- a/config.h +++ b/config.h @@ -1,14 +1,15 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -static const unsigned int borderpx = 0; /* border pixel of windows */ +static const unsigned int borderpx = 3; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 0; /* 0 means bottom bar */ -static const char *fonts[] = { "Roboto:size=14" }; +static const char *fonts[] = { "Roboto:size=14", "emoji:size=14" }; static const char dmenufont[] = "Roboto:size=14"; static const char col_turquoise[] = "#00776C"; static const char col_black[] = "#000000"; +static const char col_black_border[] = "#101010"; static const char col_gray1[] = "#222222"; static const char col_gray1_5[] = "#333333"; static const char col_gray2[] = "#444444"; @@ -21,19 +22,32 @@ static const char col_nord2[] = "#434c5e"; static const char col_nord3[] = "#4c566a"; static const char col_nord4[] = "#d8dee9"; static const char col_nord10[] = "#5e81ac"; +static const char col_white1[] = "#DBDBDD"; +static const char col_white2[] = "#FFFFFF"; +static const char col_purple1[] = "#02060F"; +static const char col_purple2[] = "#0D0224"; static const char col_blue[] = "#144982"; +static const char col_blue2[] = "#143968"; +static const char col_orange[] = "#F59549"; +static const char col_other[] = "#191C21"; static const char col_yellow[] = "#D3AD66"; static const char col_warm_white[] = "#DCD6B8"; static const unsigned int gappx = 6; +/* Display modes of the tab bar: never shown, always shown, shown only in */ +/* monocle mode in the presence of several windows. */ +/* Modes after showtab_nmodes are disabled. */ +enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; +static const int showtab = showtab_auto; /* Default tab bar show mode */ +static const int toptab = False; /* False means bottom tab bar */ static const char *colors[][3] = { /* fg bg border */ - [SchemeNorm] = { col_nord4, col_black, col_black }, - [SchemeSel] = { col_nord4, col_gray1, col_black }, + [SchemeNorm] = { col_nord4, col_black, col_black_border }, + [SchemeSel] = { col_nord4, col_gray1, col_blue }, }; /* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5" }; +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8" }; static const Rule rules[] = { /* xprop(1): @@ -49,6 +63,7 @@ static const Rule rules[] = { { "Wiimmfi-RPC v1.7.5",NULL,NULL, 0, 1, -1 }, { "minecraft-launcher",NULL,NULL, 0, 1, -1 }, { "nitrogen", NULL, NULL, 0, 1, -1 }, + { "Galculator",NULL, NULL, 0, 1, -1 }, }; /* layout(s) */ @@ -78,15 +93,22 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run_history", "-b", "-m", dmenumon, "-fn", dmenufont, "-nb", col_black, "-nf", col_gray3, "-sb", col_blue, "-sf", col_gray4, NULL }; -static const char *termcmd[] = { "alacritty", NULL }; +static const char *termcmd[] = { "spawn-alacritty.sh", NULL }; static const char *brightnessup[] = { "brightness-up", NULL }; static const char *brightnessdown[] = { "brightness-down", NULL }; +static const char *screenshooter[] = { "xfce4-screenshooter", NULL }; +static const char *volup[] = { "volup.sh", NULL }; +static const char *voldown[] = { "voldown.sh", NULL }; +static const char *volmute[] = { "volmute.sh", NULL }; +static const char *firefox[] = { "firefox", "--new-window", NULL }; static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY|ShiftMask, XK_f, spawn, {.v = firefox } }, { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_w, tabmode, {-1} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_i, incnmaster, {.i = +1 } }, @@ -109,6 +131,10 @@ static Key keys[] = { { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, { MODKEY, XK_F4, spawn, {.v = brightnessup } }, { MODKEY, XK_F3, spawn, {.v = brightnessdown } }, + { MODKEY, XK_Print, spawn, {.v = screenshooter } }, + { MODKEY, XK_F9, spawn, {.v = volmute } }, + { MODKEY, XK_F10, spawn, {.v = voldown } }, + { MODKEY, XK_F11, spawn, {.v = volup } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) @@ -118,7 +144,7 @@ static Key keys[] = { TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY|ShiftMask, XK_BackSpace, quit, {0} }, }; /* button definitions */ @@ -136,5 +162,6 @@ static Button buttons[] = { { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, }; diff --git a/drw.c b/drw.c index 4cdbcbe..190420f 100644 --- a/drw.c +++ b/drw.c @@ -203,6 +203,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname) DefaultColormap(drw->dpy, drw->screen), clrname, dest)) die("error, cannot allocate color '%s'", clrname); + dest->pixel |= 0xff << 24; } /* Wrapper to create color schemes. The caller has to call free(3) on the diff --git a/dwm b/dwm deleted file mode 100755 index 03b3a83bf39c2a0780e296222a5affd78fad17aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66192 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

fj>w1 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 diff --git a/dwm.1 b/dwm.1 index ddc8321..7752444 100644 --- a/dwm.1 +++ b/dwm.1 @@ -20,14 +20,22 @@ layout applied. Windows are grouped by tags. Each window can be tagged with one or multiple tags. Selecting certain tags displays all windows with these tags. .P -Each screen contains a small status bar which displays all available tags, the -layout, the title of the focused window, and the text read from the root window -name property, if the screen is focused. A floating window is indicated with an -empty square and a maximised floating window is indicated with a filled square -before the windows title. The selected tags are indicated with a different -color. The tags of the focused window are indicated with a filled square in the -top left corner. The tags which are applied to one or more windows are -indicated with an empty square in the top left corner. +Each screen contains two small status bars. +.P +One bar displays all available tags, the layout, the title of the focused +window, and the text read from the root window name property, if the screen is +focused. A floating window is indicated with an empty square and a maximised +floating window is indicated with a filled square before the windows title. The +selected tags are indicated with a different color. The tags of the focused +window are indicated with a filled square in the top left corner. The tags +which are applied to one or more windows are indicated with an empty square in +the top left corner. +.P +Another bar contains a tab for each window of the current view and allows +navigation between windows, especially in the monocle mode. The different +display modes of this bar are described under the Mod1\-w Keybord command +section. When a single tag is selected, this tag is indicated in the left corner +of the tab bar. .P dwm draws a small border around windows to indicate the focus state. .SH OPTIONS @@ -44,7 +52,8 @@ command. .TP .B Button1 click on a tag label to display all windows with that tag, click on the layout -label toggles between tiled and floating layout. +label toggles between tiled and floating layout, click on a window name in the +tab bar brings focus to that window. .TP .B Button3 click on a tag label adds/removes all windows with that tag to/from the view. @@ -110,6 +119,12 @@ Increase master area size. .B Mod1\-h Decrease master area size. .TP +.B Mod1\-w +Cycle over the tab bar display modes: never displayed, always displayed, +displayed only in monocle mode when the view contains more than one window (auto +mode). Some display modes can be disabled in the configuration, config.h. In +the default configuration only "never" and "auto" display modes are enabled. +.TP .B Mod1\-Return Zooms/cycles focused window to/from master area (tiled layouts only). .TP diff --git a/dwm.c b/dwm.c index 496e52b..e9b6234 100644 --- a/dwm.c +++ b/dwm.c @@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, +enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ typedef union { @@ -111,24 +111,32 @@ typedef struct { void (*arrange)(Monitor *); } Layout; +#define MAXTABS 50 + struct Monitor { char ltsymbol[16]; float mfact; int nmaster; int num; int by; /* bar geometry */ + int ty; /* tab bar geometry */ int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; int showbar; + int showtab; int topbar; + int toptab; Client *clients; Client *sel; Client *stack; Monitor *next; Window barwin; + Window tabwin; + int ntabs; + int tab_widths[MAXTABS]; const Layout *lt[2]; }; @@ -165,10 +173,13 @@ static void drawbar(Monitor *m); static void drawbars(void); static void enternotify(XEvent *e); static void expose(XEvent *e); +static void drawtab(Monitor *m); +static void drawtabs(void); static void focus(Client *c); static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); +static void focuswin(const Arg* arg); static Atom getatomprop(Client *c, Atom prop); static int getrootptr(int *x, int *y); static long getstate(Window w); @@ -207,6 +218,7 @@ static void seturgent(Client *c, int urg); static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); +static void tabmode(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *); @@ -241,6 +253,7 @@ static char stext[256]; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ +static int th = 0; /* tab bar geometry */ static int lrpad; /* sum of left and right padding for text */ static int (*xerrorxlib)(Display *, XErrorEvent *); static unsigned int numlockmask = 0; @@ -393,8 +406,9 @@ arrange(Monitor *m) } void -arrangemon(Monitor *m) -{ +arrangemon(Monitor *m) { + updatebarpos(m); + XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); if (m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); @@ -444,7 +458,24 @@ buttonpress(XEvent *e) click = ClkStatusText; else click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { + } + if(ev->window == selmon->tabwin) { + i = 0; x = 0; + for(c = selmon->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + x += selmon->tab_widths[i]; + if (ev->x > x) + ++i; + else + break; + if(i >= m->ntabs) break; + } + if(c) { + click = ClkTabBar; + arg.ui = i; + } + } + else if((c = wintoclient(ev->window))) { focus(c); restack(selmon); XAllowEvents(dpy, ReplayPointer, CurrentTime); @@ -452,8 +483,9 @@ buttonpress(XEvent *e) } for (i = 0; i < LENGTH(buttons); i++) if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ + buttons[i].func(((click == ClkTagBar || click == ClkTabBar) && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); + } } void @@ -507,6 +539,8 @@ cleanupmon(Monitor *mon) } XUnmapWindow(dpy, mon->barwin); XDestroyWindow(dpy, mon->barwin); + XUnmapWindow(dpy, mon->tabwin); + XDestroyWindow(dpy, mon->tabwin); free(mon); } @@ -638,7 +672,10 @@ createmon(void) m->mfact = mfact; m->nmaster = nmaster; m->showbar = showbar; + m->showtab = showtab; m->topbar = topbar; + m->toptab = toptab; + m->ntabs = 0; m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); @@ -752,6 +789,105 @@ drawbars(void) drawbar(m); } +void +drawtabs(void) { + Monitor *m; + + for(m = mons; m; m = m->next) + drawtab(m); +} + +static int +cmpint(const void *p1, const void *p2) { + /* The actual arguments to this function are "pointers to + pointers to char", but strcmp(3) arguments are "pointers + to char", hence the following cast plus dereference */ + return *((int*) p1) > * (int*) p2; +} + + +void +drawtab(Monitor *m) { + Client *c; + int i; + int itag = -1; + char view_info[50]; + int view_info_w = 0; + int sorted_label_widths[MAXTABS]; + int tot_width; + int maxsize = bh; + int x = 0; + int w = 0; + + //view_info: indicate the tag which is displayed in the view + for(i = 0; i < LENGTH(tags); ++i){ + if((selmon->tagset[selmon->seltags] >> i) & 1) { + if(itag >=0){ //more than one tag selected + itag = -1; + break; + } + itag = i; + } + } + + if(0 <= itag && itag < LENGTH(tags)){ + snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); + } else { + strncpy(view_info, "[...]", sizeof view_info); + } + view_info[sizeof(view_info) - 1 ] = 0; + view_info_w = TEXTW(view_info); + tot_width = view_info_w; + + /* Calculates number of labels and their width */ + m->ntabs = 0; + for(c = m->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + m->tab_widths[m->ntabs] = TEXTW(c->name); + tot_width += m->tab_widths[m->ntabs]; + ++m->ntabs; + if(m->ntabs >= MAXTABS) break; + } + + if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated + memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); + qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); + tot_width = view_info_w; + for(i = 0; i < m->ntabs; ++i){ + if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) + break; + tot_width += sorted_label_widths[i]; + } + maxsize = (m->ww - tot_width) / (m->ntabs - i); + } else{ + maxsize = m->ww; + } + i = 0; + for(c = m->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + if(i >= m->ntabs) break; + if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; + w = m->tab_widths[i]; + drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, th, 0, c->name, 0); + x += w; + ++i; + } + + drw_setscheme(drw, scheme[SchemeNorm]); + + /* cleans interspace between window names and current viewed tag label */ + w = m->ww - view_info_w - x; + drw_text(drw, x, 0, w, th, 0, "", 0); + + /* view info */ + x += w; + w = view_info_w; + drw_text(drw, x, 0, w, th, 0, view_info, 0); + + drw_map(drw, m->tabwin, 0, 0, m->ww, th); +} + void enternotify(XEvent *e) { @@ -777,8 +913,10 @@ expose(XEvent *e) Monitor *m; XExposeEvent *ev = &e->xexpose; - if (ev->count == 0 && (m = wintomon(ev->window))) + if(ev->count == 0 && (m = wintomon(ev->window))){ drawbar(m); + drawtab(m); + } } void @@ -804,6 +942,7 @@ focus(Client *c) } selmon->sel = c; drawbars(); + drawtabs(); } /* there are some broken focus acquiring clients needing extra handling */ @@ -828,6 +967,8 @@ focusmon(const Arg *arg) unfocus(selmon->sel, 0); selmon = m; focus(NULL); + if (selmon->sel) + XWarpPointer(dpy, None, selmon->sel->win, 0, 0, 0, 0, selmon->sel->w/2, selmon->sel->h/2); } void @@ -853,9 +994,23 @@ focusstack(const Arg *arg) if (c) { focus(c); restack(selmon); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); } } +void +focuswin(const Arg* arg){ + int iwin = arg->i; + Client* c = NULL; + for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ + if(ISVISIBLE(c)) --iwin; + }; + if(c) { + focus(c); + restack(selmon); + } +} + Atom getatomprop(Client *c, Atom prop) { @@ -1234,12 +1389,14 @@ propertynotify(XEvent *e) case XA_WM_HINTS: updatewmhints(c); drawbars(); + drawtabs(); break; } if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { updatetitle(c); if (c == c->mon->sel) drawbar(c->mon); + drawtab(c->mon); } if (ev->atom == netatom[NetWMWindowType]) updatewindowtype(c); @@ -1277,36 +1434,13 @@ void resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; - unsigned int n; - unsigned int gapoffset; - unsigned int gapincr; - Client *nbc; + c->oldx = c->x; c->x = wc.x = x; + c->oldy = c->y; c->y = wc.y = y; + c->oldw = c->w; c->w = wc.width = w; + c->oldh = c->h; c->h = wc.height = h; wc.border_width = c->bw; - /* Get number of clients for the selected monitor */ - for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++); - - /* Do nothing if layout is floating */ - if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) { - gapincr = gapoffset = 0; - } else { - /* Remove border and gap if layout is monocle or only one client */ - if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) { - gapoffset = 0; - gapincr = -2 * borderpx; - wc.border_width = 0; - } else { - gapoffset = gappx; - gapincr = 2 * gappx; - } - } - - c->oldx = c->x; c->x = wc.x = x + gapoffset; - c->oldy = c->y; c->y = wc.y = y + gapoffset; - c->oldw = c->w; c->w = wc.width = w - gapincr; - c->oldh = c->h; c->h = wc.height = h - gapincr; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); configure(c); XSync(dpy, False); @@ -1377,6 +1511,7 @@ restack(Monitor *m) XWindowChanges wc; drawbar(m); + drawtab(m); if (!m->sel) return; if (m->sel->isfloating || !m->lt[m->sellt]->arrange) @@ -1571,6 +1706,7 @@ setup(void) die("no fonts could be loaded."); lrpad = drw->fonts->h; bh = drw->fonts->h + 2; + th = bh; updategeom(); /* init atoms */ utf8string = XInternAtom(dpy, "UTF8_STRING", False); @@ -1698,7 +1834,7 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int i, n, h, mw, my, ty; + unsigned int i, n, h, r, g = 0, mw, my, ty; Client *c; for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); @@ -1706,20 +1842,20 @@ tile(Monitor *m) return; if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; + mw = m->nmaster ? (m->ww - (g = gappx)) * m->mfact : 0; else mw = m->ww; for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); + r = MIN(n, m->nmaster) - i; + h = (m->wh - my - gappx * (r - 1)) / r; resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - if (my + HEIGHT(c) < m->wh) - my += HEIGHT(c); + my += HEIGHT(c) + gappx; } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - if (ty + HEIGHT(c) < m->wh) - ty += HEIGHT(c); + r = n - i; + h = (m->wh - ty - gappx * (r - 1)) / r; + resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), False); + ty += HEIGHT(c) + gappx; } } @@ -1732,6 +1868,17 @@ togglebar(const Arg *arg) arrange(selmon); } +void +tabmode(const Arg *arg) +{ + if(arg && arg->i >= 0) + selmon->showtab = arg->ui % showtab_nmodes; + else + selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; + arrange(selmon); +} + + void togglefloating(const Arg *arg) { @@ -1843,6 +1990,11 @@ updatebars(void) CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); XMapRaised(dpy, m->barwin); + m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->tabwin); XSetClassHint(dpy, m->barwin, &ch); } } @@ -1850,14 +2002,33 @@ updatebars(void) void updatebarpos(Monitor *m) { + Client *c; + int nvis = 0; + m->wy = m->my; m->wh = m->mh; if (m->showbar) { m->wh -= bh; m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else + if ( m->topbar ) + m->wy += bh; + } else { m->by = -bh; + } + + for(c = m->clients; c; c = c->next) { + if(ISVISIBLE(c)) ++nvis; + } + + if(m->showtab == showtab_always + || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))) { + m->wh -= th; + m->ty = m->toptab ? m->wy : m->wy + m->wh; + if ( m->toptab ) + m->wy += th; + } else { + m->ty = -th; + } } void @@ -2094,7 +2265,7 @@ wintomon(Window w) if (w == root && getrootptr(&x, &y)) return recttomon(x, y, 1, 1); for (m = mons; m; m = m->next) - if (w == m->barwin) + if (w == m->barwin || w == m->tabwin) return m; if ((c = wintoclient(w))) return c->mon;