dwm-clientopacity-6.4.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
dwm-clientopacity-6.4.diff (12855B)
---
1 From 10dd5df95f551d81d0a814dcdb2bde20e405fb91 Mon Sep 17 00:00:00 2001
2 From: sympodius <mail@sympodius.net>
3 Date: Mon, 13 Mar 2023 16:28:16 +0000
4 Subject: [PATCH] [dwm][patch][clientopacity] Adds opacity on a per client
5 basis
6
7 ---
8 config.def.h | 80 ++++++++++++++++++++++++++++------------------------
9 dwm.c | 61 ++++++++++++++++++++++++++++++++++++++-
10 2 files changed, 103 insertions(+), 38 deletions(-)
11
12 diff --git a/config.def.h b/config.def.h
13 index 9efa774..9ca812d 100644
14 --- a/config.def.h
15 +++ b/config.def.h
16 @@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
17 static const unsigned int snap = 32; /* snap pixel */
18 static const int showbar = 1; /* 0 means no bar */
19 static const int topbar = 1; /* 0 means bottom bar */
20 +static const double activeopacity = 0.9f; /* Window opacity when it's focused (0 <= opacity <= 1) */
21 +static const double inactiveopacity = 0.7f; /* Window opacity when it's inactive (0 <= opacity <= 1) */
22 static const char *fonts[] = { "monospace:size=10" };
23 static const char dmenufont[] = "monospace:size=10";
24 static const char col_gray1[] = "#222222";
25 @@ -26,9 +28,9 @@ static const Rule rules[] = {
26 * WM_CLASS(STRING) = instance, class
27 * WM_NAME(STRING) = title
28 */
29 - /* class instance title tags mask isfloating monitor */
30 - { "Gimp", NULL, NULL, 0, 1, -1 },
31 - { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
32 + /* class instance title tags mask isfloating focusopacity unfocusopacity monitor */
33 + { "Gimp", NULL, NULL, 0, 1, 1.0, inactiveopacity, -1 },
34 + { "Firefox", NULL, NULL, 1 << 8, 0, activeopacity, inactiveopacity, -1 },
35 };
36
37 /* layout(s) */
38 @@ -61,40 +63,44 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont,
39 static const char *termcmd[] = { "st", NULL };
40
41 static const Key keys[] = {
42 - /* modifier key function argument */
43 - { MODKEY, XK_p, spawn, {.v = dmenucmd } },
44 - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
45 - { MODKEY, XK_b, togglebar, {0} },
46 - { MODKEY, XK_j, focusstack, {.i = +1 } },
47 - { MODKEY, XK_k, focusstack, {.i = -1 } },
48 - { MODKEY, XK_i, incnmaster, {.i = +1 } },
49 - { MODKEY, XK_d, incnmaster, {.i = -1 } },
50 - { MODKEY, XK_h, setmfact, {.f = -0.05} },
51 - { MODKEY, XK_l, setmfact, {.f = +0.05} },
52 - { MODKEY, XK_Return, zoom, {0} },
53 - { MODKEY, XK_Tab, view, {0} },
54 - { MODKEY|ShiftMask, XK_c, killclient, {0} },
55 - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
56 - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
57 - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
58 - { MODKEY, XK_space, setlayout, {0} },
59 - { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
60 - { MODKEY, XK_0, view, {.ui = ~0 } },
61 - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
62 - { MODKEY, XK_comma, focusmon, {.i = -1 } },
63 - { MODKEY, XK_period, focusmon, {.i = +1 } },
64 - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
65 - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
66 - TAGKEYS( XK_1, 0)
67 - TAGKEYS( XK_2, 1)
68 - TAGKEYS( XK_3, 2)
69 - TAGKEYS( XK_4, 3)
70 - TAGKEYS( XK_5, 4)
71 - TAGKEYS( XK_6, 5)
72 - TAGKEYS( XK_7, 6)
73 - TAGKEYS( XK_8, 7)
74 - TAGKEYS( XK_9, 8)
75 - { MODKEY|ShiftMask, XK_q, quit, {0} },
76 + /* modifier key function argument */
77 + { MODKEY, XK_p, spawn, {.v = dmenucmd } },
78 + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
79 + { MODKEY, XK_b, togglebar, {0} },
80 + { MODKEY, XK_j, focusstack, {.i = +1 } },
81 + { MODKEY, XK_k, focusstack, {.i = -1 } },
82 + { MODKEY, XK_i, incnmaster, {.i = +1 } },
83 + { MODKEY, XK_d, incnmaster, {.i = -1 } },
84 + { MODKEY, XK_h, setmfact, {.f = -0.05} },
85 + { MODKEY, XK_l, setmfact, {.f = +0.05} },
86 + { MODKEY, XK_Return, zoom, {0} },
87 + { MODKEY, XK_Tab, view, {0} },
88 + { MODKEY|ShiftMask, XK_c, killclient, {0} },
89 + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
90 + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
91 + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
92 + { MODKEY, XK_space, setlayout, {0} },
93 + { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
94 + { MODKEY, XK_0, view, {.ui = ~0 } },
95 + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
96 + { MODKEY, XK_comma, focusmon, {.i = -1 } },
97 + { MODKEY, XK_period, focusmon, {.i = +1 } },
98 + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
99 + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
100 + { MODKEY|ShiftMask, XK_a, changefocusopacity, {.f = +0.025}},
101 + { MODKEY|ShiftMask, XK_s, changefocusopacity, {.f = -0.025}},
102 + { MODKEY|ShiftMask, XK_z, changeunfocusopacity, {.f = +0.025}},
103 + { MODKEY|ShiftMask, XK_x, changeunfocusopacity, {.f = -0.025}},
104 + TAGKEYS( XK_1, 0)
105 + TAGKEYS( XK_2, 1)
106 + TAGKEYS( XK_3, 2)
107 + TAGKEYS( XK_4, 3)
108 + TAGKEYS( XK_5, 4)
109 + TAGKEYS( XK_6, 5)
110 + TAGKEYS( XK_7, 6)
111 + TAGKEYS( XK_8, 7)
112 + TAGKEYS( XK_9, 8)
113 + { MODKEY|ShiftMask, XK_q, quit, {0} },
114 };
115
116 /* button definitions */
117 diff --git a/dwm.c b/dwm.c
118 index c2bd871..71cf33c 100644
119 --- a/dwm.c
120 +++ b/dwm.c
121 @@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
122 enum { SchemeNorm, SchemeSel }; /* color schemes */
123 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
124 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
125 - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
126 + NetWMWindowTypeDialog, NetClientList, NetWMWindowsOpacity, NetLast }; /* EWMH atoms */
127 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
128 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
129 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
130 @@ -95,6 +95,8 @@ struct Client {
131 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
132 Client *next;
133 Client *snext;
134 + double opacity;
135 + double unfocusopacity;
136 Monitor *mon;
137 Window win;
138 };
139 @@ -138,6 +140,8 @@ typedef struct {
140 const char *title;
141 unsigned int tags;
142 int isfloating;
143 + double opacity;
144 + double unfocusopacity;
145 int monitor;
146 } Rule;
147
148 @@ -149,6 +153,8 @@ static void arrangemon(Monitor *m);
149 static void attach(Client *c);
150 static void attachstack(Client *c);
151 static void buttonpress(XEvent *e);
152 +static void changefocusopacity(const Arg *arg);
153 +static void changeunfocusopacity(const Arg *arg);
154 static void checkotherwm(void);
155 static void cleanup(void);
156 static void cleanupmon(Monitor *mon);
157 @@ -185,6 +191,7 @@ static void monocle(Monitor *m);
158 static void motionnotify(XEvent *e);
159 static void movemouse(const Arg *arg);
160 static Client *nexttiled(Client *c);
161 +static void opacity(Client *c, double opacity);
162 static void pop(Client *c);
163 static void propertynotify(XEvent *e);
164 static void quit(const Arg *arg);
165 @@ -287,6 +294,8 @@ applyrules(Client *c)
166 /* rule matching */
167 c->isfloating = 0;
168 c->tags = 0;
169 + c->opacity = activeopacity;
170 + c->unfocusopacity = inactiveopacity;
171 XGetClassHint(dpy, c->win, &ch);
172 class = ch.res_class ? ch.res_class : broken;
173 instance = ch.res_name ? ch.res_name : broken;
174 @@ -299,6 +308,8 @@ applyrules(Client *c)
175 {
176 c->isfloating = r->isfloating;
177 c->tags |= r->tags;
178 + c->opacity = r->opacity;
179 + c->unfocusopacity = r->unfocusopacity;
180 for (m = mons; m && m->num != r->monitor; m = m->next);
181 if (m)
182 c->mon = m;
183 @@ -457,6 +468,36 @@ buttonpress(XEvent *e)
184 buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
185 }
186
187 +void
188 +changefocusopacity(const Arg *arg)
189 +{
190 + if (!selmon->sel)
191 + return;
192 + selmon->sel->opacity+=arg->f;
193 + if(selmon->sel->opacity > 1.0)
194 + selmon->sel->opacity = 1.0;
195 +
196 + if(selmon->sel->opacity < 0.1)
197 + selmon->sel->opacity = 0.1;
198 +
199 + opacity(selmon->sel, selmon->sel->opacity);
200 +}
201 +
202 +void
203 +changeunfocusopacity(const Arg *arg)
204 +{
205 + if (!selmon->sel)
206 + return;
207 + selmon->sel->unfocusopacity+=arg->f;
208 + if(selmon->sel->unfocusopacity > 1.0)
209 + selmon->sel->unfocusopacity = 1.0;
210 +
211 + if(selmon->sel->unfocusopacity < 0.1)
212 + selmon->sel->unfocusopacity = 0.1;
213 +
214 + opacity(selmon->sel, selmon->sel->unfocusopacity);
215 +}
216 +
217 void
218 checkotherwm(void)
219 {
220 @@ -803,6 +844,8 @@ focus(Client *c)
221 grabbuttons(c, 1);
222 XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
223 setfocus(c);
224 + c->opacity = MIN(1.0, MAX(0, c->opacity));
225 + opacity(c, c->opacity);
226 } else {
227 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
228 XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
229 @@ -1052,6 +1095,7 @@ manage(Window w, XWindowAttributes *wa)
230 c->mon = selmon;
231 applyrules(c);
232 }
233 + opacity(c, c->opacity);
234
235 if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
236 c->x = c->mon->wx + c->mon->ww - WIDTH(c);
237 @@ -1209,6 +1253,18 @@ nexttiled(Client *c)
238 return c;
239 }
240
241 +void
242 +opacity(Client *c, double opacity)
243 +{
244 + if(opacity > 0 && opacity < 1) {
245 + unsigned long real_opacity[] = { opacity * 0xffffffff };
246 + XChangeProperty(dpy, c->win, netatom[NetWMWindowsOpacity], XA_CARDINAL,
247 + 32, PropModeReplace, (unsigned char *)real_opacity,
248 + 1);
249 + } else
250 + XDeleteProperty(dpy, c->win, netatom[NetWMWindowsOpacity]);
251 +}
252 +
253 void
254 pop(Client *c)
255 {
256 @@ -1579,6 +1635,7 @@ setup(void)
257 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
258 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
259 netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
260 + netatom[NetWMWindowsOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
261 /* init cursors */
262 cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
263 cursor[CurResize] = drw_cur_create(drw, XC_sizing);
264 @@ -1760,6 +1817,8 @@ unfocus(Client *c, int setfocus)
265 if (!c)
266 return;
267 grabbuttons(c, 0);
268 + c->unfocusopacity = MIN(1.0, MAX(0, c->unfocusopacity));
269 + opacity(c, c->unfocusopacity);
270 XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
271 if (setfocus) {
272 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
273 --
274 2.39.2
275