dwm-bartabgroups-6.2.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) 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