dwm-clientopacity-20201012-61bb8b2.diff (6047B)
1 From e5db0708b4da80eee897588b96d6098243406075 Mon Sep 17 00:00:00 2001 2 From: Fabian Blatz <fabian.blatz@gmail.com> 3 Date: Mon, 12 Oct 2020 11:26:51 +0000 4 Subject: [PATCH] adds opacity on a per client basis 5 6 --- 7 config.def.h | 10 +++++++--- 8 dwm.c | 37 ++++++++++++++++++++++++++++++++++++- 9 2 files changed, 43 insertions(+), 4 deletions(-) 10 11 diff --git a/config.def.h b/config.def.h 12 index 1c0b587..7addf50 100644 13 --- a/config.def.h 14 +++ b/config.def.h 15 @@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ 16 static const unsigned int snap = 32; /* snap pixel */ 17 static const int showbar = 1; /* 0 means no bar */ 18 static const int topbar = 1; /* 0 means bottom bar */ 19 +static const double defaultopacity = 0.75; 20 static const char *fonts[] = { "monospace:size=10" }; 21 static const char dmenufont[] = "monospace:size=10"; 22 static const char col_gray1[] = "#222222"; 23 @@ -26,9 +27,10 @@ static const Rule rules[] = { 24 * WM_CLASS(STRING) = instance, class 25 * WM_NAME(STRING) = title 26 */ 27 - /* class instance title tags mask isfloating monitor */ 28 - { "Gimp", NULL, NULL, 0, 1, -1 }, 29 - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, 30 + /* class instance title tags mask isfloating opacity monitor */ 31 + { "Gimp", NULL, NULL, 0, 1, 1.0, -1 }, 32 + { "Firefox", NULL, NULL, 1 << 8, 0, 1.0, -1 }, 33 + { "St", NULL, NULL, 0, 0, defaultopacity, -1}, 34 }; 35 36 /* layout(s) */ 37 @@ -84,6 +86,8 @@ static Key keys[] = { 38 { MODKEY, XK_period, focusmon, {.i = +1 } }, 39 { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, 40 { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, 41 + { MODKEY|ShiftMask, XK_KP_Add, changeopacity, {.f = +0.1}}, 42 + { MODKEY|ShiftMask, XK_KP_Subtract, changeopacity, {.f = -0.1}}, 43 TAGKEYS( XK_1, 0) 44 TAGKEYS( XK_2, 1) 45 TAGKEYS( XK_3, 2) 46 diff --git a/dwm.c b/dwm.c 47 index 664c527..15014c0 100644 48 --- a/dwm.c 49 +++ b/dwm.c 50 @@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 51 enum { SchemeNorm, SchemeSel }; /* color schemes */ 52 enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 53 NetWMFullscreen, NetActiveWindow, NetWMWindowType, 54 - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 55 + NetWMWindowTypeDialog, NetClientList, NetLast, NetWMWindowsOpacity }; /* EWMH atoms */ 56 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 57 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 58 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 59 @@ -95,6 +95,7 @@ struct Client { 60 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; 61 Client *next; 62 Client *snext; 63 + double opacity; 64 Monitor *mon; 65 Window win; 66 }; 67 @@ -138,6 +139,7 @@ typedef struct { 68 const char *title; 69 unsigned int tags; 70 int isfloating; 71 + double opacity; 72 int monitor; 73 } Rule; 74 75 @@ -149,6 +151,7 @@ static void arrangemon(Monitor *m); 76 static void attach(Client *c); 77 static void attachstack(Client *c); 78 static void buttonpress(XEvent *e); 79 +static void changeopacity(const Arg *arg); 80 static void checkotherwm(void); 81 static void cleanup(void); 82 static void cleanupmon(Monitor *mon); 83 @@ -185,6 +188,7 @@ static void monocle(Monitor *m); 84 static void motionnotify(XEvent *e); 85 static void movemouse(const Arg *arg); 86 static Client *nexttiled(Client *c); 87 +static void opacity(Client *c, double opacity); 88 static void pop(Client *); 89 static void propertynotify(XEvent *e); 90 static void quit(const Arg *arg); 91 @@ -288,6 +292,7 @@ applyrules(Client *c) 92 /* rule matching */ 93 c->isfloating = 0; 94 c->tags = 0; 95 + c->opacity = defaultopacity; 96 XGetClassHint(dpy, c->win, &ch); 97 class = ch.res_class ? ch.res_class : broken; 98 instance = ch.res_name ? ch.res_name : broken; 99 @@ -300,6 +305,7 @@ applyrules(Client *c) 100 { 101 c->isfloating = r->isfloating; 102 c->tags |= r->tags; 103 + c->opacity = r->opacity; 104 for (m = mons; m && m->num != r->monitor; m = m->next); 105 if (m) 106 c->mon = m; 107 @@ -456,6 +462,21 @@ buttonpress(XEvent *e) 108 buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); 109 } 110 111 +void 112 +changeopacity(const Arg *arg) 113 +{ 114 + if (!selmon->sel) 115 + return; 116 + selmon->sel->opacity+=arg->f; 117 + if(selmon->sel->opacity > 1.0) 118 + selmon->sel->opacity = 1.0; 119 + 120 + if(selmon->sel->opacity < 0) 121 + selmon->sel->opacity = 0; 122 + 123 + opacity(selmon->sel, selmon->sel->opacity); 124 +} 125 + 126 void 127 checkotherwm(void) 128 { 129 @@ -1039,6 +1060,7 @@ manage(Window w, XWindowAttributes *wa) 130 c->mon = selmon; 131 applyrules(c); 132 } 133 + opacity(c, c->opacity); 134 135 if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) 136 c->x = c->mon->mx + c->mon->mw - WIDTH(c); 137 @@ -1200,6 +1222,18 @@ nexttiled(Client *c) 138 return c; 139 } 140 141 +void 142 +opacity(Client *c, double opacity) 143 +{ 144 + if(opacity >= 0 && opacity <= 1) { 145 + unsigned long real_opacity[] = { opacity * 0xffffffff }; 146 + XChangeProperty(dpy, c->win, netatom[NetWMWindowsOpacity], XA_CARDINAL, 147 + 32, PropModeReplace, (unsigned char *)real_opacity, 148 + 1); 149 + } else 150 + XDeleteProperty(dpy, c->win, netatom[NetWMWindowsOpacity]); 151 +} 152 + 153 void 154 pop(Client *c) 155 { 156 @@ -1563,6 +1597,7 @@ setup(void) 157 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 158 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 159 netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); 160 + netatom[NetWMWindowsOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False); 161 /* init cursors */ 162 cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); 163 cursor[CurResize] = drw_cur_create(drw, XC_sizing); 164 -- 165 2.28.0 166