diff --git a/config.h b/config.h index dffae22..ed83f31 100644 --- a/config.h +++ b/config.h @@ -32,6 +32,7 @@ static char *colors[][3] = { [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, }; +#define CORNER_RADIUS 5 typedef struct { const char *name; diff --git a/dwm.c b/dwm.c index 290dc2d..f3e70c9 100644 --- a/dwm.c +++ b/dwm.c @@ -40,6 +40,7 @@ #ifdef XINERAMA #include #endif /* XINERAMA */ +#include #include #include #include @@ -315,6 +316,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 drawroundedcorners(Client *c); static void xrdb(const Arg *arg); static void zoom(const Arg *arg); @@ -1391,6 +1393,9 @@ manage(Window w, XWindowAttributes *wa) unfocus(selmon->sel, 0); c->mon->sel = c; arrange(c->mon); + + drawroundedcorners(c); + XMapWindow(dpy, c->win); if (term) swallow(term, c); @@ -1508,6 +1513,7 @@ movemouse(const Arg *arg) togglefloating(NULL); if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) resize(c, nx, ny, c->w, c->h, 1); + drawroundedcorners(c); break; } } while (ev.type != ButtonRelease); @@ -1671,6 +1677,55 @@ resizeclient(Client *c, int x, int y, int w, int h) XSync(dpy, False); } +void drawroundedcorners(Client *c) { + // if set to zero in config.h, do not attempt to round + if(CORNER_RADIUS < 0) return; + + // NOTE: this is extremely hacky and surely could be optimized. + // Any X wizards out there reading this, please pull request. + if (CORNER_RADIUS > 0 && c && !c->isfullscreen) { + Window win; + win = c->win; + if(!win) return; + + XWindowAttributes win_attr; + if(!XGetWindowAttributes(dpy, win, &win_attr)) return; + + // set in config.h: + int dia = 2 * CORNER_RADIUS; + int w = c->w; + int h = c->h; + if(w < dia || h < dia) return; + + Pixmap mask; + mask = XCreatePixmap(dpy, win, w, h, 1); + if(!mask) return; + + XGCValues xgcv; + GC shape_gc; + shape_gc = XCreateGC(dpy, mask, 0, &xgcv); + + if(!shape_gc) { + XFreePixmap(dpy, mask); + free(shape_gc); + return; + } + + XSetForeground(dpy, shape_gc, 0); + XFillRectangle(dpy, mask, shape_gc, 0, 0, w, h); + XSetForeground(dpy, shape_gc, 1); + XFillArc(dpy, mask, shape_gc, 0, 0, dia, dia, 0, 23040); + XFillArc(dpy, mask, shape_gc, w-dia-1, 0, dia, dia, 0, 23040); + XFillArc(dpy, mask, shape_gc, 0, h-dia-1, dia, dia, 0, 23040); + XFillArc(dpy, mask, shape_gc, w-dia-1, h-dia-1, dia, dia, 0, 23040); + XFillRectangle(dpy, mask, shape_gc, CORNER_RADIUS, 0, w-dia, h); + XFillRectangle(dpy, mask, shape_gc, 0, CORNER_RADIUS, w, h-dia); + XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, mask, ShapeSet); + XFreePixmap(dpy, mask); + XFreeGC(dpy, shape_gc); + } +} + void resizemouse(const Arg *arg) { @@ -1726,6 +1781,7 @@ resizemouse(const Arg *arg) selmon = m; focus(NULL); } + drawroundedcorners(c); } void