Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm patch: appicons - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
commit 1e25ed0926c75fac9aee86243a93bb627f139022
parent 885eccfb082883973d02fe3962d89251ea11aff7
Author: Rumen <[email protected]>
Date: Sat, 4 Jan 2025 23:25:02 +0100
dwm patch: appicons
added patch to dwm's wiki. the patch allows for tag names to be
dynamically replaced by icons
Diffstat:
A dwm.suckless.org/patches/appicons/… | 240 +++++++++++++++++++++++++++…
A dwm.suckless.org/patches/appicons/… | 0
A dwm.suckless.org/patches/appicons/… | 38 +++++++++++++++++++++++++++…
3 files changed, 278 insertions(+), 0 deletions(-)
---
diff --git a/dwm.suckless.org/patches/appicons/dwm-appicons-6.5.diff b/dwm.suck…
@@ -0,0 +1,240 @@
+From 5bd12261788064919c47ea35085bba6c9a1110ed Mon Sep 17 00:00:00 2001
+From: Rumen <[email protected]>
+Date: Sat, 4 Jan 2025 22:28:14 +0100
+Subject: [PATCH] appicons patch:
+
+clients can now be assigned icons based on rules set by the user.
+these icons will be displayed insteas of the tag indicator and tag name.
+---
+ config.def.h | 14 ++++--
+ dwm.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 136 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 9efa774..3045af6 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -21,14 +21,22 @@ static const char *colors[][3] = {
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+
++/* appicons */
++/* NOTE: set to 0 to set to default (whitespace) */
++static char outer_separator_beg = '[';
++static char outer_separator_end = ']';
++static char inner_separator = ' ';
++static unsigned truncate_icons_after = 2; /* will default to 1, that is the m…
++static char truncate_symbol[] = "...";
++
+ static const Rule rules[] = {
+ /* xprop(1):
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating moni…
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating moni…
++ { "Gimp", NULL, NULL, 0, 1, -1, …
++ { "Firefox", NULL, NULL, 1 << 8, 0, -1, …
+ };
+
+ /* layout(s) */
+diff --git a/dwm.c b/dwm.c
+index 1443802..069ece9 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -85,6 +85,7 @@ typedef struct Monitor Monitor;
+ typedef struct Client Client;
+ struct Client {
+ char name[256];
++ char *appicon;
+ float mina, maxa;
+ int x, y, w, h;
+ int oldx, oldy, oldw, oldh;
+@@ -138,6 +139,7 @@ typedef struct {
+ unsigned int tags;
+ int isfloating;
+ int monitor;
++ const char *appicon;
+ } Rule;
+
+ /* function declarations */
+@@ -160,6 +162,9 @@ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+ static void detachstack(Client *c);
+ static Monitor *dirtomon(int dir);
++static void remove_outer_separators(char **str);
++static void appiconsappend(char **str, const char *appicon, size_t new_size);
++static void applyappicon(char *tag_icons[], int *icons_per_tag, const Client …
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+ static void enternotify(XEvent *e);
+@@ -283,7 +288,13 @@ applyrules(Client *c)
+ Monitor *m;
+ XClassHint ch = { NULL, NULL };
+
++ outer_separator_beg = outer_separator_beg ? outer_separator_beg : ' ';
++ outer_separator_end = outer_separator_end ? outer_separator_end : ' ';
++ inner_separator = inner_separator ? inner_separator : ' ';
++ truncate_icons_after = truncate_icons_after > 0 ? truncate_icons_after : …
++
+ /* rule matching */
++ c->appicon = NULL;
+ c->isfloating = 0;
+ c->tags = 0;
+ XGetClassHint(dpy, c->win, &ch);
+@@ -296,6 +307,8 @@ applyrules(Client *c)
+ && (!r->class || strstr(class, r->class))
+ && (!r->instance || strstr(instance, r->instance)))
+ {
++ /* r->appicon is static, so lifetime is sufficient */
++ c->appicon = (char*) r->appicon;
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
+ for (m = mons; m && m->num != r->monitor; m = m->next…
+@@ -694,6 +707,96 @@ dirtomon(int dir)
+ return m;
+ }
+
++void
++remove_outer_separators(char **str)
++{
++ size_t clean_tag_name_len = strlen(*str) - 2;
++
++ char *temp_tag_name = (char*)
++ malloc(clean_tag_name_len + 1);
++
++ if (temp_tag_name == NULL) perror("dwm: malloc()");
++
++ memset(temp_tag_name, 0, clean_tag_name_len + 1);
++
++ char *clean_tag_name_beg = *str + 1;
++ strncpy(temp_tag_name,
++ clean_tag_name_beg,
++ clean_tag_name_len);
++
++ free(*str);
++ *str = temp_tag_name;
++}
++
++void
++appiconsappend(char **str, const char *appicon, size_t new_size)
++{
++ char *temp_tag_name = (char*) malloc(new_size);
++ if (temp_tag_name == NULL) perror("dwm: malloc()");
++
++ /* NOTE: Example format of temp_tag_name (with two appicons):
++ * <outer_sep_beg><appicon><inner_sep><appicon><outer_sep_end>
++ */
++ temp_tag_name = memset(temp_tag_name, 0, new_size);
++
++ temp_tag_name[0] = outer_separator_beg;
++ temp_tag_name[new_size - 2] = outer_separator_end;
++
++ strncpy(temp_tag_name + 1, *str, strlen(*str));
++ temp_tag_name[strlen(temp_tag_name)] = inner_separator;
++
++ strncpy(temp_tag_name + strlen(temp_tag_name),
++ appicon, strlen(appicon));
++
++ free(*str);
++ *str = temp_tag_name;
++}
++
++void
++applyappicon(char *tag_icons[], int *icons_per_tag, const Client *c)
++{
++ for (unsigned t = 1, i = 0;
++ i < LENGTH(tags);
++ t <<= 1, i++)
++ {
++ if (c->tags & t) {
++ if (icons_per_tag[i] == 0)
++ strncpy(tag_icons[i], c->appicon, strlen(c->appicon) + 1);
++
++ else {
++ char *icon = NULL;
++ if (icons_per_tag[i] < truncate_icons_after)
++ icon = c->appicon;
++ else if (icons_per_tag[i] == truncate_icons_after)
++ icon = truncate_symbol;
++ else {
++ icons_per_tag[i]++;
++ continue;
++ }
++
++ /* remove outer separators from previous iterations
++ * otherwise they get applied recursively */
++ if (icons_per_tag[i] > 1) {
++ remove_outer_separators(&tag_icons[i]);
++ }
++
++ size_t outer_separators_size = 2;
++ size_t inner_separator_size = 1;
++
++ size_t new_size = strlen(tag_icons[i])
++ + outer_separators_size
++ + inner_separator_size
++ + strlen(icon)
++ + 1;
++
++ appiconsappend(&tag_icons[i], icon, new_size);
++ }
++
++ icons_per_tag[i]++;
++ }
++ }
++}
++
+ void
+ drawbar(Monitor *m)
+ {
+@@ -713,22 +816,41 @@ drawbar(Monitor *m)
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ }
+
++ char *tag_icons[LENGTH(tags)];
++ int icons_per_tag[LENGTH(tags)];
++ memset(icons_per_tag, 0, LENGTH(tags) * sizeof(int));
++
++ for (int i = 0; i < LENGTH(tags); i++) {
++ /* set each tag to default value */
++ tag_icons[i] = strndup(tags[i], strlen(tags[i]));
++ }
++
+ for (c = m->clients; c; c = c->next) {
++ if (c->appicon && strlen(c->appicon) > 0) {
++ applyappicon(tag_icons, icons_per_tag, c);
++ }
++
+ occ |= c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+ }
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+- w = TEXTW(tags[i]);
++ w = TEXTW(tag_icons[i]);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? Sc…
+- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+- if (occ & 1 << i)
++ drw_text(drw, x, 0, w, bh, lrpad / 2, tag_icons[i], urg & 1 <…
++ if (occ & 1 << i && icons_per_tag[i] == 0)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+ m == selmon && selmon->sel && selmon->sel->ta…
+ urg & 1 << i);
+ x += w;
+ }
++
++ for (int i = 0; i < LENGTH(tags); i++) {
++ free(tag_icons[i]);
++ tag_icons[i] = NULL;
++ }
++
+ w = TEXTW(m->ltsymbol);
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+--
+2.47.1
+
diff --git a/dwm.suckless.org/patches/appicons/example.png b/dwm.suckless.org/p…
Binary files differ.
diff --git a/dwm.suckless.org/patches/appicons/index.md b/dwm.suckless.org/patc…
@@ -0,0 +1,38 @@
+appicons
+========
+
+![App Icons Screenshot](example.png)
+
+
+Description
+-----------
+Adds support for app icons which can be used instead of the tag indicator
+and tag name. This is configurable through an extra option in `rules`.
+
+Icons should work out of the box. Emojis require a special font like
+[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji).
+
+When one or more app icons are present in a tag, the tag name will be
+encapsulated with the outer separators (`outer_separator_beg` and
+`outer_separator_end`). Additionally, the icons of the tag will be
+separated between themselves by `inner_separator`.
+
+Each tag can have a maximum of `truncate_icons_after` icons.
+After which the `truncate_symbol` will be displayed.
+
+
+Download
+--------
+* [dwm-appicons-6.5.diff](dwm-appicons-6.5.diff) (2025-01-04)
+
+
+
+Author
+------
+* Rumen Mitov - <[email protected]>
+
+
+
+Inspiration
+-----------
+* [XMonad's DynamicIcons](https://hackage.haskell.org/package/xmonad-contrib-…
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.