st-netwmicon-0.8.5.diff (6217B)
1 From 2bab59f760fbb510b0a8f0ba1c26671c8839304e Mon Sep 17 00:00:00 2001 2 From: aleks <aleks.stier@icloud.com> 3 Date: Tue, 31 May 2022 00:16:17 +0200 4 Subject: [PATCH] Enable to set _NET_WM_ICON with a png-image 5 6 Generally the icon of an application is defined by its desktop-entry. 7 The patch desktopentry serves this purpose. Unfortunately, some programs 8 like tint2 (https://gitlab.com/o9000/tint2) or alttab 9 (https://github.com/sagb/alttab) can't make use of the desktop-entry and 10 rely instead on a hardcoded icon which has to be defined by the 11 application itself with the window-propery _NET_WM_ICON. Since st 12 doesn't define _NET_WM_ICON this programs can't display the correct icon 13 for st even if a desktop-entry exists. This patch solves this problem. 14 15 The dependencies are gd and glib. 16 17 By default each time st starts it will search for a file with the name st.png 18 under /usr/local/share/pixmaps/. If you put an image with this name in the 19 root-directory of the st-repository and call make install the image will be 20 installed in /usr/local/share/pixmaps/ automatically. Otherwise you have to 21 put the file there manually. 22 23 If you use the desktopentry-patch you should adjust the icon 24 in the file st.desktop by replacing the line *Icon=utilities-terminal* with 25 *Icon=st*. 26 27 Most programs which use the desktop-file to determine the icon should be able to 28 find st.png under /usr/local/share/pixmaps/. If not report it to me and try 29 changing in confing.mk the line *ICONPREFIX = $(PREFIX)/share/pixmaps* to 30 *ICONPREFIX = $(PREFIX)/share/icons/hicolor/256x256/apps/* and install the icon 31 there. 32 33 The code for loading and transforming the image to an appropriate format 34 is, except for minor modifications, from xseticon 35 (https://www.leonerd.org.uk/code/xseticon/) which is developed by Paul 36 Evans. 37 38 --- 39 Makefile | 3 +++ 40 config.mk | 8 ++++++-- 41 st.h | 5 +++-- 42 x.c | 38 +++++++++++++++++++++++++++++++++++++- 43 4 files changed, 49 insertions(+), 5 deletions(-) 44 45 diff --git a/Makefile b/Makefile 46 index 470ac86..96e27e3 100644 47 --- a/Makefile 48 +++ b/Makefile 49 @@ -49,9 +49,12 @@ install: st 50 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 51 tic -sx st.info 52 @echo Please see the README file regarding the terminfo entry of st. 53 + mkdir -p $(DESTDIR)$(ICONPREFIX) 54 + [ -f $(ICONNAME) ] && cp -f $(ICONNAME) $(DESTDIR)$(ICONPREFIX) || : 55 56 uninstall: 57 rm -f $(DESTDIR)$(PREFIX)/bin/st 58 rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 59 + rm -f $(DESTDIR)$(ICONPREFIX)/$(ICONNAME) 60 61 .PHONY: all options clean dist install uninstall 62 diff --git a/config.mk b/config.mk 63 index 4c4c5d5..7af8ab7 100644 64 --- a/config.mk 65 +++ b/config.mk 66 @@ -6,6 +6,8 @@ VERSION = 0.8.5 67 # paths 68 PREFIX = /usr/local 69 MANPREFIX = $(PREFIX)/share/man 70 +ICONPREFIX = $(PREFIX)/share/pixmaps 71 +ICONNAME = st.png 72 73 X11INC = /usr/X11R6/include 74 X11LIB = /usr/X11R6/lib 75 @@ -14,14 +16,16 @@ PKG_CONFIG = pkg-config 76 77 # includes and libs 78 INCS = -I$(X11INC) \ 79 + `$(PKG_CONFIG) --cflags glib-2.0` \ 80 `$(PKG_CONFIG) --cflags fontconfig` \ 81 `$(PKG_CONFIG) --cflags freetype2` 82 -LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ 83 +LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lgd \ 84 + `$(PKG_CONFIG) --libs glib-2.0` \ 85 `$(PKG_CONFIG) --libs fontconfig` \ 86 `$(PKG_CONFIG) --libs freetype2` 87 88 # flags 89 -STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 90 +STCPPFLAGS = -DVERSION=\"$(VERSION)\" -DICON=\"$(ICONPREFIX)/$(ICONNAME)\" -D_XOPEN_SOURCE=600 91 STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) 92 STLDFLAGS = $(LIBS) $(LDFLAGS) 93 94 diff --git a/st.h b/st.h 95 index 519b9bd..0f6e7d4 100644 96 --- a/st.h 97 +++ b/st.h 98 @@ -3,9 +3,10 @@ 99 #include <stdint.h> 100 #include <sys/types.h> 101 102 +#include <gd.h> 103 +#include <glib.h> 104 + 105 /* macros */ 106 -#define MIN(a, b) ((a) < (b) ? (a) : (b)) 107 -#define MAX(a, b) ((a) < (b) ? (b) : (a)) 108 #define LEN(a) (sizeof(a) / sizeof(a)[0]) 109 #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) 110 #define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) 111 diff --git a/x.c b/x.c 112 index 8a16faa..84a1e31 100644 113 --- a/x.c 114 +++ b/x.c 115 @@ -77,6 +77,8 @@ typedef XftDraw *Draw; 116 typedef XftColor Color; 117 typedef XftGlyphFontSpec GlyphFontSpec; 118 119 +typedef unsigned long int CARD32; 120 + 121 /* Purely graphic info */ 122 typedef struct { 123 int tw, th; /* tty width and height */ 124 @@ -93,7 +95,7 @@ typedef struct { 125 Window win; 126 Drawable buf; 127 GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ 128 - Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; 129 + Atom xembed, wmdeletewin, netwmname, netwmicon, netwmiconname, netwmpid; 130 struct { 131 XIM xim; 132 XIC xic; 133 @@ -1204,6 +1206,40 @@ xinit(int cols, int rows) 134 xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); 135 XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); 136 137 + /* use a png-image to set _NET_WM_ICON */ 138 + FILE* file = fopen(ICON, "r"); 139 + if (file) { 140 + /* inititialize variables */ 141 + const gdImagePtr icon_rgba = gdImageCreateFromPng(file); 142 + fclose(file); 143 + const int width = gdImageSX(icon_rgba); 144 + const int height = gdImageSY(icon_rgba); 145 + const int icon_n = width * height + 2; 146 + CARD32 *icon_argb = g_new0(CARD32, icon_n); 147 + /* set width and height of the icon */ 148 + int i = 0; 149 + icon_argb[i++] = width; 150 + icon_argb[i++] = height; 151 + /* RGBA -> ARGB */ 152 + for (int y = 0; y < height; y++) { 153 + for (int x = 0; x < width; x++) { 154 + const int pixel_rgba = gdImageGetPixel(icon_rgba, x, y); 155 + guint8* pixel_argb = (guint8*) &icon_argb[i++]; 156 + pixel_argb[0] = gdImageBlue(icon_rgba, pixel_rgba); 157 + pixel_argb[1] = gdImageGreen(icon_rgba, pixel_rgba); 158 + pixel_argb[2] = gdImageRed(icon_rgba, pixel_rgba); 159 + /* scale alpha from 0-127 to 0-255 */ 160 + const int alpha = 127 - gdImageAlpha(icon_rgba, pixel_rgba); 161 + pixel_argb[3] = alpha == 127 ? 255 : alpha * 2; 162 + } 163 + } 164 + gdImageDestroy(icon_rgba); 165 + /* set _NET_WM_ICON */ 166 + xw.netwmicon = XInternAtom(xw.dpy, "_NET_WM_ICON", False); 167 + XChangeProperty(xw.dpy, xw.win, xw.netwmicon, XA_CARDINAL, 32, 168 + PropModeReplace, (uchar *)icon_argb, icon_n); 169 + } 170 + 171 xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); 172 XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, 173 PropModeReplace, (uchar *)&thispid, 1); 174 -- 175 2.36.1 176