sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-bartabgroups-6.2.diff (7487B)


      1 From bac0e7d5f91be0a6d919396540d4e1d1009c2e8e Mon Sep 17 00:00:00 2001
      2 From: Miles Alan <m@milesalan.com>
      3 Date: Sat, 25 Jan 2020 21:56:31 -0600
      4 Subject: [PATCH] bartabgroups: Splits the titlebar area into into an
      5  mfact-respecting tabbar
      6 
      7 In tiling mode, two tab groups are shown divided at the mfact location.
      8 In monocole mode, one tab group is shown (which excludes floating windows).
      9 In floating mode, one tab group is shown (which includes floating windows).
     10 Clicking on a tab will focus that window.
     11 
     12 Adjust the config.def.h to change functionality and to make exceptions for the
     13 tab bar for custom layouts.
     14 ---
     15  config.def.h |  11 +++++
     16  dwm.c        | 112 ++++++++++++++++++++++++++++++++++++++++++++++-----
     17  2 files changed, 112 insertions(+), 11 deletions(-)
     18 
     19 diff --git a/config.def.h b/config.def.h
     20 index 1c0b587..e61bb55 100644
     21 --- a/config.def.h
     22 +++ b/config.def.h
     23 @@ -16,6 +16,8 @@ static const char *colors[][3]      = {
     24  	/*               fg         bg         border   */
     25  	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
     26  	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
     27 +	[SchemeTabActive]  = { col_gray2, col_gray3,  col_gray2 },
     28 +	[SchemeTabInactive]  = { col_gray1, col_gray3,  col_gray1 }
     29  };
     30  
     31  /* tagging */
     32 @@ -36,6 +38,15 @@ static const float mfact     = 0.55; /* factor of master area size [0.05..0.95]
     33  static const int nmaster     = 1;    /* number of clients in master area */
     34  static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */
     35  
     36 +/* Bartabgroups properties */
     37 +#define BARTAB_BORDERS 1       // 0 = off, 1 = on
     38 +#define BARTAB_BOTTOMBORDER 1  // 0 = off, 1 = on
     39 +#define BARTAB_TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on
     40 +#define BARTAB_TAGSPX 5        // # pixels for tag grid boxes
     41 +#define BARTAB_TAGSROWS 3      // # rows in tag grid (9 tags, e.g. 3x3)
     42 +static void (*bartabmonfns[])(Monitor *) = { monocle /* , customlayoutfn */ };
     43 +static void (*bartabfloatfns[])(Monitor *) = { NULL /* , customlayoutfn */ };
     44 +
     45  static const Layout layouts[] = {
     46  	/* symbol     arrange function */
     47  	{ "[]=",      tile },    /* first entry is default */
     48 diff --git a/dwm.c b/dwm.c
     49 index 4465af1..d567978 100644
     50 --- a/dwm.c
     51 +++ b/dwm.c
     52 @@ -59,7 +59,7 @@
     53  
     54  /* enums */
     55  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
     56 -enum { SchemeNorm, SchemeSel }; /* color schemes */
     57 +enum { SchemeNorm, SchemeSel, SchemeTabActive, SchemeTabInactive }; /* color schemes */
     58  enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
     59         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
     60         NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
     61 @@ -377,6 +377,98 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
     62  	return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
     63  }
     64  
     65 +void
     66 +bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive) {
     67 +	if (!c) return;
     68 +	int i, nclienttags = 0, nviewtags = 0;
     69 +
     70 +	drw_setscheme(drw, scheme[
     71 +		m->sel == c ? SchemeSel : (groupactive ? SchemeTabActive: SchemeTabInactive)
     72 +	]);
     73 +	drw_text(drw, x, 0, w, bh, lrpad / 2, c->name, 0);
     74 +
     75 +	// Floating win indicator
     76 +	if (c->isfloating) drw_rect(drw, x + 2, 2, 5, 5, 0, 0);
     77 +
     78 +	// Optional borders between tabs
     79 +	if (BARTAB_BORDERS) {
     80 +		XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBorder].pixel);
     81 +		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, 0, 1, bh);
     82 +		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w, 0, 1, bh);
     83 +	}
     84 +
     85 +	// Optional tags icons
     86 +	for (i = 0; i < LENGTH(tags); i++) {
     87 +		if ((m->tagset[m->seltags] >> i) & 1) { nviewtags++; }
     88 +		if ((c->tags >> i) & 1) { nclienttags++; }
     89 +	}
     90 +	if (BARTAB_TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1) {
     91 +		for (i = 0; i < LENGTH(tags); i++) {
     92 +			drw_rect(drw,
     93 +				( x + w - 2 - ((LENGTH(tags) / BARTAB_TAGSROWS) * BARTAB_TAGSPX)
     94 +					- (i % (LENGTH(tags)/BARTAB_TAGSROWS)) + ((i % (LENGTH(tags) / BARTAB_TAGSROWS)) * BARTAB_TAGSPX)
     95 +				),
     96 +				( 2 + ((i / (LENGTH(tags)/BARTAB_TAGSROWS)) * BARTAB_TAGSPX)
     97 +					- ((i / (LENGTH(tags)/BARTAB_TAGSROWS)))
     98 +				),
     99 +				BARTAB_TAGSPX, BARTAB_TAGSPX, (c->tags >> i) & 1, 0
    100 +			);
    101 +		}
    102 +	}
    103 +}
    104 +
    105 +void
    106 +battabclick(Monitor *m, Client *c, int passx, int x, int w, int unused) {
    107 +	if (passx >= x && passx <= x + w) {
    108 +		focus(c);
    109 +		restack(selmon);
    110 +	}
    111 +}
    112 +
    113 +void
    114 +bartabcalculate(
    115 +	Monitor *m, int offx, int sw, int passx,
    116 +	void(*tabfn)(Monitor *, Client *, int, int, int, int)
    117 +) {
    118 +	Client *c;
    119 +	int
    120 +		i, clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0,
    121 +		masteractive = 0, fulllayout = 0, floatlayout = 0,
    122 +		x, w, tgactive;
    123 +
    124 +	for (i = 0, c = m->clients; c; c = c->next) {
    125 +		if (!ISVISIBLE(c)) continue;
    126 +		if (c->isfloating) { clientsnfloating++; continue; }
    127 +		if (m->sel == c) { masteractive = i < m->nmaster; }
    128 +		if (i < m->nmaster) { clientsnmaster++; } else { clientsnstack++; }
    129 +		i++;
    130 +	}
    131 +	for (i = 0; i < LENGTH(bartabfloatfns); i++) if (m ->lt[m->sellt]->arrange == bartabfloatfns[i]) { floatlayout = 1; break; }
    132 +	for (i = 0; i < LENGTH(bartabmonfns); i++) if (m ->lt[m->sellt]->arrange == bartabmonfns[i]) { fulllayout = 1; break; }
    133 +	for (c = m->clients, i = 0; c; c = c->next) {
    134 +		if (!ISVISIBLE(c)) continue;
    135 +		if (clientsnmaster + clientsnstack == 0 || floatlayout) {
    136 +			 x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating)) * i);
    137 +			 w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating);
    138 +			 tgactive = 1;
    139 +		} else if (!c->isfloating && (fulllayout || ((clientsnmaster == 0) ^ (clientsnstack == 0)))) {
    140 +			 x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack)) * i);
    141 +			 w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack);
    142 +			 tgactive = 1;
    143 +		} else if (i < m->nmaster && !c->isfloating) {
    144 +			 x = offx + ((((m->mw * m->mfact) - offx) /clientsnmaster) * i);
    145 +			 w = ((m->mw * m->mfact) - offx) / clientsnmaster;
    146 +			 tgactive = masteractive;
    147 +		} else if (!c->isfloating) {
    148 +			 x = (m->mw * m->mfact) + ((((m->mw * (1 - m->mfact)) - sw) / clientsnstack) * (i - m->nmaster));
    149 +			 w = ((m->mw * (1 - m->mfact)) - sw) / clientsnstack;
    150 +			 tgactive = !masteractive;
    151 +		} else continue;
    152 +		tabfn(m, c, passx, x, w, tgactive);
    153 +		i++;
    154 +	}
    155 +}
    156 +
    157  void
    158  arrange(Monitor *m)
    159  {
    160 @@ -441,8 +533,8 @@ buttonpress(XEvent *e)
    161  			click = ClkLtSymbol;
    162  		else if (ev->x > selmon->ww - TEXTW(stext))
    163  			click = ClkStatusText;
    164 -		else
    165 -			click = ClkWinTitle;
    166 +		else // Focus clicked tab bar item
    167 +			bartabcalculate(selmon, x, TEXTW(stext) - lrpad + 2, ev->x, battabclick);
    168  	} else if ((c = wintoclient(ev->window))) {
    169  		focus(c);
    170  		restack(selmon);
    171 @@ -728,15 +820,13 @@ drawbar(Monitor *m)
    172  	drw_setscheme(drw, scheme[SchemeNorm]);
    173  	x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
    174  
    175 +	// Draw bartabgroups
    176 +	drw_rect(drw, x, 0, m->ww - sw - x, bh, 1, 1);
    177  	if ((w = m->ww - sw - x) > bh) {
    178 -		if (m->sel) {
    179 -			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
    180 -			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
    181 -			if (m->sel->isfloating)
    182 -				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
    183 -		} else {
    184 -			drw_setscheme(drw, scheme[SchemeNorm]);
    185 -			drw_rect(drw, x, 0, w, bh, 1, 1);
    186 +		bartabcalculate(m, x, sw, -1, bartabdraw);
    187 +		if (BARTAB_BOTTOMBORDER) {
    188 +			drw_setscheme(drw, scheme[SchemeTabActive]);
    189 +			drw_rect(drw, 0, bh - 1, m->ww, 1, 1, 0);
    190  		}
    191  	}
    192  	drw_map(drw, m->barwin, 0, 0, m->ww, bh);
    193 -- 
    194 2.23.1
    195