dwm

my fork of dwm
Index Commits Files Refs README LICENSE
patches/dwm-systray-dwmblocks-6.2.diff (15318B)
   1 diff -ruN dwm-6.2-ori/config.def.h dwm-6.2/config.def.h
   2 --- dwm-6.2-ori/config.def.h    2020-08-17 23:51:19.053910127 +0530
   3 +++ dwm-6.2/config.def.h    2020-12-27 20:01:59.763790107 +0530
   4 @@ -16,10 +16,26 @@
   5  static const char col_gray3[]       = "#bbbbbb";
   6  static const char col_gray4[]       = "#eeeeee";
   7  static const char col_cyan[]        = "#005577";
   8 +static const char col1[]            = "#ffffff";
   9 +static const char col2[]            = "#ffffff";
  10 +static const char col3[]            = "#ffffff";
  11 +static const char col4[]            = "#ffffff";
  12 +static const char col5[]            = "#ffffff";
  13 +static const char col6[]            = "#ffffff";
  14 +
  15 +enum { SchemeNorm, SchemeCol1, SchemeCol2, SchemeCol3, SchemeCol4,
  16 +       SchemeCol5, SchemeCol6, SchemeSel }; /* color schemes */
  17 +
  18  static const char *colors[][3]      = {
  19      /*               fg         bg         border   */
  20 -    [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
  21 -    [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
  22 +    [SchemeNorm]  = { col_gray3, col_gray1, col_gray2 },
  23 +    [SchemeCol1]  = { col1,      col_gray1, col_gray2 },
  24 +    [SchemeCol2]  = { col2,      col_gray1, col_gray2 },
  25 +    [SchemeCol3]  = { col3,      col_gray1, col_gray2 },
  26 +    [SchemeCol4]  = { col4,      col_gray1, col_gray2 },
  27 +    [SchemeCol5]  = { col5,      col_gray1, col_gray2 },
  28 +    [SchemeCol6]  = { col6,      col_gray1, col_gray2 },
  29 +    [SchemeSel]   = { col_gray4, col_cyan,  col_cyan  },
  30  };
  31  
  32  /* tagging */
  33 @@ -107,7 +123,9 @@
  34      { ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
  35      { ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
  36      { ClkWinTitle,          0,              Button2,        zoom,           {0} },
  37 -    { ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
  38 +    { ClkStatusText,        0,              Button1,        sigdwmblocks,   {.i = 1} },
  39 +    { ClkStatusText,        0,              Button2,        sigdwmblocks,   {.i = 2} },
  40 +    { ClkStatusText,        0,              Button3,        sigdwmblocks,   {.i = 3} },
  41      { ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
  42      { ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
  43      { ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
  44 diff -ruN dwm-6.2-ori/dwm.c dwm-6.2/dwm.c
  45 --- dwm-6.2-ori/dwm.c    2020-08-17 23:51:19.057243495 +0530
  46 +++ dwm-6.2/dwm.c    2021-08-20 20:59:38.894111552 +0530
  47 @@ -40,6 +40,7 @@
  48  #include <X11/extensions/Xinerama.h>
  49  #endif /* XINERAMA */
  50  #include <X11/Xft/Xft.h>
  51 +#include <fcntl.h>
  52  
  53  #include "drw.h"
  54  #include "util.h"
  55 @@ -56,6 +57,13 @@
  56  #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
  57  #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
  58  #define TEXTW(X)                (drw_fontset_getwidth(drw, (X)) + lrpad)
  59 +#define TTEXTW(X)               (drw_fontset_getwidth(drw, (X)))
  60 +
  61 +#define STATUSLENGTH            256
  62 +#define DWMBLOCKSLOCKFILE       "/var/local/dwmblocks/dwmblocks.pid"
  63 +#define DELIMITERENDCHAR        10
  64 +#define LSPAD                   (lrpad / 2) /* padding on left side of status text */
  65 +#define RSPAD                   (lrpad / 2) /* padding on right side of status text */
  66  
  67  #define SYSTEM_TRAY_REQUEST_DOCK    0
  68  
  69 @@ -74,8 +82,7 @@
  70  #define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
  71  
  72  /* enums */
  73 -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
  74 -enum { SchemeNorm, SchemeSel }; /* color schemes */
  75 +enum { CurNormal, CurHand, CurResize, CurMove, CurLast }; /* cursor */
  76  enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
  77         NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
  78         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
  79 @@ -142,6 +149,7 @@
  80      unsigned int tagset[2];
  81      int showbar;
  82      int topbar;
  83 +        int statushandcursor;
  84      Client *clients;
  85      Client *sel;
  86      Client *stack;
  87 @@ -234,6 +242,7 @@
  88  static void seturgent(Client *c, int urg);
  89  static void showhide(Client *c);
  90  static void sigchld(int unused);
  91 +static void sigdwmblocks(const Arg *arg);
  92  static void spawn(const Arg *arg);
  93  static Monitor *systraytomon(Monitor *m);
  94  static void tag(const Arg *arg);
  95 @@ -249,6 +258,7 @@
  96  static void updatebarpos(Monitor *m);
  97  static void updatebars(void);
  98  static void updateclientlist(void);
  99 +static void updatedwmblockssig(int x);
 100  static int updategeom(void);
 101  static void updatenumlockmask(void);
 102  static void updatesizehints(Client *c);
 103 @@ -269,14 +279,17 @@
 104  static void zoom(const Arg *arg);
 105  
 106  /* variables */
 107 -static Systray *systray =  NULL;
 108  static const char broken[] = "broken";
 109 -static char stext[256];
 110 +static char stextc[STATUSLENGTH];
 111 +static char stexts[STATUSLENGTH];
 112  static int screen;
 113  static int sw, sh;           /* X display screen geometry width, height */
 114 -static int bh, blw = 0;      /* bar geometry */
 115 +static int bh, blw, ble;     /* bar geometry */
 116 +static int wsbar;            /* width of selmon bar */
 117 +static int wstext;           /* width of status text */
 118  static int lrpad;            /* sum of left and right padding for text */
 119  static int (*xerrorxlib)(Display *, XErrorEvent *);
 120 +static unsigned int dwmblockssig;
 121  static unsigned int numlockmask = 0;
 122  static void (*handler[LASTEvent]) (XEvent *) = {
 123      [ButtonPress] = buttonpress,
 124 @@ -303,6 +316,7 @@
 125  static Drw *drw;
 126  static Monitor *mons, *selmon;
 127  static Window root, wmcheckwin;
 128 +static Systray *systray =  NULL;
 129  
 130  /* configuration, allows nested code to access above variables */
 131  #include "config.h"
 132 @@ -452,13 +466,13 @@
 133  void
 134  buttonpress(XEvent *e)
 135  {
 136 -    unsigned int i, x, click;
 137 +        int i, x;
 138 +        unsigned int click;
 139      Arg arg = {0};
 140      Client *c;
 141      Monitor *m;
 142      XButtonPressedEvent *ev = &e->xbutton;
 143  
 144 -    click = ClkRootWin;
 145      /* focus monitor if necessary */
 146      if ((m = wintomon(ev->window)) && m != selmon) {
 147          unfocus(selmon->sel, 1);
 148 @@ -466,25 +480,29 @@
 149          focus(NULL);
 150      }
 151      if (ev->window == selmon->barwin) {
 152 -        i = x = 0;
 153 -        do
 154 -            x += TEXTW(tags[i]);
 155 -        while (ev->x >= x && ++i < LENGTH(tags));
 156 -        if (i < LENGTH(tags)) {
 157 -            click = ClkTagBar;
 158 -            arg.ui = 1 << i;
 159 -        } else if (ev->x < x + blw)
 160 -            click = ClkLtSymbol;
 161 -        else if (ev->x > selmon->ww - TEXTW(stext) - getsystraywidth())
 162 -            click = ClkStatusText;
 163 -        else
 164 -            click = ClkWinTitle;
 165 +                if (ev->x < ble - blw) {
 166 +                        i = -1, x = -ev->x;
 167 +                        do
 168 +                                x += TEXTW(tags[++i]);
 169 +                        while (x <= 0);
 170 +                        click = ClkTagBar;
 171 +                        arg.ui = 1 << i;
 172 +                } else if (ev->x < ble)
 173 +                        click = ClkLtSymbol;
 174 +                else if (ev->x < wsbar - wstext)
 175 +                        click = ClkWinTitle;
 176 +                else if ((x = wsbar - RSPAD - ev->x) > 0 && (x -= wstext - LSPAD - RSPAD) <= 0) {
 177 +                        updatedwmblockssig(x);
 178 +                        click = ClkStatusText;
 179 +                } else
 180 +                                return;
 181      } else if ((c = wintoclient(ev->window))) {
 182          focus(c);
 183          restack(selmon);
 184          XAllowEvents(dpy, ReplayPointer, CurrentTime);
 185          click = ClkClientWin;
 186 -    }
 187 +    } else
 188 +                click = ClkRootWin;
 189      for (i = 0; i < LENGTH(buttons); i++)
 190          if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
 191          && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
 192 @@ -789,23 +807,47 @@
 193  void
 194  drawbar(Monitor *m)
 195  {
 196 -    int x, w, sw = 0, stw = 0;
 197 +    int x, w;
 198 +        int wbar = m->ww;
 199      int boxs = drw->fonts->h / 9;
 200      int boxw = drw->fonts->h / 6 + 2;
 201      unsigned int i, occ = 0, urg = 0;
 202      Client *c;
 203  
 204 -    if(showsystray && m == systraytomon(m))
 205 -        stw = getsystraywidth();
 206 +        if (showsystray && m == systraytomon(m))
 207 +                wbar -= getsystraywidth();
 208  
 209      /* draw status first so it can be overdrawn by tags later */
 210      if (m == selmon) { /* status is only drawn on selected monitor */
 211 -        drw_setscheme(drw, scheme[SchemeNorm]);
 212 -        sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
 213 -        drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0);
 214 +                char *stc = stextc;
 215 +                char *stp = stextc;
 216 +                char tmp;
 217 +
 218 +                wsbar = wbar;
 219 +                drw_setscheme(drw, scheme[SchemeNorm]);
 220 +                x = wbar - wstext;
 221 +                drw_rect(drw, x, 0, LSPAD, bh, 1, 1); x += LSPAD; /* to keep left padding clean */
 222 +                for (;;) {
 223 +                        if ((unsigned char)*stc >= ' ') {
 224 +                                stc++;
 225 +                                continue;
 226 +                        }
 227 +                        tmp = *stc;
 228 +                        if (stp != stc) {
 229 +                                *stc = '\0';
 230 +                                x = drw_text(drw, x, 0, TTEXTW(stp), bh, 0, stp, 0);
 231 +                        }
 232 +                        if (tmp == '\0')
 233 +                                break;
 234 +                        if (tmp - DELIMITERENDCHAR - 1 < LENGTH(colors))
 235 +                                drw_setscheme(drw, scheme[tmp - DELIMITERENDCHAR - 1]);
 236 +                        *stc = tmp;
 237 +                        stp = ++stc;
 238 +                }
 239 +                drw_setscheme(drw, scheme[SchemeNorm]);
 240 +                drw_rect(drw, x, 0, wbar - x, bh, 1, 1); /* to keep right padding clean */
 241      }
 242  
 243 -    resizebarwin(m);
 244      for (c = m->clients; c; c = c->next) {
 245          occ |= c->tags;
 246          if (c->isurgent)
 247 @@ -822,11 +864,17 @@
 248                  urg & 1 << i);
 249          x += w;
 250      }
 251 -    w = blw = TEXTW(m->ltsymbol);
 252 +    w = TEXTW(m->ltsymbol);
 253      drw_setscheme(drw, scheme[SchemeNorm]);
 254      x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
 255  
 256 -    if ((w = m->ww - sw - stw - x) > bh) {
 257 +        if (m == selmon) {
 258 +                blw = w, ble = x;
 259 +                w = wbar - wstext - x;
 260 +        } else
 261 +                w = wbar - x;
 262 +
 263 +    if (w > bh) {
 264          if (m->sel) {
 265              drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
 266              drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
 267 @@ -837,7 +885,9 @@
 268              drw_rect(drw, x, 0, w, bh, 1, 1);
 269          }
 270      }
 271 -    drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
 272 +
 273 +        XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, wbar, bh);
 274 +    drw_map(drw, m->barwin, 0, 0, wbar, bh);
 275  }
 276  
 277  void
 278 @@ -1243,17 +1293,24 @@
 279  motionnotify(XEvent *e)
 280  {
 281      static Monitor *mon = NULL;
 282 +        int x;
 283      Monitor *m;
 284      XMotionEvent *ev = &e->xmotion;
 285  
 286 -    if (ev->window != root)
 287 -        return;
 288 -    if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
 289 -        unfocus(selmon->sel, 1);
 290 -        selmon = m;
 291 -        focus(NULL);
 292 -    }
 293 -    mon = m;
 294 +        if (ev->window == root) {
 295 +                if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
 296 +                        unfocus(selmon->sel, 1);
 297 +                        selmon = m;
 298 +                        focus(NULL);
 299 +                }
 300 +                mon = m;
 301 +        } else if (ev->window == selmon->barwin && (x = wsbar - RSPAD - ev->x) > 0
 302 +                                                && (x -= wstext - LSPAD - RSPAD) <= 0)
 303 +                updatedwmblockssig(x);
 304 +        else if (selmon->statushandcursor) {
 305 +                selmon->statushandcursor = 0;
 306 +                XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
 307 +        }
 308  }
 309  
 310  void
 311 @@ -1750,6 +1807,7 @@
 312      xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
 313      /* init cursors */
 314      cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
 315 +        cursor[CurHand] = drw_cur_create(drw, XC_hand2);
 316      cursor[CurResize] = drw_cur_create(drw, XC_sizing);
 317      cursor[CurMove] = drw_cur_create(drw, XC_fleur);
 318      /* init appearance */
 319 @@ -1825,6 +1883,37 @@
 320  }
 321  
 322  void
 323 +sigdwmblocks(const Arg *arg)
 324 +{
 325 +        static int fd = -1;
 326 +        struct flock fl;
 327 +        union sigval sv;
 328 +
 329 +        if (!dwmblockssig)
 330 +                return;
 331 +        fl.l_type = F_WRLCK;
 332 +        fl.l_whence = SEEK_SET;
 333 +        fl.l_start = 0;
 334 +        fl.l_len = 0;
 335 +        if (fd != -1) {
 336 +                if (fcntl(fd, F_GETLK, &fl) != -1 && fl.l_type == F_WRLCK)
 337 +                        goto signal;
 338 +                close(fd);
 339 +                fl.l_type = F_WRLCK;
 340 +        }
 341 +        if ((fd = open(DWMBLOCKSLOCKFILE, O_RDONLY | O_CLOEXEC)) == -1)
 342 +                return;
 343 +        if (fcntl(fd, F_GETLK, &fl) == -1 || fl.l_type != F_WRLCK) {
 344 +                close(fd);
 345 +                fd = -1;
 346 +                return;
 347 +        }
 348 +signal:
 349 +        sv.sival_int = (dwmblockssig << 8) | arg->i;
 350 +        sigqueue(fl.l_pid, SIGRTMIN, sv);
 351 +}
 352 +
 353 +void
 354  spawn(const Arg *arg)
 355  {
 356      if (arg->v == dmenucmd)
 357 @@ -2011,7 +2100,7 @@
 358      XSetWindowAttributes wa = {
 359          .override_redirect = True,
 360          .background_pixmap = ParentRelative,
 361 -        .event_mask = ButtonPressMask|ExposureMask
 362 +        .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
 363      };
 364      XClassHint ch = {"dwm", "dwm"};
 365      for (m = mons; m; m = m->next) {
 366 @@ -2058,6 +2147,41 @@
 367                  (unsigned char *) &(c->win), 1);
 368  }
 369  
 370 +void
 371 +updatedwmblockssig(int x)
 372 +{
 373 +        char *sts = stexts;
 374 +        char *stp = stexts;
 375 +        char tmp;
 376 +
 377 +        while (*sts != '\0') {
 378 +                if ((unsigned char)*sts >= ' ') {
 379 +                        sts++;
 380 +                        continue;
 381 +                }
 382 +                tmp = *sts;
 383 +                *sts = '\0';
 384 +                x += TTEXTW(stp);
 385 +                *sts = tmp;
 386 +                if (x > 0) {
 387 +                        if (tmp == DELIMITERENDCHAR)
 388 +                                break;
 389 +                        if (!selmon->statushandcursor) {
 390 +                                selmon->statushandcursor = 1;
 391 +                                XDefineCursor(dpy, selmon->barwin, cursor[CurHand]->cursor);
 392 +                        }
 393 +                        dwmblockssig = tmp;
 394 +                        return;
 395 +                }
 396 +                stp = ++sts;
 397 +        }
 398 +        if (selmon->statushandcursor) {
 399 +                selmon->statushandcursor = 0;
 400 +                XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
 401 +        }
 402 +        dwmblockssig = 0;
 403 +}
 404 +
 405  int
 406  updategeom(void)
 407  {
 408 @@ -2198,10 +2322,27 @@
 409  void
 410  updatestatus(void)
 411  {
 412 -    if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
 413 -        strcpy(stext, "dwm-"VERSION);
 414 -    drawbar(selmon);
 415 -    updatesystray();
 416 +    char rawstext[STATUSLENGTH];
 417 +
 418 +    if (gettextprop(root, XA_WM_NAME, rawstext, sizeof rawstext)) {
 419 +                char stextp[STATUSLENGTH];
 420 +                char *stp = stextp, *stc = stextc, *sts = stexts;
 421 +
 422 +                for (char *rst = rawstext; *rst != '\0'; rst++)
 423 +                        if ((unsigned char)*rst >= ' ')
 424 +                                *(stp++) = *(stc++) = *(sts++) = *rst;
 425 +                        else if ((unsigned char)*rst > DELIMITERENDCHAR)
 426 +                                *(stc++) = *rst;
 427 +                        else
 428 +                                *(sts++) = *rst;
 429 +                *stp = *stc = *sts = '\0';
 430 +                wstext = TTEXTW(stextp) + LSPAD + RSPAD;
 431 +        } else {
 432 +                strcpy(stextc, "dwm-"VERSION);
 433 +                strcpy(stexts, stextc);
 434 +                wstext = TTEXTW(stextc) + LSPAD + RSPAD;
 435 +        }
 436 +        drawbar(selmon);
 437  }
 438  
 439  void