From 4c03c6699314ef41553d1a84078d32ce4d9d96ac Mon Sep 17 00:00:00 2001 From: _N0x Date: Thu, 14 Oct 2021 11:08:33 +0200 Subject: [PATCH] Added alpha patch to bar (systray still broken) --- dwm-6.2/config.def.h | 24 +- dwm-6.2/config.mk | 2 +- dwm-6.2/drw.c | 26 +- dwm-6.2/drw.h | 9 +- dwm-6.2/dwm.c | 84 ++- .../patches/dwm-alpha-20201019-61bb8b2.diff | 289 ++++++++++ ...1bb8b2.diff => dwm-alpha-systray-6.2.diff} | 543 +++++++++--------- 7 files changed, 648 insertions(+), 329 deletions(-) create mode 100644 dwm-6.2/patches/dwm-alpha-20201019-61bb8b2.diff rename dwm-6.2/patches/{dwm-systray-20210217-61bb8b2.diff => dwm-alpha-systray-6.2.diff} (65%) diff --git a/dwm-6.2/config.def.h b/dwm-6.2/config.def.h index bc9d8b5..726f43a 100644 --- a/dwm-6.2/config.def.h +++ b/dwm-6.2/config.def.h @@ -18,10 +18,8 @@ static const int vertpadbar = 6; /* vertical padding for statusba static const char *fonts[] = { "MesloLGS NF:size=11" }; static const char dmenufont[] = "MesloLGS NF:size=11"; static const char dmenupromt[] = "Run:"; -/* -static const char *fonts[] = { "monospace:size=10" }; -static const char dmenufont[] = "monospace:size=10"; -*/ + +/* colors */ static const char col_gray1[] = "#222222"; static const char col_gray2[] = "#444444"; static const char col_gray3[] = "#bbbbbb"; @@ -29,13 +27,17 @@ static const char col_gray4[] = "#eeeeee"; static const char col_teal[] = "#408977"; static const char *colors[][3] = { /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_teal, col_teal }, - [SchemeStatus] = { col_gray3, col_gray1, "#000000" }, // Statusbar right {text,background,not used but cannot be empty} - [SchemeTagsSel] = { col_gray4, col_teal, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty} - [SchemeTagsNorm] = { col_gray3, col_gray1, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty} - [SchemeInfoSel] = { col_gray3, col_gray1, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty} - [SchemeInfoNorm] = { col_gray3, col_gray1, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty} + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_teal, col_teal }, +}; + +/* alpha */ +static const unsigned int baralpha = 0xd0; +static const unsigned int borderalpha = OPAQUE; +static const unsigned int alphas[][3] = { + /* fg bg border */ + [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, + [SchemeSel] = { OPAQUE, baralpha, borderalpha }, }; /* tagging */ diff --git a/dwm-6.2/config.mk b/dwm-6.2/config.mk index 6d36cb7..3cb1518 100644 --- a/dwm-6.2/config.mk +++ b/dwm-6.2/config.mk @@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2 # includes and libs INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dwm-6.2/drw.c b/dwm-6.2/drw.c index 8fd1ca4..c202cb3 100644 --- a/dwm-6.2/drw.c +++ b/dwm-6.2/drw.c @@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) } Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) { Drw *drw = ecalloc(1, sizeof(Drw)); @@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->root = root; drw->w = w; drw->h = h; - drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); - drw->gc = XCreateGC(dpy, root, 0, NULL); + drw->visual = visual; + drw->depth = depth; + drw->cmap = cmap; + drw->drawable = XCreatePixmap(dpy, root, w, h, depth); + drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) drw->h = h; if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); } void @@ -193,21 +196,22 @@ drw_fontset_free(Fnt *font) } void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) { if (!drw || !dest || !clrname) return; - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), + if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, clrname, dest)) die("error, cannot allocate color '%s'", clrname); + + dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); } /* Wrapper to create color schemes. The caller has to call free(3) on the * returned color scheme when done using it. */ Clr * -drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) { size_t i; Clr *ret; @@ -217,7 +221,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) return NULL; for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); + drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); return ret; } @@ -273,9 +277,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); + d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); x += lpad; w -= lpad; } diff --git a/dwm-6.2/drw.h b/dwm-6.2/drw.h index 4bcd5ad..a56f523 100644 --- a/dwm-6.2/drw.h +++ b/dwm-6.2/drw.h @@ -20,6 +20,9 @@ typedef struct { Display *dpy; int screen; Window root; + Visual *visual; + unsigned int depth; + Colormap cmap; Drawable drawable; GC gc; Clr *scheme; @@ -27,7 +30,7 @@ typedef struct { } Drw; /* Drawable abstraction */ -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap); void drw_resize(Drw *drw, unsigned int w, unsigned int h); void drw_free(Drw *drw); @@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colorscheme abstraction */ -void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); -Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); /* Cursor abstraction */ Cur *drw_cur_create(Drw *drw, int shape); diff --git a/dwm-6.2/dwm.c b/dwm-6.2/dwm.c index 1994edf..a9737d1 100644 --- a/dwm-6.2/dwm.c +++ b/dwm-6.2/dwm.c @@ -74,9 +74,11 @@ #define VERSION_MINOR 0 #define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR +#define OPAQUE 0xffU + /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* color schemes */ +enum { SchemeNorm, SchemeSel}; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, NetWMFullscreen, NetActiveWindow, NetWMWindowType, @@ -270,6 +272,7 @@ static Client *wintosystrayicon(Window w); static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); +static void xinitvisual(); static void zoom(const Arg *arg); /* variables */ @@ -314,6 +317,11 @@ static Drw *drw; static Monitor *mons, *selmon; static Window root, wmcheckwin; +static int useargb = 0; +static Visual *visual; +static int depth; +static Colormap cmap; + /* configuration, allows nested code to access above variables */ #include "config.h" @@ -861,13 +869,13 @@ drawstatusbar(Monitor *m, int bh, char* stext, int stw) { char buf[8]; memcpy(buf, (char*)text+i+1, 7); buf[7] = '\0'; - drw_clr_create(drw, &drw->scheme[ColFg], buf); + drw_clr_create(drw, &drw->scheme[ColFg], buf, alphas[SchemeNorm][ColFg]); i += 7; } else if (text[i] == 'b') { char buf[8]; memcpy(buf, (char*)text+i+1, 7); buf[7] = '\0'; - drw_clr_create(drw, &drw->scheme[ColBg], buf); + drw_clr_create(drw, &drw->scheme[ColBg], buf, alphas[SchemeNorm][ColBg]); i += 7; } else if (text[i] == 'd') { drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; @@ -933,7 +941,7 @@ drawbar(Monitor *m) x = 0; for (i = 0; i < LENGTH(tags); i++) { w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]); + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); if (occ & 1 << i) drw_rect(drw, x + boxs, boxs, boxw, boxw, @@ -942,17 +950,19 @@ drawbar(Monitor *m) x += w; } w = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeTagsNorm]); + // Color of the layout-switcher + drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + // Color of the window Title if ((w = m->ww - sw - stw - x) > bh) { if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]); + drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0); if (m->sel->isfloating) drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); } else { - drw_setscheme(drw, scheme[SchemeInfoNorm]); + drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1); } } @@ -1926,7 +1936,8 @@ setup(void) sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); + xinitvisual(); + drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h + horizpadbar; @@ -1963,9 +1974,9 @@ setup(void) cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); - scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); + scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], alphas[0], 3); for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); + scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); /* init system tray */ updatesystray(); /* init bars */ @@ -2221,7 +2232,9 @@ updatebars(void) Monitor *m; XSetWindowAttributes wa = { .override_redirect = True, - .background_pixmap = ParentRelative, + .background_pixel = 0, + .border_pixel = 0, + .colormap = cmap, .event_mask = ButtonPressMask|ExposureMask }; XClassHint ch = {"dwm", "dwm"}; @@ -2231,9 +2244,12 @@ updatebars(void) w = m->ww; if (showsystray && m == systraytomon(m)) w -= getsystraywidth(); - m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, w -2 * sp, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + //m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, w -2 * sp, bh, 0, DefaultDepth(dpy, screen), + // CopyFromParent, DefaultVisual(dpy, screen), + // CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth, + InputOutput, visual, + CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); if (showsystray && m == systraytomon(m)) XMapRaised(dpy, systray->win); @@ -2530,7 +2546,8 @@ updatesystray(void) XMapSubwindows(dpy, systray->win); /* redraw background */ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); - XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); + // FIXME: + //XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); XSync(dpy, False); } @@ -2678,6 +2695,43 @@ systraytomon(Monitor *m) { return t; } +void +xinitvisual() +{ + XVisualInfo *infos; + XRenderPictFormat *fmt; + int nitems; + int i; + + XVisualInfo tpl = { + .screen = screen, + .depth = 32, + .class = TrueColor + }; + long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; + + infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); + visual = NULL; + for(i = 0; i < nitems; i ++) { + fmt = XRenderFindVisualFormat(dpy, infos[i].visual); + if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { + visual = infos[i].visual; + depth = infos[i].depth; + cmap = XCreateColormap(dpy, root, visual, AllocNone); + useargb = 1; + break; + } + } + + XFree(infos); + + if (! visual) { + visual = DefaultVisual(dpy, screen); + depth = DefaultDepth(dpy, screen); + cmap = DefaultColormap(dpy, screen); + } +} + void zoom(const Arg *arg) { diff --git a/dwm-6.2/patches/dwm-alpha-20201019-61bb8b2.diff b/dwm-6.2/patches/dwm-alpha-20201019-61bb8b2.diff new file mode 100644 index 0000000..9a8e92a --- /dev/null +++ b/dwm-6.2/patches/dwm-alpha-20201019-61bb8b2.diff @@ -0,0 +1,289 @@ +From 51f9c34480b984e261a738e5295f518b42c2f29c Mon Sep 17 00:00:00 2001 +From: Petrus Karell +Date: Mon, 19 Oct 2020 19:15:24 +0300 +Subject: [PATCH] Allow dwm to have translucent bars, while keeping all + the text on it opaque, just like the alpha-patch for st. Updated for 61bb8b2 + +--- + config.def.h | 7 ++++++ + config.mk | 2 +- + drw.c | 26 ++++++++++++----------- + drw.h | 9 +++++--- + dwm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------ + 5 files changed, 82 insertions(+), 22 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..4f68fe8 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -12,11 +12,18 @@ static const char col_gray2[] = "#444444"; + static const char col_gray3[] = "#bbbbbb"; + static const char col_gray4[] = "#eeeeee"; + static const char col_cyan[] = "#005577"; ++static const unsigned int baralpha = 0xd0; ++static const unsigned int borderalpha = OPAQUE; + static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, + }; ++static const unsigned int alphas[][3] = { ++ /* fg bg border */ ++ [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, ++ [SchemeSel] = { OPAQUE, baralpha, borderalpha }, ++}; + + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +diff --git a/config.mk b/config.mk +index 7084c33..21b5404 100644 +--- a/config.mk ++++ b/config.mk +@@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2 + + # includes and libs + INCS = -I${X11INC} -I${FREETYPEINC} +-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender + + # flags + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +diff --git a/drw.c b/drw.c +index 4cdbcbe..fe3aadd 100644 +--- a/drw.c ++++ b/drw.c +@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) + } + + Drw * +-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) ++drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) + { + Drw *drw = ecalloc(1, sizeof(Drw)); + +@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h + drw->root = root; + drw->w = w; + drw->h = h; +- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); +- drw->gc = XCreateGC(dpy, root, 0, NULL); ++ drw->visual = visual; ++ drw->depth = depth; ++ drw->cmap = cmap; ++ drw->drawable = XCreatePixmap(dpy, root, w, h, depth); ++ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); +- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); ++ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); + } + + void +@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font) + } + + void +-drw_clr_create(Drw *drw, Clr *dest, const char *clrname) ++drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) + { + if (!drw || !dest || !clrname) + return; + +- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen), ++ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); ++ ++ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); + } + + /* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ + Clr * +-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) ++drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) + { + size_t i; + Clr *ret; +@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) + return NULL; + + for (i = 0; i < clrcount; i++) +- drw_clr_create(drw, &ret[i], clrnames[i]); ++ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); + return ret; + } + +@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); +- d = XftDrawCreate(drw->dpy, drw->drawable, +- DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen)); ++ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); + x += lpad; + w -= lpad; + } +diff --git a/drw.h b/drw.h +index 4bcd5ad..a56f523 100644 +--- a/drw.h ++++ b/drw.h +@@ -20,6 +20,9 @@ typedef struct { + Display *dpy; + int screen; + Window root; ++ Visual *visual; ++ unsigned int depth; ++ Colormap cmap; + Drawable drawable; + GC gc; + Clr *scheme; +@@ -27,7 +30,7 @@ typedef struct { + } Drw; + + /* Drawable abstraction */ +-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); ++Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap); + void drw_resize(Drw *drw, unsigned int w, unsigned int h); + void drw_free(Drw *drw); + +@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text); + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + + /* Colorscheme abstraction */ +-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); ++void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); ++Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); + + /* Cursor abstraction */ + Cur *drw_cur_create(Drw *drw, int shape); +diff --git a/dwm.c b/dwm.c +index 664c527..d8005c7 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -57,6 +57,8 @@ + #define TAGMASK ((1 << LENGTH(tags)) - 1) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + ++#define OPAQUE 0xffU ++ + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ + enum { SchemeNorm, SchemeSel }; /* color schemes */ +@@ -233,6 +235,7 @@ static Monitor *wintomon(Window w); + static int xerror(Display *dpy, XErrorEvent *ee); + static int xerrordummy(Display *dpy, XErrorEvent *ee); + static int xerrorstart(Display *dpy, XErrorEvent *ee); ++static void xinitvisual(); + static void zoom(const Arg *arg); + + /* variables */ +@@ -269,6 +272,11 @@ static Drw *drw; + static Monitor *mons, *selmon; + static Window root, wmcheckwin; + ++static int useargb = 0; ++static Visual *visual; ++static int depth; ++static Colormap cmap; ++ + /* configuration, allows nested code to access above variables */ + #include "config.h" + +@@ -1542,7 +1550,8 @@ setup(void) + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); +- drw = drw_create(dpy, screen, root, sw, sh); ++ xinitvisual(); ++ drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; +@@ -1570,7 +1579,7 @@ setup(void) + /* init appearance */ + scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) +- scheme[i] = drw_scm_create(drw, colors[i], 3); ++ scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); + /* init bars */ + updatebars(); + updatestatus(); +@@ -1807,16 +1816,18 @@ updatebars(void) + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, +- .background_pixmap = ParentRelative, ++ .background_pixel = 0, ++ .border_pixel = 0, ++ .colormap = cmap, + .event_mask = ButtonPressMask|ExposureMask + }; + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; +- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), +- CopyFromParent, DefaultVisual(dpy, screen), +- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); ++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth, ++ InputOutput, visual, ++ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->barwin); + XSetClassHint(dpy, m->barwin, &ch); +@@ -2113,6 +2124,43 @@ xerrorstart(Display *dpy, XErrorEvent *ee) + return -1; + } + ++void ++xinitvisual() ++{ ++ XVisualInfo *infos; ++ XRenderPictFormat *fmt; ++ int nitems; ++ int i; ++ ++ XVisualInfo tpl = { ++ .screen = screen, ++ .depth = 32, ++ .class = TrueColor ++ }; ++ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; ++ ++ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); ++ visual = NULL; ++ for(i = 0; i < nitems; i ++) { ++ fmt = XRenderFindVisualFormat(dpy, infos[i].visual); ++ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { ++ visual = infos[i].visual; ++ depth = infos[i].depth; ++ cmap = XCreateColormap(dpy, root, visual, AllocNone); ++ useargb = 1; ++ break; ++ } ++ } ++ ++ XFree(infos); ++ ++ if (! visual) { ++ visual = DefaultVisual(dpy, screen); ++ depth = DefaultDepth(dpy, screen); ++ cmap = DefaultColormap(dpy, screen); ++ } ++} ++ + void + zoom(const Arg *arg) + { +-- +2.28.0 + diff --git a/dwm-6.2/patches/dwm-systray-20210217-61bb8b2.diff b/dwm-6.2/patches/dwm-alpha-systray-6.2.diff similarity index 65% rename from dwm-6.2/patches/dwm-systray-20210217-61bb8b2.diff rename to dwm-6.2/patches/dwm-alpha-systray-6.2.diff index 02604e5..a1d9d92 100644 --- a/dwm-6.2/patches/dwm-systray-20210217-61bb8b2.diff +++ b/dwm-6.2/patches/dwm-alpha-systray-6.2.diff @@ -1,48 +1,39 @@ -From 54948f3b69824de6eba41d281ff72c08131451a8 Mon Sep 17 00:00:00 2001 -From: Hritik Vijay -Date: Wed, 17 Feb 2021 19:30:25 +0530 -Subject: [PATCH] [Patch] Systray for dwm +From 71e4f843ed84d2a6f86dc1aeb516adec5d222194 Mon Sep 17 00:00:00 2001 +From: bakkeby +Date: Tue, 7 Apr 2020 10:53:35 +0200 +Subject: [PATCH 2/2] Adding systray patch -This patch adds an option for systray placement via `systrayleft`. - -Original author: Jan Christoph Ebersbach , inspired by http://code.google.com/p/dwm-plus -URL: http://dwm.suckless.org/patches/systray -dwm 6.2 port by Igor Gevka +Refer to https://dwm.suckless.org/patches/systray/ --- - config.def.h | 6 +- - dwm.c | 406 +++++++++++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 385 insertions(+), 27 deletions(-) + config.def.h | 4 + + dwm.c | 411 ++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 391 insertions(+), 24 deletions(-) diff --git a/config.def.h b/config.def.h -index 1c0b587..9e74de2 100644 +index 4f68fe8..1952613 100644 --- a/config.def.h +++ b/config.def.h -@@ -3,6 +3,11 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ +@@ -5,6 +5,10 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ -+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ -+static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ -+static const unsigned int systrayspacing = 2; /* systray spacing */ -+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -+static const int showsystray = 1; /* 0 means no systray */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ ++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ ++static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ ++static const int showsystray = 1; /* 0 means no systray */ static const char *fonts[] = { "monospace:size=10" }; -@@ -112,4 +117,3 @@ static Button buttons[] = { - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, - }; -- + static const char dmenufont[] = "monospace:size=10"; + static const char col_gray1[] = "#222222"; diff --git a/dwm.c b/dwm.c -index 664c527..f0d50ee 100644 +index 20f8309..679beb0 100644 --- a/dwm.c +++ b/dwm.c -@@ -57,12 +57,30 @@ - #define TAGMASK ((1 << LENGTH(tags)) - 1) - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +@@ -59,12 +59,30 @@ + + #define OPAQUE 0xffU +#define SYSTEM_TRAY_REQUEST_DOCK 0 ++#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 + +/* XEMBED messages */ +#define XEMBED_EMBEDDED_NOTIFY 0 @@ -59,21 +50,23 @@ index 664c527..f0d50ee 100644 +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR + /* enums */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { SchemeNorm, SchemeSel }; /* color schemes */ - enum { NetSupported, NetWMName, NetWMState, NetWMCheck, -+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ +-enum { NetSupported, NetWMName, NetWMState, NetWMCheck, +- NetWMFullscreen, NetActiveWindow, NetWMWindowType, +- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayVisual, ++ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDock, ++ NetSystemTrayOrientationHorz, NetWMWindowTypeDialog, NetClientList, NetWMCheck, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -@@ -141,6 +159,12 @@ typedef struct { +@@ -143,6 +161,12 @@ typedef struct { int monitor; } Rule; -+typedef struct Systray Systray; ++typedef struct Systray Systray; +struct Systray { + Window win; + Client *icons; @@ -82,23 +75,23 @@ index 664c527..f0d50ee 100644 /* function declarations */ static void applyrules(Client *c); static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -@@ -172,6 +196,7 @@ static void focusstack(const Arg *arg); - static Atom getatomprop(Client *c, Atom prop); +@@ -171,9 +195,11 @@ static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static Atom getatomprop(Client *c, Atom prop); static int getrootptr(int *x, int *y); static long getstate(Window w); -+static unsigned int getsystraywidth(); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); ++static unsigned int getsystraywidth(); static void grabbuttons(Client *c, int focused); static void grabkeys(void); -@@ -189,13 +214,16 @@ static void pop(Client *); - static void propertynotify(XEvent *e); - static void quit(const Arg *arg); - static Monitor *recttomon(int x, int y, int w, int h); -+static void removesystrayicon(Client *i); + static void incnmaster(const Arg *arg); +@@ -193,10 +219,12 @@ static Monitor *recttomon(int x, int y, int w, int h); static void resize(Client *c, int x, int y, int w, int h, int interact); -+static void resizebarwin(Monitor *m); static void resizeclient(Client *c, int x, int y, int w, int h); static void resizemouse(const Arg *arg); ++static void removesystrayicon(Client *i); +static void resizerequest(XEvent *e); static void restack(Monitor *m); static void run(void); @@ -108,7 +101,7 @@ index 664c527..f0d50ee 100644 static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); -@@ -207,6 +235,7 @@ static void seturgent(Client *c, int urg); +@@ -208,6 +236,7 @@ static void seturgent(Client *c, int urg); static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); @@ -116,11 +109,11 @@ index 664c527..f0d50ee 100644 static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *); -@@ -224,18 +253,23 @@ static int updategeom(void); +@@ -225,12 +254,16 @@ static int updategeom(void); static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); -+static void updatesystray(void); ++static void updatesystray(int updatebar); +static void updatesystrayicongeom(Client *i, int w, int h); +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); static void updatetitle(Client *c); @@ -133,14 +126,7 @@ index 664c527..f0d50ee 100644 static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); - static void zoom(const Arg *arg); - - /* variables */ -+static Systray *systray = NULL; - static const char broken[] = "broken"; - static char stext[256]; - static int screen; -@@ -258,9 +292,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { +@@ -260,9 +293,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { [MapRequest] = maprequest, [MotionNotify] = motionnotify, [PropertyNotify] = propertynotify, @@ -152,20 +138,32 @@ index 664c527..f0d50ee 100644 static int running = 1; static Cur *cursor[CurLast]; static Clr **scheme; -@@ -440,7 +475,7 @@ buttonpress(XEvent *e) +@@ -271,6 +305,9 @@ static Drw *drw; + static Monitor *mons, *selmon; + static Window root, wmcheckwin; + ++static Systray *systray = NULL; ++static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; ++ + static int useargb = 0; + static Visual *visual; + static int depth; +@@ -447,7 +484,7 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + blw) click = ClkLtSymbol; -- else if (ev->x > selmon->ww - (int)TEXTW(stext)) -+ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) +- else if (ev->x > selmon->ww - TEXTW(stext)) ++ else if (ev->x > selmon->ww - TEXTW(stext) - getsystraywidth()) click = ClkStatusText; else click = ClkWinTitle; -@@ -483,6 +518,11 @@ cleanup(void) +@@ -490,6 +527,13 @@ cleanup(void) XUngrabKey(dpy, AnyKey, AnyModifier, root); while (mons) cleanupmon(mons); + if (showsystray) { ++ while (systray->icons) ++ removesystrayicon(systray->icons); + XUnmapWindow(dpy, systray->win); + XDestroyWindow(dpy, systray->win); + free(systray); @@ -173,7 +171,7 @@ index 664c527..f0d50ee 100644 for (i = 0; i < CurLast; i++) drw_cur_free(drw, cursor[i]); for (i = 0; i < LENGTH(colors); i++) -@@ -513,9 +553,57 @@ cleanupmon(Monitor *mon) +@@ -520,9 +564,49 @@ cleanupmon(Monitor *mon) void clientmessage(XEvent *e) { @@ -191,15 +189,11 @@ index 664c527..f0d50ee 100644 + free(c); + return; + } ++ + c->mon = selmon; + c->next = systray->icons; + systray->icons = c; -+ if (!XGetWindowAttributes(dpy, c->win, &wa)) { -+ /* use sane defaults */ -+ wa.width = bh; -+ wa.height = bh; -+ wa.border_width = 0; -+ } ++ XGetWindowAttributes(dpy, c->win, &wa); + c->x = c->oldx = c->y = c->oldy = 0; + c->w = c->oldw = wa.width; + c->h = c->oldh = wa.height; @@ -217,110 +211,97 @@ index 664c527..f0d50ee 100644 + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); -+ /* FIXME not sure if I have to send these events, too */ -+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); -+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); -+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); + XSync(dpy, False); -+ resizebarwin(selmon); -+ updatesystray(); + setclientstate(c, NormalState); ++ updatesystray(1); + } + return; + } ++ if (!c) return; if (cme->message_type == netatom[NetWMState]) { -@@ -568,7 +656,7 @@ configurenotify(XEvent *e) - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); -- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ resizebarwin(m); - } - focus(NULL); - arrange(NULL); -@@ -653,6 +741,11 @@ destroynotify(XEvent *e) +@@ -660,6 +744,10 @@ destroynotify(XEvent *e) if ((c = wintoclient(ev->window))) unmanage(c, 1); -+ else if ((c = wintosystrayicon(ev->window))) { ++ else if (showsystray && (c = wintosystrayicon(ev->window))) { + removesystrayicon(c); -+ resizebarwin(selmon); -+ updatesystray(); ++ updatesystray(1); + } } void -@@ -696,19 +789,23 @@ dirtomon(int dir) +@@ -703,17 +791,23 @@ dirtomon(int dir) void drawbar(Monitor *m) { -- int x, w, tw = 0; -+ int x, w, tw = 0, stw = 0; +- int x, w, sw = 0; ++ int x, w, sw = 0, stw = 0; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; Client *c; -+ if(showsystray && m == systraytomon(m) && !systrayonleft) ++ if (showsystray && m == systraytomon(m)) { + stw = getsystraywidth(); ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ drw_rect(drw, m->ww - stw, 0, stw, bh, 1, 1); ++ } + /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ drw_setscheme(drw, scheme[SchemeNorm]); -- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ -- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); -+ tw = TEXTW(stext) - lrpad + 2; /* 2px padding */ -+ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); + sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ +- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); ++ drw_text(drw, m->ww - sw - stw, 0, sw, bh, 0, stext, 0); } -+ resizebarwin(m); for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) -@@ -729,7 +826,7 @@ drawbar(Monitor *m) +@@ -736,7 +830,7 @@ drawbar(Monitor *m) drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); -- if ((w = m->ww - tw - x) > bh) { -+ if ((w = m->ww - tw - stw - x) > bh) { +- if ((w = m->ww - sw - x) > bh) { ++ if ((w = m->ww - sw - stw - x) > bh) { if (m->sel) { drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -@@ -740,7 +837,7 @@ drawbar(Monitor *m) - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } -- drw_map(drw, m->barwin, 0, 0, m->ww, bh); -+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); +@@ -757,6 +851,9 @@ drawbars(void) + + for (m = mons; m; m = m->next) + drawbar(m); ++ ++ if (showsystray && !systraypinning) ++ updatesystray(0); } void -@@ -777,8 +874,11 @@ expose(XEvent *e) +@@ -784,8 +881,12 @@ 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); -+ if (m == selmon) -+ updatesystray(); ++ ++ if (showsystray && m == systraytomon(m)) ++ updatesystray(0); + } } void -@@ -863,10 +963,17 @@ getatomprop(Client *c, Atom prop) - unsigned long dl; +@@ -871,9 +972,17 @@ getatomprop(Client *c, Atom prop) unsigned char *p = NULL; Atom da, atom = None; + +- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, + /* FIXME getatomprop should return the number of items and a pointer to + * the stored data instead of this workaround */ + Atom req = XA_ATOM; + if (prop == xatom[XembedInfo]) + req = xatom[XembedInfo]; - -- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, ++ + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, &da, &di, &dl, &dl, &p) == Success && p) { atom = *(Atom *)p; @@ -329,7 +310,7 @@ index 664c527..f0d50ee 100644 XFree(p); } return atom; -@@ -900,6 +1007,16 @@ getstate(Window w) +@@ -907,6 +1016,16 @@ getstate(Window w) return result; } @@ -338,54 +319,54 @@ index 664c527..f0d50ee 100644 +{ + unsigned int w = 0; + Client *i; -+ if(showsystray) -+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; -+ return w ? w + systrayspacing : 1; ++ if (showsystray) ++ for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next); ++ return w ? w + systrayspacing : 0; +} + int gettextprop(Window w, Atom atom, char *text, unsigned int size) { -@@ -1004,7 +1121,7 @@ killclient(const Arg *arg) +@@ -1011,7 +1130,7 @@ killclient(const Arg *arg) { if (!selmon->sel) return; - if (!sendevent(selmon->sel, wmatom[WMDelete])) { -+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { ++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0, 0, 0)) { XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); -@@ -1092,6 +1209,12 @@ maprequest(XEvent *e) - { +@@ -1100,6 +1219,12 @@ maprequest(XEvent *e) static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; -+ Client *i; -+ if ((i = wintosystrayicon(ev->window))) { -+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); -+ resizebarwin(selmon); -+ updatesystray(); -+ } ++ Client *i; ++ if (showsystray && (i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ updatesystray(1); ++ } ++ if (!XGetWindowAttributes(dpy, ev->window, &wa)) return; -@@ -1216,6 +1339,16 @@ propertynotify(XEvent *e) + if (wa.override_redirect) +@@ -1223,6 +1348,16 @@ propertynotify(XEvent *e) Window trans; XPropertyEvent *ev = &e->xproperty; -+ if ((c = wintosystrayicon(ev->window))) { ++ if (showsystray && (c = wintosystrayicon(ev->window))) { + if (ev->atom == XA_WM_NORMAL_HINTS) { + updatesizehints(c); + updatesystrayicongeom(c, c->w, c->h); + } + else + updatesystrayiconstate(c, ev); -+ resizebarwin(selmon); -+ updatesystray(); ++ updatesystray(1); + } ++ if ((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if (ev->state == PropertyDelete) -@@ -1266,6 +1399,20 @@ recttomon(int x, int y, int w, int h) +@@ -1273,6 +1408,19 @@ recttomon(int x, int y, int w, int h) return r; } @@ -401,27 +382,11 @@ index 664c527..f0d50ee 100644 + *ii = i->next; + free(i); +} -+ + void resize(Client *c, int x, int y, int w, int h, int interact) { -@@ -1273,6 +1420,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) - resizeclient(c, x, y, w, h); - } - -+void -+resizebarwin(Monitor *m) { -+ unsigned int w = m->ww; -+ if (showsystray && m == systraytomon(m) && !systrayonleft) -+ w -= getsystraywidth(); -+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -+} -+ - void - resizeclient(Client *c, int x, int y, int w, int h) - { -@@ -1345,6 +1500,19 @@ resizemouse(const Arg *arg) +@@ -1352,6 +1500,18 @@ resizemouse(const Arg *arg) } } @@ -433,15 +398,14 @@ index 664c527..f0d50ee 100644 + + if ((i = wintosystrayicon(ev->window))) { + updatesystrayicongeom(i, ev->width, ev->height); -+ resizebarwin(selmon); -+ updatesystray(); ++ updatesystray(1); + } +} + void restack(Monitor *m) { -@@ -1434,26 +1602,36 @@ setclientstate(Client *c, long state) +@@ -1441,26 +1601,35 @@ setclientstate(Client *c, long state) } int @@ -465,8 +429,7 @@ index 664c527..f0d50ee 100644 + exists = protocols[n] == proto; + XFree(protocols); + } -+ } -+ else { ++ } else { + exists = True; + mt = proto; } @@ -489,7 +452,7 @@ index 664c527..f0d50ee 100644 } return exists; } -@@ -1467,7 +1645,7 @@ setfocus(Client *c) +@@ -1474,7 +1643,7 @@ setfocus(Client *c) XA_WINDOW, 32, PropModeReplace, (unsigned char *) &(c->win), 1); } @@ -498,7 +461,7 @@ index 664c527..f0d50ee 100644 } void -@@ -1556,6 +1734,10 @@ setup(void) +@@ -1564,13 +1733,22 @@ setup(void) wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); @@ -506,11 +469,13 @@ index 664c527..f0d50ee 100644 + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); + netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); + netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); ++ netatom[NetSystemTrayVisual] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_VISUAL", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); -@@ -1563,6 +1745,9 @@ setup(void) + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); ++ netatom[NetWMWindowTypeDock] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + xatom[Manager] = XInternAtom(dpy, "MANAGER", False); @@ -519,76 +484,165 @@ index 664c527..f0d50ee 100644 /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); -@@ -1571,6 +1756,8 @@ setup(void) +@@ -1579,6 +1757,9 @@ setup(void) scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); + scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); + /* init system tray */ -+ updatesystray(); ++ if (showsystray) ++ updatesystray(0); /* init bars */ updatebars(); updatestatus(); -@@ -1704,7 +1891,18 @@ togglebar(const Arg *arg) +@@ -1661,6 +1842,23 @@ spawn(const Arg *arg) + } + } + ++Monitor * ++systraytomon(Monitor *m) ++{ ++ Monitor *t; ++ int i, n; ++ if (!systraypinning) { ++ if (!m) ++ return selmon; ++ return m == selmon ? m : NULL; ++ } ++ for (n = 1, t = mons; t && t->next; n++, t = t->next); ++ for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next); ++ if (systraypinningfailfirst && n < systraypinning) ++ return mons; ++ return t; ++} ++ + void + tag(const Arg *arg) { +@@ -1711,6 +1909,23 @@ togglebar(const Arg *arg) selmon->showbar = !selmon->showbar; updatebarpos(selmon); -- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -+ resizebarwin(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + if (showsystray) { + XWindowChanges wc; + if (!selmon->showbar) + wc.y = -bh; + else if (selmon->showbar) { ++ #if BARPADDING_PATCH ++ wc.y = vp; ++ if (!selmon->topbar) ++ wc.y = selmon->mh - bh + vp; ++ #else + wc.y = 0; + if (!selmon->topbar) + wc.y = selmon->mh - bh; ++ #endif // BARPADDING_PATCH + } + XConfigureWindow(dpy, systray->win, CWY, &wc); + } arrange(selmon); } -@@ -1799,11 +1997,18 @@ unmapnotify(XEvent *e) +@@ -1804,6 +2019,11 @@ unmapnotify(XEvent *e) + setclientstate(c, WithdrawnState); else unmanage(c, 0); - } -+ else if ((c = wintosystrayicon(ev->window))) { ++ } else if (showsystray && (c = wintosystrayicon(ev->window))) { + /* KLUDGE! sometimes icons occasionally unmap their windows, but do + * _not_ destroy them. We map those windows back */ + XMapRaised(dpy, c->win); -+ updatesystray(); -+ } ++ updatesystray(1); + } } - void - updatebars(void) - { -+ unsigned int w; - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, -@@ -1814,10 +2019,15 @@ updatebars(void) - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; -- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), -+ w = m->ww; -+ if (showsystray && m == systraytomon(m)) -+ w -= getsystraywidth(); -+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); +@@ -1826,6 +2046,8 @@ updatebars(void) + InputOutput, visual, + CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + if (showsystray && m == systraytomon(m)) + XMapRaised(dpy, systray->win); XMapRaised(dpy, m->barwin); XSetClassHint(dpy, m->barwin, &ch); } -@@ -1993,6 +2203,124 @@ updatestatus(void) - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); +@@ -2003,6 +2225,137 @@ updatestatus(void) drawbar(selmon); -+ updatesystray(); + } + ++void ++updatesystray(int updatebar) ++{ ++ XSetWindowAttributes wa; ++ XWindowChanges wc; ++ Client *i; ++ Monitor *m = systraytomon(NULL); ++ unsigned int x = m->mx + m->mw; ++ unsigned int w = 1, xpad = 0, ypad = 0; ++ #if BARPADDING_PATCH ++ xpad = sp; ++ ypad = vp; ++ #endif // BARPADDING_PATCH ++ ++ if (!showsystray) ++ return; ++ if (!systray) { ++ /* init systray */ ++ if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); ++ ++ wa.override_redirect = True; ++ wa.event_mask = ButtonPressMask|ExposureMask; ++ wa.background_pixel = 0; ++ wa.border_pixel = 0; ++ wa.colormap = cmap; ++ systray->win = XCreateWindow(dpy, root, x - xpad, m->by + ypad, w, bh, 0, depth, ++ InputOutput, visual, ++ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, ++ PropModeReplace, (unsigned char *)&systrayorientation, 1); ++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayVisual], XA_VISUALID, 32, ++ PropModeReplace, (unsigned char *)&visual->visualid, 1); ++ XChangeProperty(dpy, systray->win, netatom[NetWMWindowType], XA_ATOM, 32, ++ PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1); ++ XMapRaised(dpy, systray->win); ++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); ++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); ++ XSync(dpy, False); ++ } ++ else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return; ++ } ++ } ++ ++ for (w = 0, i = systray->icons; i; i = i->next) { ++ wa.background_pixel = 0; ++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); ++ XMapRaised(dpy, i->win); ++ w += systrayspacing; ++ i->x = w; ++ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); ++ w += i->w; ++ if (i->mon != m) ++ i->mon = m; ++ } ++ w = w ? w + systrayspacing : 1; ++ x -= w; ++ XMoveResizeWindow(dpy, systray->win, x - xpad, m->by + ypad, w, bh); ++ wc.x = x - xpad; ++ wc.y = m->by + ypad; ++ wc.width = w; ++ wc.height = bh; ++ wc.stack_mode = Above; wc.sibling = m->barwin; ++ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); ++ XMapWindow(dpy, systray->win); ++ XMapSubwindows(dpy, systray->win); ++ XSync(dpy, False); ++ ++ if (updatebar) ++ drawbar(m); +} + +void @@ -611,6 +665,8 @@ index 664c527..f0d50ee 100644 + i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); + i->h = bh; + } ++ if (i->w > 2*bh) ++ i->w = bh; + } +} + @@ -642,75 +698,11 @@ index 664c527..f0d50ee 100644 + systray->win, XEMBED_EMBEDDED_VERSION); +} + -+void -+updatesystray(void) -+{ -+ XSetWindowAttributes wa; -+ XWindowChanges wc; -+ Client *i; -+ Monitor *m = systraytomon(NULL); -+ unsigned int x = m->mx + m->mw; -+ unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; -+ unsigned int w = 1; -+ -+ if (!showsystray) -+ return; -+ if (systrayonleft) -+ x -= sw; -+ if (!systray) { -+ /* init systray */ -+ if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) -+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); -+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); -+ wa.event_mask = ButtonPressMask | ExposureMask; -+ wa.override_redirect = True; -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XSelectInput(dpy, systray->win, SubstructureNotifyMask); -+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, -+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); -+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); -+ XMapRaised(dpy, systray->win); -+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); -+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { -+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); -+ XSync(dpy, False); -+ } -+ else { -+ fprintf(stderr, "dwm: unable to obtain system tray.\n"); -+ free(systray); -+ systray = NULL; -+ return; -+ } -+ } -+ for (w = 0, i = systray->icons; i; i = i->next) { -+ /* make sure the background color stays the same */ -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); -+ XMapRaised(dpy, i->win); -+ w += systrayspacing; -+ i->x = w; -+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); -+ w += i->w; -+ if (i->mon != m) -+ i->mon = m; -+ } -+ w = w ? w + systrayspacing : 1; -+ x -= w; -+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); -+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; -+ wc.stack_mode = Above; wc.sibling = m->barwin; -+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); -+ XMapWindow(dpy, systray->win); -+ XMapSubwindows(dpy, systray->win); -+ /* redraw background */ -+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); -+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); -+ XSync(dpy, False); - } - void -@@ -2060,6 +2388,16 @@ wintoclient(Window w) - return NULL; + updatetitle(Client *c) + { +@@ -2085,6 +2438,16 @@ wintomon(Window w) + return selmon; } +Client * @@ -719,36 +711,13 @@ index 664c527..f0d50ee 100644 + + if (!showsystray || !w) + return i; -+ for (i = systray->icons; i && i->win != w; i = i->next) ; ++ for (i = systray->icons; i && i->win != w; i = i->next); + return i; +} + - Monitor * - wintomon(Window w) - { -@@ -2113,6 +2451,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee) - return -1; - } - -+Monitor * -+systraytomon(Monitor *m) { -+ Monitor *t; -+ int i, n; -+ if(!systraypinning) { -+ if(!m) -+ return selmon; -+ return m == selmon ? m : NULL; -+ } -+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ; -+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; -+ if(systraypinningfailfirst && n < systraypinning) -+ return mons; -+ return t; -+} -+ - void - zoom(const Arg *arg) - { + /* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ -- -2.30.1 +2.19.1