tabbed-icon-20200905-2da4e96.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
tabbed-icon-20200905-2da4e96.diff (9398B) | |
--- | |
1 diff --git a/Makefile b/Makefile | |
2 index 1b95d15..e571818 100644 | |
3 --- a/Makefile | |
4 +++ b/Makefile | |
5 @@ -37,7 +37,7 @@ dist: clean | |
6 @echo creating dist tarball | |
7 @mkdir -p tabbed-${VERSION} | |
8 @cp -R LICENSE Makefile README config.def.h config.mk \ | |
9 - tabbed.1 arg.h ${SRC} tabbed-${VERSION} | |
10 + tabbed.1 arg.h icon.h ${SRC} tabbed-${VERSION} | |
11 @tar -cf tabbed-${VERSION}.tar tabbed-${VERSION} | |
12 @gzip tabbed-${VERSION}.tar | |
13 @rm -rf tabbed-${VERSION} | |
14 diff --git a/TODO b/TODO | |
15 index 8e1986d..dbcb930 100644 | |
16 --- a/TODO | |
17 +++ b/TODO | |
18 @@ -1,4 +1,3 @@ | |
19 # TODO | |
20 * add some way to detach windows | |
21 * add some way to attach windows | |
22 - | |
23 diff --git a/icon.h b/icon.h | |
24 new file mode 100644 | |
25 index 0000000..e2ef631 | |
26 --- /dev/null | |
27 +++ b/icon.h | |
28 @@ -0,0 +1,41 @@ | |
29 +/* GIMP RGBA C-Source image dump (icon.c) */ | |
30 + | |
31 +#define ICON_WIDTH (16) | |
32 +#define ICON_HEIGHT (16) | |
33 +#define ICON_BYTES_PER_PIXEL (4) /* 2:RGB16, 3:RGB, 4:RGBA */ | |
34 +#define ICON_COMMENT \ | |
35 + "GIMP -> Export -> C-Source -> Prefixed name = ICON, Use macros, Save… | |
36 +#define ICON_PIXEL_DATA ((unsigned char*) ICON_pixel_data) | |
37 +static const unsigned char ICON_pixel_data[16 * 16 * 4 + 1] = | |
38 +("\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\… | |
39 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
40 + "\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\… | |
41 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
42 + "\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000\… | |
43 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
44 + "\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\… | |
45 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
46 + "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\… | |
47 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
48 + "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\… | |
49 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
50 + "\000\377\000\000\000\377\000\000\000\000\000\000\000\377\000\000\000\… | |
51 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
52 + "\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\… | |
53 + "\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
54 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\… | |
55 + "\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\… | |
56 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
57 + "\000\000\377\000\000\000\000\000\000\000\377\000\000\000\377\000\000\… | |
58 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
59 + "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\… | |
60 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
61 + "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\… | |
62 + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\… | |
63 + "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\… | |
64 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
65 + "\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000\000\000\… | |
66 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
67 + "\000\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\… | |
68 + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\… | |
69 + "\000\000\000\000\000\000\000\000\377\000\000\000\377"); | |
70 diff --git a/tabbed.c b/tabbed.c | |
71 index eafe28a..ec6212e 100644 | |
72 --- a/tabbed.c | |
73 +++ b/tabbed.c | |
74 @@ -18,6 +18,7 @@ | |
75 #include <X11/Xft/Xft.h> | |
76 | |
77 #include "arg.h" | |
78 +#include "icon.h" | |
79 | |
80 /* XEMBED messages */ | |
81 #define XEMBED_EMBEDDED_NOTIFY 0 | |
82 @@ -49,7 +50,7 @@ | |
83 | |
84 enum { ColFG, ColBG, ColLast }; /* color */ | |
85 enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen, | |
86 - XEmbed, WMSelectTab, WMLast }; /* default atoms */ | |
87 + XEmbed, WMSelectTab, WMIcon, WMLast }; /* default atoms */ | |
88 | |
89 typedef union { | |
90 int i; | |
91 @@ -135,6 +136,7 @@ static void updatenumlockmask(void); | |
92 static void updatetitle(int c); | |
93 static int xerror(Display *dpy, XErrorEvent *ee); | |
94 static void xsettitle(Window w, const char *str); | |
95 +static void xseticon(void); | |
96 | |
97 /* variables */ | |
98 static int screen; | |
99 @@ -169,6 +171,7 @@ static char winid[64]; | |
100 static char **cmd; | |
101 static char *wmname = "tabbed"; | |
102 static const char *geometry; | |
103 +static unsigned long icon[ICON_WIDTH * ICON_HEIGHT + 2]; | |
104 | |
105 char *argv0; | |
106 | |
107 @@ -455,6 +458,8 @@ focus(int c) | |
108 n += snprintf(&buf[n], sizeof(buf) - n, " %s", … | |
109 | |
110 xsettitle(win, buf); | |
111 + XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, … | |
112 + PropModeReplace, (unsigned char *) icon… | |
113 XRaiseWindow(dpy, win); | |
114 | |
115 return; | |
116 @@ -474,6 +479,7 @@ focus(int c) | |
117 lastsel = sel; | |
118 sel = c; | |
119 } | |
120 + xseticon(); | |
121 | |
122 if (clients[c]->urgent && (wmh = XGetWMHints(dpy, clients[c]->w… | |
123 wmh->flags &= ~XUrgencyHint; | |
124 @@ -868,9 +874,13 @@ propertynotify(const XEvent *e) | |
125 } | |
126 } | |
127 XFree(wmh); | |
128 + if (c == sel) | |
129 + xseticon(); | |
130 } else if (ev->state != PropertyDelete && ev->atom == XA_WM_NAM… | |
131 (c = getclient(ev->window)) > -1) { | |
132 updatetitle(c); | |
133 + } else if (ev->atom == wmatom[WMIcon] && (c = getclient(ev->win… | |
134 + xseticon(); | |
135 } | |
136 } | |
137 | |
138 @@ -995,6 +1005,7 @@ setup(void) | |
139 wmatom[WMSelectTab] = XInternAtom(dpy, "_TABBED_SELECT_TAB", Fa… | |
140 wmatom[WMState] = XInternAtom(dpy, "_NET_WM_STATE", False); | |
141 wmatom[XEmbed] = XInternAtom(dpy, "_XEMBED", False); | |
142 + wmatom[WMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False); | |
143 | |
144 /* init appearance */ | |
145 wx = 0; | |
146 @@ -1074,6 +1085,17 @@ setup(void) | |
147 snprintf(winid, sizeof(winid), "%lu", win); | |
148 setenv("XEMBED", winid, 1); | |
149 | |
150 + /* change icon from RGBA to ARGB */ | |
151 + icon[0] = ICON_WIDTH; | |
152 + icon[1] = ICON_HEIGHT; | |
153 + for (int i = 0; i < ICON_WIDTH * ICON_HEIGHT; ++i) { | |
154 + icon[i + 2] = | |
155 + ICON_PIXEL_DATA[i * 4 + 3] << 24 | | |
156 + ICON_PIXEL_DATA[i * 4 + 0] << 0 | | |
157 + ICON_PIXEL_DATA[i * 4 + 1] << 8 | | |
158 + ICON_PIXEL_DATA[i * 4 + 2] << 16 ; | |
159 + } | |
160 + | |
161 nextfocus = foreground; | |
162 focus(-1); | |
163 } | |
164 @@ -1265,6 +1287,46 @@ xsettitle(Window w, const char *str) | |
165 } | |
166 } | |
167 | |
168 +void | |
169 +xseticon(void) | |
170 +{ | |
171 + Atom ret_type; | |
172 + XWMHints *wmh, *cwmh; | |
173 + int ret_format; | |
174 + unsigned long ret_nitems, ret_nleft; | |
175 + long offset = 0L; | |
176 + unsigned char *data; | |
177 + | |
178 + wmh = XGetWMHints(dpy, win); | |
179 + wmh->flags &= ~(IconPixmapHint | IconMaskHint); | |
180 + wmh->icon_pixmap = wmh->icon_mask = None; | |
181 + | |
182 + | |
183 + if (XGetWindowProperty(dpy, clients[sel]->win, wmatom[WMIcon], … | |
184 + XA_CARDINAL, &ret_type, &ret_format, &re… | |
185 + &ret_nleft, &data) == Success && | |
186 + ret_type == XA_CARDINAL && ret_format == 32) | |
187 + { | |
188 + XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, … | |
189 + PropModeReplace, data, ret_nitems); | |
190 + } else if ((cwmh = XGetWMHints(dpy, clients[sel]->win)) && cwmh… | |
191 + XDeleteProperty(dpy, win, wmatom[WMIcon]); | |
192 + wmh->flags |= IconPixmapHint; | |
193 + wmh->icon_pixmap = cwmh->icon_pixmap; | |
194 + if (cwmh->flags & IconMaskHint) { | |
195 + wmh->flags |= IconMaskHint; | |
196 + wmh->icon_mask = cwmh->icon_mask; | |
197 + } | |
198 + XFree(cwmh); | |
199 + } else { | |
200 + XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, … | |
201 + PropModeReplace, (unsigned char *) icon… | |
202 + } | |
203 + XSetWMHints(dpy, win, wmh); | |
204 + XFree(wmh); | |
205 + XFree(data); | |
206 +} | |
207 + | |
208 void | |
209 usage(void) | |
210 { |