1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
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 <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
+#include <X11/extensions/shape.h>
#include <X11/Xft/Xft.h>
#include <X11/Xlib-xcb.h>
#include <xcb/res.h>
@@ -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
|