From bd5267be8b166d3a59694ead8c6ad813cc22f337 Mon Sep 17 00:00:00 2001 From: speediegq Date: Sat, 3 Sep 2022 17:05:20 +0200 Subject: [PATCH] Add toggle for window icons --- drw.c | 16 +++++++++++++++- drw.h | 8 ++++++++ options.h | 4 +++- speedwm.c | 34 +++++++++++++++++++++++++++++++++- toggle.h | 1 + xresources.h | 2 ++ 6 files changed, 62 insertions(+), 3 deletions(-) diff --git a/drw.c b/drw.c index 85e2506..7cf235f 100644 --- a/drw.c +++ b/drw.c @@ -4,11 +4,13 @@ #include #include #include -#include #include "drw.h" #include "util.h" #include "toggle.h" +#if USEWINICON +#include +#endif #define UTF_INVALID 0xFFFD #define UTF_SIZ 4 @@ -77,7 +79,9 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->depth = depth; drw->cmap = cmap; drw->drawable = XCreatePixmap(dpy, root, w, h, depth); +#if USEWINICON drw->picture = XRenderCreatePicture(dpy, drw->drawable, XRenderFindVisualFormat(dpy, visual), 0, NULL); +#endif drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); @@ -92,18 +96,24 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) drw->w = w; drw->h = h; +#if USEWINICON if (drw->picture) XRenderFreePicture(drw->dpy, drw->picture); +#endif if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); +#if USEWINICON drw->picture = XRenderCreatePicture(drw->dpy, drw->drawable, XRenderFindVisualFormat(drw->dpy, drw->visual), 0, NULL); +#endif } void drw_free(Drw *drw) { + #if USEWINICON XRenderFreePicture(drw->dpy, drw->picture); + #endif XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); drw_fontset_free(drw->fonts); @@ -253,6 +263,7 @@ drw_setscheme(Drw *drw, Clr *scm) drw->scheme = scm; } +#if USEWINICON Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) { Pixmap pm; @@ -313,6 +324,7 @@ drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int return pic; } +#endif void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) @@ -475,6 +487,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp return x + (render ? w : 0); } +#if USEWINICON void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic) { @@ -482,6 +495,7 @@ drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic) return; XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h); } +#endif void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) diff --git a/drw.h b/drw.h index 5e6cbc1..affc03c 100644 --- a/drw.h +++ b/drw.h @@ -1,5 +1,7 @@ /* See LICENSE file for copyright and license details. */ +#include "toggle.h" + typedef struct { Cursor cursor; } Cur; @@ -24,7 +26,9 @@ typedef struct { unsigned int depth; Colormap cmap; Drawable drawable; +#if USEWINICON Picture picture; +#endif GC gc; Clr *scheme; Fnt *fonts; @@ -53,13 +57,17 @@ void drw_cur_free(Drw *drw, Cur *cursor); void drw_setfontset(Drw *drw, Fnt *set); void drw_setscheme(Drw *drw, Clr *scm); +#if USEWINICON Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h); +#endif /* Drawing functions */ void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); void drw_polygon(Drw *drw, int x, int y, int ow, int oh, int sw, int sh, const XPoint *points, int npoints, int shape, int filled); int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); +#if USEWINICON void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic); +#endif /* Map functions */ void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/options.h b/options.h index e26b085..4149ff0 100644 --- a/options.h +++ b/options.h @@ -193,9 +193,11 @@ static int movefullscreenmon = 1; /* Move fullscreen windows to static int fullscreenhidebar = 1; /* Hide the bar when full screen */ static int lockfullscreen = 1; -/* Icon options */ +/* Window icon options */ +#if USEWINICON static int sizeicon = 10; /* size of the icon */ static int spacingicon = 5; /* spacing between the title and icon */ +#endif /* Bar options */ static int barheight = 5; /* Bar height in px, 0 = calculate automatically */ diff --git a/speedwm.c b/speedwm.c index 082771e..a521960 100644 --- a/speedwm.c +++ b/speedwm.c @@ -9,8 +9,10 @@ #include #include #include +#if USEWINICON #include #include +#endif #include #include #include "toggle.h" @@ -85,7 +87,11 @@ enum { SchemeNormBorder, SchemeStatus, }; -enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck, +enum { NetSupported, NetWMName, +#if USEWINICON + NetWMIcon, +#endif + NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDesktop, NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetWMWindowsOpacity, NetClientListStacking, NetClientInfo, NetLast }; /* EWMH atoms */ enum { WMClass, WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ @@ -137,7 +143,9 @@ struct Client { int isfixed, ispermanent, isfloating, isurgent, neverfocus, oldstate, isfullscreen, ignoretransient, issticky, isterminal, noswallow, needresize; pid_t pid; char scratchkey; +#if USEWINICON unsigned int icw, ich; Picture icon; +#endif int issteam; int beingmoved; Client *next; @@ -318,7 +326,9 @@ static void focusstack(int inc, int vis); static void focusstackvis(const Arg *arg); static void focusstackhid(const Arg *arg); static Atom getatomprop(Client *c, Atom prop); +#if USEWINICON static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich); +#endif static int getrootptr(int *x, int *y); static long getstate(Window w); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); @@ -423,7 +433,9 @@ static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggleopacity(const Arg *arg); static void togglefullscr(const Arg *arg); +#if USEWINICON static void freeicon(Client *c); +#endif #if USEMOUSE static void togglewin(const Arg *arg); #endif @@ -445,7 +457,9 @@ static void updatestatus(void); static void updaterules(Client *c); static void updatetitle(Client *c); static void updatepreview(void); +#if USEWINICON static void updateicon(Client *c); +#endif static void updatewindowtype(Client *c); static void updatewmhints(Client *c); static void view(const Arg *arg); @@ -1785,8 +1799,12 @@ drawbar(Monitor *m) if (hideicon) { drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0); } else { + #if USEWINICON drw_text(drw, x, 0, tabw, bh, lrpad / 2 + (c->icon ? c->icw + ICONSPACING : 0), c->name, 0); if (c->icon) drw_pic(drw, x + lrpad / 2, (bh - c->ich) / 2, c->icw, c->ich, c->icon); + #else + drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0); + #endif } } @@ -1987,6 +2005,7 @@ getatomprop(Client *c, Atom prop) return atom; } +#if USEWINICON static uint32_t prealpha(uint32_t p) { uint8_t a = p >> 24u; uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u; @@ -2047,6 +2066,7 @@ geticonprop(Window win, unsigned int *picw, unsigned int *pich) return ret; } +#endif int getrootptr(int *x, int *y) @@ -2515,7 +2535,9 @@ manage(Window w, XWindowAttributes *wa) c->oldbw = wa->border_width; c->cfact = 1.0; +#if USEWINICON updateicon(c); +#endif updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { c->mon = t->mon; @@ -3284,11 +3306,13 @@ propertynotify(XEvent *e) if (c == c->mon->sel) drawbar(c->mon); } +#if USEWINICON else if (ev->atom == netatom[NetWMIcon]) { updateicon(c); if (c == c->mon->sel) drawbar(c->mon); } +#endif if (ev->atom == netatom[NetWMWindowType]) updatewindowtype(c); if (ev->atom == motifatom) @@ -3942,7 +3966,9 @@ setup(void) netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); +#if USEWINICON netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False); +#endif netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); if (fullscreenhidebar) @@ -4354,6 +4380,7 @@ togglefullscr(const Arg *arg) setfullscreen(selmon->sel, !selmon->sel->isfullscreen); } +#if USEWINICON void freeicon(Client *c) { @@ -4363,6 +4390,7 @@ freeicon(Client *c) } updatecurrentdesktop(); } +#endif void unfocus(Client *c, int setfocus) @@ -4401,7 +4429,9 @@ unmanage(Client *c, int destroyed) detach(c); detachstack(c); +#if USEWINICON freeicon(c); +#endif if (!destroyed) { wc.border_width = c->oldbw; XGrabServer(dpy); /* avoid race conditions */ @@ -4835,12 +4865,14 @@ updatetitle(Client *c) #endif } +#if USEWINICON void updateicon(Client *c) { freeicon(c); c->icon = geticonprop(c->win, &c->icw, &c->ich); } +#endif void updatepreview(void) diff --git a/toggle.h b/toggle.h index 6aa5af8..90b5588 100644 --- a/toggle.h +++ b/toggle.h @@ -4,3 +4,4 @@ #define USEIPC 1 /* Whether or not to use IPC. If you set this to 1, set USEIPC to true in config.mk and comment the YAJLLIBS and YAJLINC lines in config.mk. Not compatible with BSDs so for those, set this to 0. */ #define USEALPHA 1 /* Whether or not to use transparency for the bar */ #define USEMOUSE 1 /* Whether or not to use mouse binds */ +#define USEWINICON 1 /* Whether or not to use window icons. Requires imlib to be enabled in config.mk and it must be installed. */ diff --git a/xresources.h b/xresources.h index 00effa0..2b0c4e4 100644 --- a/xresources.h +++ b/xresources.h @@ -118,7 +118,9 @@ ResourcePref resources[] = { { "attachdirection", INTEGER, &attachdirection }, { "resizehints", INTEGER, &resizehints }, { "startontag", INTEGER, &startontag }, +#if USEWINICON { "sizeicon", INTEGER, &sizeicon }, +#endif { "decorhints", INTEGER, &decorhints }, { "swallowclients", INTEGER, &swallowclients }, { "swallowfloating", INTEGER, &swallowfloating },