Files
tabbed/tabbed-icon-edited.diff

190 lines
8.5 KiB
Diff

diff --git a/TODO b/TODO
index 8e1986d..dbcb930 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,3 @@
# TODO
* add some way to detach windows
* add some way to attach windows
-
diff --git a/icon.h b/icon.h
new file mode 100644
index 0000000..e2ef631
--- /dev/null
+++ b/icon.h
@@ -0,0 +1,41 @@
+/* GIMP RGBA C-Source image dump (icon.c) */
+
+#define ICON_WIDTH (16)
+#define ICON_HEIGHT (16)
+#define ICON_BYTES_PER_PIXEL (4) /* 2:RGB16, 3:RGB, 4:RGBA */
+#define ICON_COMMENT \
+ "GIMP -> Export -> C-Source -> Prefixed name = ICON, Use macros, Save alpha"
+#define ICON_PIXEL_DATA ((unsigned char*) ICON_pixel_data)
+static const unsigned char ICON_pixel_data[16 * 16 * 4 + 1] =
+("\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000"
+ "\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000"
+ "\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000"
+ "\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000"
+ "\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377"
+ "\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000"
+ "\000\000\377\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
+ "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
+ "\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\377\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\001\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000"
+ "\000\000\377\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\000\000\000\000"
+ "\000\000\000\000\000\000\000\000\377\000\000\000\377");
diff --git a/tabbed.c b/tabbed.c
index eafe28a..ec6212e 100644
--- a/tabbed.c
+++ b/tabbed.c
@@ -18,6 +18,7 @@
#include <X11/Xft/Xft.h>
#include "arg.h"
+#include "icon.h"
/* XEMBED messages */
#define XEMBED_EMBEDDED_NOTIFY 0
@@ -49,7 +50,7 @@
enum { ColFG, ColBG, ColLast }; /* color */
enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen,
- XEmbed, WMSelectTab, WMLast }; /* default atoms */
+ XEmbed, WMSelectTab, WMIcon, WMLast }; /* default atoms */
typedef union {
int i;
@@ -135,6 +136,7 @@ static void updatenumlockmask(void);
static void updatetitle(int c);
static int xerror(Display *dpy, XErrorEvent *ee);
static void xsettitle(Window w, const char *str);
+static void xseticon(void);
/* variables */
static int screen;
@@ -455,6 +458,8 @@ focus(int c)
n += snprintf(&buf[n], sizeof(buf) - n, " %s", cmd[i]);
xsettitle(win, buf);
+ XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) icon, ICON_WIDTH * ICON_HEIGHT + 2);
XRaiseWindow(dpy, win);
return;
@@ -474,6 +479,7 @@ focus(int c)
lastsel = sel;
sel = c;
}
+ xseticon();
if (clients[c]->urgent && (wmh = XGetWMHints(dpy, clients[c]->win))) {
wmh->flags &= ~XUrgencyHint;
@@ -868,9 +874,13 @@ propertynotify(const XEvent *e)
}
}
XFree(wmh);
+ if (c == sel)
+ xseticon();
} else if (ev->state != PropertyDelete && ev->atom == XA_WM_NAME &&
(c = getclient(ev->window)) > -1) {
updatetitle(c);
+ } else if (ev->atom == wmatom[WMIcon] && (c = getclient(ev->window)) > -1 && c == sel) {
+ xseticon();
}
}
@@ -995,6 +1005,7 @@ setup(void)
wmatom[WMSelectTab] = XInternAtom(dpy, "_TABBED_SELECT_TAB", False);
wmatom[WMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
wmatom[XEmbed] = XInternAtom(dpy, "_XEMBED", False);
+ wmatom[WMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
/* init appearance */
wx = 0;
@@ -1074,6 +1085,17 @@ setup(void)
snprintf(winid, sizeof(winid), "%lu", win);
setenv("XEMBED", winid, 1);
+ /* change icon from RGBA to ARGB */
+ icon[0] = ICON_WIDTH;
+ icon[1] = ICON_HEIGHT;
+ for (int i = 0; i < ICON_WIDTH * ICON_HEIGHT; ++i) {
+ icon[i + 2] =
+ ICON_PIXEL_DATA[i * 4 + 3] << 24 |
+ ICON_PIXEL_DATA[i * 4 + 0] << 0 |
+ ICON_PIXEL_DATA[i * 4 + 1] << 8 |
+ ICON_PIXEL_DATA[i * 4 + 2] << 16 ;
+ }
+
nextfocus = foreground;
focus(-1);
}
@@ -1265,6 +1287,46 @@ xsettitle(Window w, const char *str)
}
}
+void
+xseticon(void)
+{
+ Atom ret_type;
+ XWMHints *wmh, *cwmh;
+ int ret_format;
+ unsigned long ret_nitems, ret_nleft;
+ long offset = 0L;
+ unsigned char *data;
+
+ wmh = XGetWMHints(dpy, win);
+ wmh->flags &= ~(IconPixmapHint | IconMaskHint);
+ wmh->icon_pixmap = wmh->icon_mask = None;
+
+
+ if (XGetWindowProperty(dpy, clients[sel]->win, wmatom[WMIcon], offset, LONG_MAX, False,
+ XA_CARDINAL, &ret_type, &ret_format, &ret_nitems,
+ &ret_nleft, &data) == Success &&
+ ret_type == XA_CARDINAL && ret_format == 32)
+ {
+ XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, 32,
+ PropModeReplace, data, ret_nitems);
+ } else if ((cwmh = XGetWMHints(dpy, clients[sel]->win)) && cwmh->flags & IconPixmapHint) {
+ XDeleteProperty(dpy, win, wmatom[WMIcon]);
+ wmh->flags |= IconPixmapHint;
+ wmh->icon_pixmap = cwmh->icon_pixmap;
+ if (cwmh->flags & IconMaskHint) {
+ wmh->flags |= IconMaskHint;
+ wmh->icon_mask = cwmh->icon_mask;
+ }
+ XFree(cwmh);
+ } else {
+ XChangeProperty(dpy, win, wmatom[WMIcon], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) icon, ICON_WIDTH * ICON_HEIGHT + 2);
+ }
+ XSetWMHints(dpy, win, wmh);
+ XFree(wmh);
+ XFree(data);
+}
+
void
usage(void)
{