dwm-awesomebar-20200907-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-awesomebar-20200907-6.2.diff (12533B)
       ---
            1 diff --git a/config.def.h b/config.def.h
            2 index 1c0b587..bb8f3f7 100644
            3 --- a/config.def.h
            4 +++ b/config.def.h
            5 @@ -16,6 +16,7 @@ static const char *colors[][3]      = {
            6          /*               fg         bg         border   */
            7          [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
            8          [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
            9 +        [SchemeHid]  = { col_cyan,  col_gray1, col_cyan  },
           10  };
           11  
           12  /* tagging */
           13 @@ -64,8 +65,10 @@ static Key keys[] = {
           14          { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
           15          { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
           16          { MODKEY,                       XK_b,      togglebar,      {0} },
           17 -        { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
           18 -        { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
           19 +        { MODKEY,                       XK_j,      focusstackvis,  {.i = +1 } },
           20 +        { MODKEY,                       XK_k,      focusstackvis,  {.i = -1 } },
           21 +        { MODKEY|ShiftMask,             XK_j,      focusstackhid,  {.i = +1 } },
           22 +        { MODKEY|ShiftMask,             XK_k,      focusstackhid,  {.i = -1 } },
           23          { MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
           24          { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
           25          { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
           26 @@ -84,6 +87,8 @@ static Key keys[] = {
           27          { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
           28          { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
           29          { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
           30 +        { MODKEY,                       XK_s,      show,           {0} },
           31 +        { MODKEY,                       XK_h,      hide,           {0} },
           32          TAGKEYS(                        XK_1,                      0)
           33          TAGKEYS(                        XK_2,                      1)
           34          TAGKEYS(                        XK_3,                      2)
           35 @@ -102,6 +107,7 @@ static Button buttons[] = {
           36          /* click                event mask      button          function        argument */
           37          { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
           38          { ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
           39 +        { ClkWinTitle,          0,              Button1,        togglewin,      {0} },
           40          { ClkWinTitle,          0,              Button2,        zoom,           {0} },
           41          { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
           42          { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
           43 diff --git a/dwm.c b/dwm.c
           44 index 4465af1..e780189 100644
           45 --- a/dwm.c
           46 +++ b/dwm.c
           47 @@ -50,6 +50,7 @@
           48  #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
           49                                 * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
           50  #define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
           51 +#define HIDDEN(C)               ((getstate(C->win) == IconicState))
           52  #define LENGTH(X)               (sizeof X / sizeof X[0])
           53  #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
           54  #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
           55 @@ -59,7 +60,7 @@
           56  
           57  /* enums */
           58  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
           59 -enum { SchemeNorm, SchemeSel }; /* color schemes */
           60 +enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */
           61  enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
           62         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
           63         NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
           64 @@ -117,6 +118,8 @@ struct Monitor {
           65          int nmaster;
           66          int num;
           67          int by;               /* bar geometry */
           68 +        int btw;              /* width of tasks portion of bar */
           69 +        int bt;               /* number of tasks */
           70          int mx, my, mw, mh;   /* screen size */
           71          int wx, wy, ww, wh;   /* window area  */
           72          unsigned int seltags;
           73 @@ -124,6 +127,7 @@ struct Monitor {
           74          unsigned int tagset[2];
           75          int showbar;
           76          int topbar;
           77 +        int hidsel;
           78          Client *clients;
           79          Client *sel;
           80          Client *stack;
           81 @@ -168,12 +172,16 @@ static void expose(XEvent *e);
           82  static void focus(Client *c);
           83  static void focusin(XEvent *e);
           84  static void focusmon(const Arg *arg);
           85 -static void focusstack(const Arg *arg);
           86 +static void focusstackvis(const Arg *arg);
           87 +static void focusstackhid(const Arg *arg);
           88 +static void focusstack(int inc, int vis);
           89  static int getrootptr(int *x, int *y);
           90  static long getstate(Window w);
           91  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
           92  static void grabbuttons(Client *c, int focused);
           93  static void grabkeys(void);
           94 +static void hide(const Arg *arg);
           95 +static void hidewin(Client *c);
           96  static void incnmaster(const Arg *arg);
           97  static void keypress(XEvent *e);
           98  static void killclient(const Arg *arg);
           99 @@ -203,6 +211,8 @@ static void setlayout(const Arg *arg);
          100  static void setmfact(const Arg *arg);
          101  static void setup(void);
          102  static void seturgent(Client *c, int urg);
          103 +static void show(const Arg *arg);
          104 +static void showwin(Client *c);
          105  static void showhide(Client *c);
          106  static void sigchld(int unused);
          107  static void spawn(const Arg *arg);
          108 @@ -213,6 +223,7 @@ static void togglebar(const Arg *arg);
          109  static void togglefloating(const Arg *arg);
          110  static void toggletag(const Arg *arg);
          111  static void toggleview(const Arg *arg);
          112 +static void togglewin(const Arg *arg);
          113  static void unfocus(Client *c, int setfocus);
          114  static void unmanage(Client *c, int destroyed);
          115  static void unmapnotify(XEvent *e);
          116 @@ -439,10 +450,25 @@ buttonpress(XEvent *e)
          117                          arg.ui = 1 << i;
          118                  } else if (ev->x < x + blw)
          119                          click = ClkLtSymbol;
          120 -                else if (ev->x > selmon->ww - TEXTW(stext))
          121 +                /* 2px right padding */
          122 +                else if (ev->x > selmon->ww - TEXTW(stext) + lrpad - 2)
          123                          click = ClkStatusText;
          124 -                else
          125 -                        click = ClkWinTitle;
          126 +                else {
          127 +                        x += blw;
          128 +                        c = m->clients;
          129 +
          130 +                        if (c) {
          131 +                                do {
          132 +                                        if (!ISVISIBLE(c))
          133 +                                                continue;
          134 +                                        else
          135 +                                                x += (1.0 / (double)m->bt) * m->btw;
          136 +                                } while (ev->x > x && (c = c->next));
          137 +
          138 +                                click = ClkWinTitle;
          139 +                                arg.v = c;
          140 +                        }
          141 +                }
          142          } else if ((c = wintoclient(ev->window))) {
          143                  focus(c);
          144                  restack(selmon);
          145 @@ -452,7 +478,7 @@ buttonpress(XEvent *e)
          146          for (i = 0; i < LENGTH(buttons); i++)
          147                  if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
          148                  && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
          149 -                        buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
          150 +                        buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
          151  }
          152  
          153  void
          154 @@ -695,7 +721,7 @@ dirtomon(int dir)
          155  void
          156  drawbar(Monitor *m)
          157  {
          158 -        int x, w, sw = 0;
          159 +        int x, w, sw = 0, n = 0, scm;
          160          int boxs = drw->fonts->h / 9;
          161          int boxw = drw->fonts->h / 6 + 2;
          162          unsigned int i, occ = 0, urg = 0;
          163 @@ -709,6 +735,8 @@ drawbar(Monitor *m)
          164          }
          165  
          166          for (c = m->clients; c; c = c->next) {
          167 +                if (ISVISIBLE(c))
          168 +                        n++;
          169                  occ |= c->tags;
          170                  if (c->isurgent)
          171                          urg |= c->tags;
          172 @@ -729,16 +757,37 @@ drawbar(Monitor *m)
          173          x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
          174  
          175          if ((w = m->ww - sw - x) > bh) {
          176 -                if (m->sel) {
          177 -                        drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
          178 -                        drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
          179 -                        if (m->sel->isfloating)
          180 -                                drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
          181 +                if (n > 0) {
          182 +                        int remainder = w % n;
          183 +                        int tabw = (1.0 / (double)n) * w + 1;
          184 +                        for (c = m->clients; c; c = c->next) {
          185 +                                if (!ISVISIBLE(c))
          186 +                                        continue;
          187 +                                if (m->sel == c)
          188 +                                        scm = SchemeSel;
          189 +                                else if (HIDDEN(c))
          190 +                                        scm = SchemeHid;
          191 +                                else
          192 +                                        scm = SchemeNorm;
          193 +                                drw_setscheme(drw, scheme[scm]);
          194 +
          195 +                                if (remainder >= 0) {
          196 +                                        if (remainder == 0) {
          197 +                                                tabw--;
          198 +                                        }
          199 +                                        remainder--;
          200 +                                }
          201 +                                drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0);
          202 +                                x += tabw;
          203 +                        }
          204                  } else {
          205                          drw_setscheme(drw, scheme[SchemeNorm]);
          206                          drw_rect(drw, x, 0, w, bh, 1, 1);
          207                  }
          208          }
          209 +
          210 +        m->bt = n;
          211 +        m->btw = w;
          212          drw_map(drw, m->barwin, 0, 0, m->ww, bh);
          213  }
          214  
          215 @@ -784,9 +833,17 @@ void
          216  focus(Client *c)
          217  {
          218          if (!c || !ISVISIBLE(c))
          219 -                for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
          220 -        if (selmon->sel && selmon->sel != c)
          221 +                for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext);
          222 +        if (selmon->sel && selmon->sel != c) {
          223                  unfocus(selmon->sel, 0);
          224 +
          225 +                if (selmon->hidsel) {
          226 +                        hidewin(selmon->sel);
          227 +                        if (c)
          228 +                                arrange(c->mon);
          229 +                        selmon->hidsel = 0;
          230 +                }
          231 +        }
          232          if (c) {
          233                  if (c->mon != selmon)
          234                          selmon = c->mon;
          235 @@ -830,28 +887,57 @@ focusmon(const Arg *arg)
          236  }
          237  
          238  void
          239 -focusstack(const Arg *arg)
          240 +focusstackvis(const Arg *arg)
          241 +{
          242 +        focusstack(arg->i, 0);
          243 +}
          244 +
          245 +void
          246 +focusstackhid(const Arg *arg)
          247 +{
          248 +        focusstack(arg->i, 1);
          249 +}
          250 +
          251 +void
          252 +focusstack(int inc, int hid)
          253  {
          254          Client *c = NULL, *i;
          255  
          256 -        if (!selmon->sel)
          257 +        if (!selmon->sel && !hid)
          258                  return;
          259 -        if (arg->i > 0) {
          260 -                for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
          261 +        if (!selmon->clients)
          262 +                return;
          263 +
          264 +        if (inc > 0) {
          265 +                if (selmon->sel)
          266 +                        for (c = selmon->sel->next;
          267 +                                         c && (!ISVISIBLE(c) || (!hid && HIDDEN(c)));
          268 +                                         c = c->next);
          269                  if (!c)
          270 -                        for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
          271 +                        for (c = selmon->clients;
          272 +                                         c && (!ISVISIBLE(c) || (!hid && HIDDEN(c)));
          273 +                                         c = c->next);
          274          } else {
          275 -                for (i = selmon->clients; i != selmon->sel; i = i->next)
          276 -                        if (ISVISIBLE(i))
          277 -                                c = i;
          278 +                if (selmon->sel) {
          279 +                        for (i = selmon->clients; i != selmon->sel; i = i->next)
          280 +                                if (ISVISIBLE(i) && !(!hid && HIDDEN(i)))
          281 +                                        c = i;
          282 +                } else
          283 +                        c = selmon->clients;
          284                  if (!c)
          285                          for (; i; i = i->next)
          286 -                                if (ISVISIBLE(i))
          287 +                                if (ISVISIBLE(i) && !(!hid && HIDDEN(i)))
          288                                          c = i;
          289          }
          290 +
          291          if (c) {
          292                  focus(c);
          293                  restack(selmon);
          294 +
          295 +                if (HIDDEN(c)) {
          296 +                        showwin(c);
          297 +                        c->mon->hidsel = 1;
          298 +                }
          299          }
          300  }
          301  
          302 @@ -963,6 +1049,36 @@ grabkeys(void)
          303          }
          304  }
          305  
          306 +void
          307 +hide(const Arg *arg)
          308 +{
          309 +        hidewin(selmon->sel);
          310 +        focus(NULL);
          311 +        arrange(selmon);
          312 +}
          313 +
          314 +void
          315 +hidewin(Client *c) {
          316 +        if (!c || HIDDEN(c))
          317 +                return;
          318 +
          319 +        Window w = c->win;
          320 +        static XWindowAttributes ra, ca;
          321 +
          322 +        // more or less taken directly from blackbox's hide() function
          323 +        XGrabServer(dpy);
          324 +        XGetWindowAttributes(dpy, root, &ra);
          325 +        XGetWindowAttributes(dpy, w, &ca);
          326 +        // prevent UnmapNotify events
          327 +        XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
          328 +        XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
          329 +        XUnmapWindow(dpy, w);
          330 +        setclientstate(c, IconicState);
          331 +        XSelectInput(dpy, root, ra.your_event_mask);
          332 +        XSelectInput(dpy, w, ca.your_event_mask);
          333 +        XUngrabServer(dpy);
          334 +}
          335 +
          336  void
          337  incnmaster(const Arg *arg)
          338  {
          339 @@ -1067,12 +1183,14 @@ manage(Window w, XWindowAttributes *wa)
          340          XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
          341                  (unsigned char *) &(c->win), 1);
          342          XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
          343 -        setclientstate(c, NormalState);
          344 +        if (!HIDDEN(c))
          345 +                setclientstate(c, NormalState);
          346          if (c->mon == selmon)
          347                  unfocus(selmon->sel, 0);
          348          c->mon->sel = c;
          349          arrange(c->mon);
          350 -        XMapWindow(dpy, c->win);
          351 +        if (!HIDDEN(c))
          352 +                XMapWindow(dpy, c->win);
          353          focus(NULL);
          354  }
          355  
          356 @@ -1195,7 +1313,7 @@ movemouse(const Arg *arg)
          357  Client *
          358  nexttiled(Client *c)
          359  {
          360 -        for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
          361 +        for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = c->next);
          362          return c;
          363  }
          364  
          365 @@ -1248,6 +1366,16 @@ propertynotify(XEvent *e)
          366  void
          367  quit(const Arg *arg)
          368  {
          369 +        // fix: reloading dwm keeps all the hidden clients hidden
          370 +        Monitor *m;
          371 +        Client *c;
          372 +        for (m = mons; m; m = m->next) {
          373 +                if (m) {
          374 +                        for (c = m->stack; c; c = c->next)
          375 +                                if (c && HIDDEN(c)) showwin(c);
          376 +                }
          377 +        }
          378 +
          379          running = 0;
          380  }
          381  
          382 @@ -1610,6 +1738,25 @@ seturgent(Client *c, int urg)
          383          XFree(wmh);
          384  }
          385  
          386 +void
          387 +show(const Arg *arg)
          388 +{
          389 +        if (selmon->hidsel)
          390 +                selmon->hidsel = 0;
          391 +        showwin(selmon->sel);
          392 +}
          393 +
          394 +void
          395 +showwin(Client *c)
          396 +{
          397 +        if (!c || !HIDDEN(c))
          398 +                return;
          399 +
          400 +        XMapWindow(dpy, c->win);
          401 +        setclientstate(c, NormalState);
          402 +        arrange(c->mon);
          403 +}
          404 +
          405  void
          406  showhide(Client *c)
          407  {
          408 @@ -1746,6 +1893,23 @@ toggleview(const Arg *arg)
          409          }
          410  }
          411  
          412 +void
          413 +togglewin(const Arg *arg)
          414 +{
          415 +        Client *c = (Client*)arg->v;
          416 +
          417 +        if (c == selmon->sel) {
          418 +                hidewin(c);
          419 +                focus(NULL);
          420 +                arrange(c->mon);
          421 +        } else {
          422 +                if (HIDDEN(c))
          423 +                        showwin(c);
          424 +                focus(c);
          425 +                restack(selmon);
          426 +        }
          427 +}
          428 +
          429  void
          430  unfocus(Client *c, int setfocus)
          431  {