summaryrefslogtreecommitdiff
path: root/patches/client-opacity-focus/client-opacity-focus.dwl.patch
blob: 11aa97305315aaf905dafe326bd9557867152d1e (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
diff --git a/dwl.c b/dwl.c
index 12f441e..e45e420 100644
--- a/dwl.c
+++ b/dwl.c
@@ -138,6 +138,9 @@ typedef struct {
 	unsigned int bw;
 	uint32_t tags;
 	int isfloating, isurgent, isfullscreen;
+	float opacity;
+	float opacity_focus;
+	float opacity_unfocus;
 	uint32_t resize; /* configure serial of a pending resize */
 } Client;
 
@@ -227,6 +230,8 @@ typedef struct {
 	const char *title;
 	uint32_t tags;
 	int isfloating;
+	float opacity_focus;
+	float opacity_unfocus;
 	int monitor;
 } Rule;
 
@@ -319,6 +324,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
 static void requestmonstate(struct wl_listener *listener, void *data);
 static void resize(Client *c, struct wlr_box geo, int interact);
 static void run(char *startup_cmd);
+static void scenebuffersetopacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
 static void setcursor(struct wl_listener *listener, void *data);
 static void setcursorshape(struct wl_listener *listener, void *data);
 static void setfloating(Client *c, int floating);
@@ -326,6 +332,8 @@ static void setfullscreen(Client *c, int fullscreen);
 static void setlayout(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setmon(Client *c, Monitor *m, uint32_t newtags);
+static void setopacityunfocus(const Arg *arg);
+static void setopacityfocus(const Arg *arg);
 static void setpsel(struct wl_listener *listener, void *data);
 static void setsel(struct wl_listener *listener, void *data);
 static void setup(void);
@@ -490,6 +498,8 @@ applyrules(Client *c)
 		if ((!r->title || strstr(title, r->title))
 				&& (!r->id || strstr(appid, r->id))) {
 			c->isfloating = r->isfloating;
+			c->opacity_unfocus = r->opacity_unfocus;
+			c->opacity_focus = r->opacity_focus;
 			newtags |= r->tags;
 			i = 0;
 			wl_list_for_each(m, &mons, link) {
@@ -1127,6 +1137,10 @@ createnotify(struct wl_listener *listener, void *data)
 	c = toplevel->base->data = ecalloc(1, sizeof(*c));
 	c->surface.xdg = toplevel->base;
 	c->bw = borderpx;
+	/* Set default opacity*/
+	c->opacity_unfocus = default_opacity_unfocus;
+	c->opacity_focus = default_opacity_focus;
+	c->opacity = default_opacity_unfocus;
 
 	LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify);
 	LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify);
@@ -1429,6 +1443,7 @@ focusclient(Client *c, int lift)
 		wl_list_insert(&fstack, &c->flink);
 		selmon = c->mon;
 		c->isurgent = 0;
+		c->opacity = c->opacity_focus;
 
 		/* Don't change border color if there is an exclusive focus or we are
 		 * handling a drag operation */
@@ -1453,6 +1468,7 @@ focusclient(Client *c, int lift)
 			client_set_border_color(old_c, bordercolor);
 
 			client_activate_surface(old, 0);
+			old_c->opacity = old_c->opacity_unfocus;
 		}
 	}
 	printstatus();
@@ -2159,6 +2175,7 @@ rendermon(struct wl_listener *listener, void *data)
 	/* Render if no XDG clients have an outstanding resize and are visible on
 	 * this monitor. */
 	wl_list_for_each(c, &clients, link) {
+		wlr_scene_node_for_each_buffer(&c->scene_surface->node, scenebuffersetopacity, c);
 		if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && !client_is_stopped(c))
 			goto skip;
 	}
@@ -2295,6 +2312,15 @@ run(char *startup_cmd)
 	wl_display_run(dpy);
 }
 
+void
+scenebuffersetopacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *data)
+{
+	Client *c = data;
+	/* xdg-popups are children of Client.scene, we do not have to worry about
+	 * messing with them. */
+	wlr_scene_buffer_set_opacity(buffer, c->isfullscreen ? 1 : c->opacity);
+}
+
 void
 setcursor(struct wl_listener *listener, void *data)
 {
@@ -2363,6 +2389,7 @@ setfullscreen(Client *c, int fullscreen)
 		 * client positions are set by the user and cannot be recalculated */
 		resize(c, c->prev, 0);
 	}
+	wlr_scene_node_for_each_buffer(&c->scene_surface->node, scenebuffersetopacity, c);
 	arrange(c->mon);
 	printstatus();
 }
@@ -2419,6 +2446,44 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
 	focusclient(focustop(selmon), 1);
 }
 
+
+void
+setopacityunfocus(const Arg *arg)
+{
+	Client *sel = focustop(selmon);
+	if (!sel)
+		return;
+
+	sel->opacity_unfocus += arg->f;
+	if (sel->opacity_unfocus > 1.0)
+		sel->opacity_unfocus = 1.0f;
+
+	if (sel->opacity_unfocus < 0.1)
+		sel->opacity_unfocus = 0.1f;
+
+	wlr_scene_node_for_each_buffer(&sel->scene_surface->node, scenebuffersetopacity, sel);
+}
+
+void
+setopacityfocus(const Arg *arg)
+{
+	Client *sel = focustop(selmon);
+	if (!sel)
+		return;
+
+	sel->opacity_focus += arg->f;
+	if (sel->opacity_focus > 1.0)
+		sel->opacity_focus = 1.0f;
+
+	if (sel->opacity_focus < 0.1)
+		sel->opacity_focus = 0.1f;
+
+	/* Change opacity from current client */
+	sel->opacity = sel->opacity_focus;
+
+	wlr_scene_node_for_each_buffer(&sel->scene_surface->node, scenebuffersetopacity, sel);
+}
+
 void
 setpsel(struct wl_listener *listener, void *data)
 {
-- 
2.53.0