about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManuel Palenzuela <manuelpalenzuelamerino@gmail.com>2019-06-19 01:28:32 +0200
committerManuel Palenzuela <manuelpalenzuelamerino@gmail.com>2019-06-19 01:28:32 +0200
commit4c844d7a9d90e05ba6cef17dd318f62466ed1687 (patch)
tree84aed9a11a604761778ba0a0c7c2837b1afabcf8
parentModified togglefullscreen patch (diff)
downloaddwm-4c844d7a9d90e05ba6cef17dd318f62466ed1687.tar.gz
dwm-4c844d7a9d90e05ba6cef17dd318f62466ed1687.tar.bz2
dwm-4c844d7a9d90e05ba6cef17dd318f62466ed1687.zip
Added the option for rounded corners [Patch]
-rw-r--r--config.h12
-rw-r--r--config.mk2
-rw-r--r--dwm.c62
-rw-r--r--patches/dwm-roundedcorners.diff171
4 files changed, 240 insertions, 7 deletions
diff --git a/config.h b/config.h
index 95b9ea1..a9866e4 100644
--- a/config.h
+++ b/config.h
@@ -1,12 +1,14 @@
 /* See LICENSE file for copyright and license details. */
 
 /* appearance */
-static const unsigned int borderpx  = 1;        /* border pixel of windows */
+static const unsigned int borderpx  = 1;         /* border pixel of windows */
 static const unsigned int gappx     = 10;        /* gap pixel between windows */
-static const unsigned int snap      = 32;       /* snap pixel */
-static const int showbar            = 1;        /* 0 means no bar */
-static const int topbar             = 1;        /* 0 means bottom bar */
-static const int focusonwheel       = 0;				/* 0 means no focus when click mouse wheel */
+static const unsigned int corner_radius = 0;     /* rounded corners radius */
+static const unsigned int round_non_floating = 1;/* if 0 only floating windows rounded */
+static const unsigned int snap      = 32;        /* snap pixel */
+static const int showbar            = 1;         /* 0 means no bar */
+static const int topbar             = 1;         /* 0 means bottom bar */
+static const int focusonwheel       = 0;				 /* 0 means no focus when click mouse wheel */
 static const char *fonts[]          = { "Noto Sans Display Nerd Font:size=10" };
 static const char dmenufont[]       = "Noto Sans Display Nerd Font:size=10";
 static const char col_gray1[]       = "#222222";
diff --git a/config.mk b/config.mk
index 3cb1518..39bdf4e 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} -lXrender
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lXext
 
 # flags
 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
diff --git a/dwm.c b/dwm.c
index 501661f..8f3c986 100644
--- a/dwm.c
+++ b/dwm.c
@@ -38,6 +38,7 @@
 #include <X11/Xutil.h>
 #ifdef XINERAMA
 #include <X11/extensions/Xinerama.h>
+#include <X11/extensions/shape.h>
 #endif /* XINERAMA */
 #include <X11/Xft/Xft.h>
 
@@ -95,7 +96,7 @@ struct Client {
 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
 	int bw, oldbw;
 	unsigned int tags;
-	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+	int isfixed, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
 	Client *next;
 	Client *snext;
 	Monitor *mon;
@@ -142,6 +143,7 @@ typedef struct {
 	const char *title;
 	unsigned int tags;
 	int isfloating;
+  int iscentered;
 	int monitor;
 } Rule;
 
@@ -193,6 +195,7 @@ static void quit(const Arg *arg);
 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 resizeclient(Client *c, int x, int y, int w, int h);
+static void drawroundedcorners(Client *c);
 static void resizemouse(const Arg *arg);
 static void restack(Monitor *m);
 static void run(void);
@@ -310,6 +313,7 @@ applyrules(Client *c)
 		&& (!r->instance || strstr(instance, r->instance)))
 		{
 			c->isfloating = r->isfloating;
+      c->iscentered = r->iscentered;
 			c->tags |= r->tags;
 			for (m = mons; m && m->num != r->monitor; m = m->next);
 			if (m)
@@ -1064,6 +1068,12 @@ manage(Window w, XWindowAttributes *wa)
 		&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
 	c->bw = borderpx;
 
+  if(c->iscentered) {
+    c->x = (c->mon->mw - WIDTH(c)) / 2;
+    c->y = (c->mon->mh - HEIGHT(c)) / 2;
+    if(c->isfloating) drawroundedcorners(c);
+  }
+
 	wc.border_width = c->bw;
 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
 	XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
@@ -1290,11 +1300,58 @@ resizeclient(Client *c, int x, int y, int w, int h)
     c->h = wc.height += c->bw * 2;
   }
 
+  if(!c->isfloating && round_non_floating == 1) drawroundedcorners(c);
+
 	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
 	configure(c);
 	XSync(dpy, False);
 }
 
+void drawroundedcorners(Client *c) {
+
+    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;
+
+        const int w = c->w;
+        const int h = c->h;
+
+        const int dia = 2 * corner_radius; // set in config.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)
 {
@@ -1339,6 +1396,8 @@ resizemouse(const Arg *arg)
 			}
 			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
 				resize(c, c->x, c->y, nw, nh, 1);
+
+      drawroundedcorners(c);
 			break;
 		}
 	} while (ev.type != ButtonRelease);
@@ -1350,6 +1409,7 @@ resizemouse(const Arg *arg)
 		selmon = m;
 		focus(NULL);
 	}
+  drawroundedcorners(c);
 }
 
 void
diff --git a/patches/dwm-roundedcorners.diff b/patches/dwm-roundedcorners.diff
new file mode 100644
index 0000000..39ef2af
--- /dev/null
+++ b/patches/dwm-roundedcorners.diff
@@ -0,0 +1,171 @@
+diff --git a/config.h b/config.h
+index 95b9ea1..a9866e4 100644
+--- a/config.h
++++ b/config.h
+@@ -1,12 +1,14 @@
+ /* See LICENSE file for copyright and license details. */
+ 
+ /* appearance */
+-static const unsigned int borderpx  = 1;        /* border pixel of windows */
++static const unsigned int borderpx  = 1;         /* border pixel of windows */
+ static const unsigned int gappx     = 10;        /* gap pixel between windows */
+-static const unsigned int snap      = 32;       /* snap pixel */
+-static const int showbar            = 1;        /* 0 means no bar */
+-static const int topbar             = 1;        /* 0 means bottom bar */
+-static const int focusonwheel       = 0;				/* 0 means no focus when click mouse wheel */
++static const unsigned int corner_radius = 0;     /* rounded corners radius */
++static const unsigned int round_non_floating = 1;/* if 0 only floating windows rounded */
++static const unsigned int snap      = 32;        /* snap pixel */
++static const int showbar            = 1;         /* 0 means no bar */
++static const int topbar             = 1;         /* 0 means bottom bar */
++static const int focusonwheel       = 0;				 /* 0 means no focus when click mouse wheel */
+ static const char *fonts[]          = { "Noto Sans Display Nerd Font:size=10" };
+ static const char dmenufont[]       = "Noto Sans Display Nerd Font:size=10";
+ static const char col_gray1[]       = "#222222";
+diff --git a/config.mk b/config.mk
+index 3cb1518..39bdf4e 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} -lXrender
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lXext
+ 
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index 501661f..8f3c986 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -38,6 +38,7 @@
+ #include <X11/Xutil.h>
+ #ifdef XINERAMA
+ #include <X11/extensions/Xinerama.h>
++#include <X11/extensions/shape.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
+ 
+@@ -95,7 +96,7 @@ struct Client {
+ 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ 	int bw, oldbw;
+ 	unsigned int tags;
+-	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++	int isfixed, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ 	Client *next;
+ 	Client *snext;
+ 	Monitor *mon;
+@@ -142,6 +143,7 @@ typedef struct {
+ 	const char *title;
+ 	unsigned int tags;
+ 	int isfloating;
++  int iscentered;
+ 	int monitor;
+ } Rule;
+ 
+@@ -193,6 +195,7 @@ static void quit(const Arg *arg);
+ 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 resizeclient(Client *c, int x, int y, int w, int h);
++static void drawroundedcorners(Client *c);
+ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+@@ -310,6 +313,7 @@ applyrules(Client *c)
+ 		&& (!r->instance || strstr(instance, r->instance)))
+ 		{
+ 			c->isfloating = r->isfloating;
++      c->iscentered = r->iscentered;
+ 			c->tags |= r->tags;
+ 			for (m = mons; m && m->num != r->monitor; m = m->next);
+ 			if (m)
+@@ -1064,6 +1068,12 @@ manage(Window w, XWindowAttributes *wa)
+ 		&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
+ 	c->bw = borderpx;
+ 
++  if(c->iscentered) {
++    c->x = (c->mon->mw - WIDTH(c)) / 2;
++    c->y = (c->mon->mh - HEIGHT(c)) / 2;
++    if(c->isfloating) drawroundedcorners(c);
++  }
++
+ 	wc.border_width = c->bw;
+ 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+ 	XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
+@@ -1290,11 +1300,58 @@ resizeclient(Client *c, int x, int y, int w, int h)
+     c->h = wc.height += c->bw * 2;
+   }
+ 
++  if(!c->isfloating && round_non_floating == 1) drawroundedcorners(c);
++
+ 	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
+ 	configure(c);
+ 	XSync(dpy, False);
+ }
+ 
++void drawroundedcorners(Client *c) {
++
++    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;
++
++        const int w = c->w;
++        const int h = c->h;
++
++        const int dia = 2 * corner_radius; // set in config.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)
+ {
+@@ -1339,6 +1396,8 @@ resizemouse(const Arg *arg)
+ 			}
+ 			if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+ 				resize(c, c->x, c->y, nw, nh, 1);
++
++      drawroundedcorners(c);
+ 			break;
+ 		}
+ 	} while (ev.type != ButtonRelease);
+@@ -1350,6 +1409,7 @@ resizemouse(const Arg *arg)
+ 		selmon = m;
+ 		focus(NULL);
+ 	}
++  drawroundedcorners(c);
+ }
+ 
+ void