Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-appicons-6.5.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-appicons-6.5.diff (8715B)
---
1 From dbae98a1cf614908ff0075c5f4a3d4ad619f0519 Mon Sep 17 00:00:00 2001
2 From: Rumen <[email protected]>
3 Date: Mon, 6 Jan 2025 16:39:08 +0100
4 Subject: [PATCH] appicons patch
5
6 Adds support for app icons that can replace the tag indicator and tag na…
7 ---
8 config.def.h | 14 +++--
9 dwm.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++--
10 2 files changed, 149 insertions(+), 7 deletions(-)
11
12 diff --git a/config.def.h b/config.def.h
13 index 9efa774..3045af6 100644
14 --- a/config.def.h
15 +++ b/config.def.h
16 @@ -21,14 +21,22 @@ static const char *colors[][3] = {
17 /* tagging */
18 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "…
19
20 +/* appicons */
21 +/* NOTE: set to 0 to set to default (whitespace) */
22 +static char outer_separator_beg = '[';
23 +static char outer_separator_end = ']';
24 +static char inner_separator = ' ';
25 +static unsigned truncate_icons_after = 2; /* will default to 1, that is…
26 +static char truncate_symbol[] = "...";
27 +
28 static const Rule rules[] = {
29 /* xprop(1):
30 * WM_CLASS(STRING) = instance, class
31 * WM_NAME(STRING) = title
32 */
33 - /* class instance title tags mask isfloating …
34 - { "Gimp", NULL, NULL, 0, 1, …
35 - { "Firefox", NULL, NULL, 1 << 8, 0, …
36 + /* class instance title tags mask isfloating …
37 + { "Gimp", NULL, NULL, 0, 1, …
38 + { "Firefox", NULL, NULL, 1 << 8, 0, …
39 };
40
41 /* layout(s) */
42 diff --git a/dwm.c b/dwm.c
43 index 1443802..bad8815 100644
44 --- a/dwm.c
45 +++ b/dwm.c
46 @@ -85,6 +85,7 @@ typedef struct Monitor Monitor;
47 typedef struct Client Client;
48 struct Client {
49 char name[256];
50 + char *appicon;
51 float mina, maxa;
52 int x, y, w, h;
53 int oldx, oldy, oldw, oldh;
54 @@ -121,6 +122,7 @@ struct Monitor {
55 unsigned int seltags;
56 unsigned int sellt;
57 unsigned int tagset[2];
58 + char **tag_icons;
59 int showbar;
60 int topbar;
61 Client *clients;
62 @@ -138,6 +140,7 @@ typedef struct {
63 unsigned int tags;
64 int isfloating;
65 int monitor;
66 + const char *appicon;
67 } Rule;
68
69 /* function declarations */
70 @@ -160,6 +163,9 @@ static void destroynotify(XEvent *e);
71 static void detach(Client *c);
72 static void detachstack(Client *c);
73 static Monitor *dirtomon(int dir);
74 +static void remove_outer_separators(char **str);
75 +static void appiconsappend(char **str, const char *appicon, size_t new_…
76 +static void applyappicon(char *tag_icons[], int *icons_per_tag, const C…
77 static void drawbar(Monitor *m);
78 static void drawbars(void);
79 static void enternotify(XEvent *e);
80 @@ -283,7 +289,13 @@ applyrules(Client *c)
81 Monitor *m;
82 XClassHint ch = { NULL, NULL };
83
84 + outer_separator_beg = outer_separator_beg ? outer_separator_beg : '…
85 + outer_separator_end = outer_separator_end ? outer_separator_end : '…
86 + inner_separator = inner_separator ? inner_separator : ' ';
87 + truncate_icons_after = truncate_icons_after > 0 ? truncate_icons_af…
88 +
89 /* rule matching */
90 + c->appicon = NULL;
91 c->isfloating = 0;
92 c->tags = 0;
93 XGetClassHint(dpy, c->win, &ch);
94 @@ -296,6 +308,8 @@ applyrules(Client *c)
95 && (!r->class || strstr(class, r->class))
96 && (!r->instance || strstr(instance, r->instance)))
97 {
98 + /* r->appicon is static, so lifetime is sufficient */
99 + c->appicon = (char*) r->appicon;
100 c->isfloating = r->isfloating;
101 c->tags |= r->tags;
102 for (m = mons; m && m->num != r->monitor; m = m…
103 @@ -433,7 +447,7 @@ buttonpress(XEvent *e)
104 if (ev->window == selmon->barwin) {
105 i = x = 0;
106 do
107 - x += TEXTW(tags[i]);
108 + x += TEXTW(m->tag_icons[i]);
109 while (ev->x >= x && ++i < LENGTH(tags));
110 if (i < LENGTH(tags)) {
111 click = ClkTagBar;
112 @@ -508,6 +522,14 @@ cleanupmon(Monitor *mon)
113 }
114 XUnmapWindow(dpy, mon->barwin);
115 XDestroyWindow(dpy, mon->barwin);
116 +
117 + for (int i = 0; i < LENGTH(tags); i++) {
118 + if (mon->tag_icons[i]) free(mon->tag_icons[i]);
119 + mon->tag_icons[i] = NULL;
120 + }
121 +
122 + if (mon->tag_icons) free(mon->tag_icons);
123 +
124 free(mon);
125 }
126
127 @@ -643,6 +665,13 @@ createmon(void)
128 m->lt[0] = &layouts[0];
129 m->lt[1] = &layouts[1 % LENGTH(layouts)];
130 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
131 +
132 + m->tag_icons = (char**) malloc(LENGTH(tags) * sizeof(char*));
133 + if (m->tag_icons == NULL) perror("dwm: malloc()");
134 + for (int i = 0; i < LENGTH(tags); i++) {
135 + m->tag_icons[i] = NULL;
136 + }
137 +
138 return m;
139 }
140
141 @@ -694,6 +723,96 @@ dirtomon(int dir)
142 return m;
143 }
144
145 +void
146 +remove_outer_separators(char **str)
147 +{
148 + size_t clean_tag_name_len = strlen(*str) - 2;
149 +
150 + char *temp_tag_name = (char*)
151 + malloc(clean_tag_name_len + 1);
152 +
153 + if (temp_tag_name == NULL) perror("dwm: malloc()");
154 +
155 + memset(temp_tag_name, 0, clean_tag_name_len + 1);
156 +
157 + char *clean_tag_name_beg = *str + 1;
158 + strncpy(temp_tag_name,
159 + clean_tag_name_beg,
160 + clean_tag_name_len);
161 +
162 + free(*str);
163 + *str = temp_tag_name;
164 +}
165 +
166 +void
167 +appiconsappend(char **str, const char *appicon, size_t new_size)
168 +{
169 + char *temp_tag_name = (char*) malloc(new_size);
170 + if (temp_tag_name == NULL) perror("dwm: malloc()");
171 +
172 + /* NOTE: Example format of temp_tag_name (with two appicons):
173 + * <outer_sep_beg><appicon><inner_sep><appicon><outer_sep_end>
174 + */
175 + temp_tag_name = memset(temp_tag_name, 0, new_size);
176 +
177 + temp_tag_name[0] = outer_separator_beg;
178 + temp_tag_name[new_size - 2] = outer_separator_end;
179 +
180 + strncpy(temp_tag_name + 1, *str, strlen(*str));
181 + temp_tag_name[strlen(temp_tag_name)] = inner_separator;
182 +
183 + strncpy(temp_tag_name + strlen(temp_tag_name),
184 + appicon, strlen(appicon));
185 +
186 + free(*str);
187 + *str = temp_tag_name;
188 +}
189 +
190 +void
191 +applyappicon(char *tag_icons[], int *icons_per_tag, const Client *c)
192 +{
193 + for (unsigned t = 1, i = 0;
194 + i < LENGTH(tags);
195 + t <<= 1, i++)
196 + {
197 + if (c->tags & t) {
198 + if (icons_per_tag[i] == 0)
199 + strncpy(tag_icons[i], c->appicon, strlen(c->appicon) + …
200 +
201 + else {
202 + char *icon = NULL;
203 + if (icons_per_tag[i] < truncate_icons_after)
204 + icon = c->appicon;
205 + else if (icons_per_tag[i] == truncate_icons_after)
206 + icon = truncate_symbol;
207 + else {
208 + icons_per_tag[i]++;
209 + continue;
210 + }
211 +
212 + /* remove outer separators from previous iterations
213 + * otherwise they get applied recursively */
214 + if (icons_per_tag[i] > 1) {
215 + remove_outer_separators(&tag_icons[i]);
216 + }
217 +
218 + size_t outer_separators_size = 2;
219 + size_t inner_separator_size = 1;
220 +
221 + size_t new_size = strlen(tag_icons[i])
222 + + outer_separators_size
223 + + inner_separator_size
224 + + strlen(icon)
225 + + 1;
226 +
227 + appiconsappend(&tag_icons[i], icon, new_size);
228 + }
229 +
230 + icons_per_tag[i]++;
231 + }
232 + }
233 +}
234 +
235 void
236 drawbar(Monitor *m)
237 {
238 @@ -713,22 +832,37 @@ drawbar(Monitor *m)
239 drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
240 }
241
242 + int icons_per_tag[LENGTH(tags)];
243 + memset(icons_per_tag, 0, LENGTH(tags) * sizeof(int));
244 +
245 + for (int i = 0; i < LENGTH(tags); i++) {
246 + if (m->tag_icons[i]) free(m->tag_icons[i]);
247 +
248 + /* set each tag to default value */
249 + m->tag_icons[i] = strndup(tags[i], strlen(tags[i]));
250 + }
251 +
252 for (c = m->clients; c; c = c->next) {
253 + if (c->appicon && strlen(c->appicon) > 0) {
254 + applyappicon(m->tag_icons, icons_per_tag, c);
255 + }
256 +
257 occ |= c->tags;
258 if (c->isurgent)
259 urg |= c->tags;
260 }
261 x = 0;
262 for (i = 0; i < LENGTH(tags); i++) {
263 - w = TEXTW(tags[i]);
264 + w = TEXTW(m->tag_icons[i]);
265 drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << …
266 - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 …
267 - if (occ & 1 << i)
268 + drw_text(drw, x, 0, w, bh, lrpad / 2, m->tag_icons[i], …
269 + if (occ & 1 << i && icons_per_tag[i] == 0)
270 drw_rect(drw, x + boxs, boxs, boxw, boxw,
271 m == selmon && selmon->sel && selmon->s…
272 urg & 1 << i);
273 x += w;
274 }
275 +
276 w = TEXTW(m->ltsymbol);
277 drw_setscheme(drw, scheme[SchemeNorm]);
278 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
279 --
280 2.47.1
281
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.