dwm-winicon-6.2-v2.1.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-winicon-6.2-v2.1.diff (12485B)
       ---
            1 diff --git a/config.def.h b/config.def.h
            2 index 1c0b587..b68169e 100644
            3 --- a/config.def.h
            4 +++ b/config.def.h
            5 @@ -5,6 +5,8 @@ static const unsigned int borderpx  = 1;        /* border pixel of windows */
            6  static const unsigned int snap      = 32;       /* snap pixel */
            7  static const int showbar            = 1;        /* 0 means no bar */
            8  static const int topbar             = 1;        /* 0 means bottom bar */
            9 +#define ICONSIZE 16   /* icon size */
           10 +#define ICONSPACING 5 /* space between icon and title */
           11  static const char *fonts[]          = { "monospace:size=10" };
           12  static const char dmenufont[]       = "monospace:size=10";
           13  static const char col_gray1[]       = "#222222";
           14 diff --git a/config.mk b/config.mk
           15 index 6d36cb7..48c38d9 100644
           16 --- a/config.mk
           17 +++ b/config.mk
           18 @@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
           19  
           20  # includes and libs
           21  INCS = -I${X11INC} -I${FREETYPEINC}
           22 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
           23 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lImlib2
           24  
           25  # flags
           26  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           27 diff --git a/drw.c b/drw.c
           28 index 8fd1ca4..77e321a 100644
           29 --- a/drw.c
           30 +++ b/drw.c
           31 @@ -4,6 +4,7 @@
           32  #include <string.h>
           33  #include <X11/Xlib.h>
           34  #include <X11/Xft/Xft.h>
           35 +#include <Imlib2.h>
           36  
           37  #include "drw.h"
           38  #include "util.h"
           39 @@ -71,6 +72,7 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
           40          drw->w = w;
           41          drw->h = h;
           42          drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
           43 +        drw->picture = XRenderCreatePicture(dpy, drw->drawable, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), 0, NULL);
           44          drw->gc = XCreateGC(dpy, root, 0, NULL);
           45          XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
           46  
           47 @@ -85,14 +87,18 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
           48  
           49          drw->w = w;
           50          drw->h = h;
           51 +        if (drw->picture)
           52 +                XRenderFreePicture(drw->dpy, drw->picture);
           53          if (drw->drawable)
           54                  XFreePixmap(drw->dpy, drw->drawable);
           55          drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
           56 +        drw->picture = XRenderCreatePicture(drw->dpy, drw->drawable, XRenderFindVisualFormat(drw->dpy, DefaultVisual(drw->dpy, drw->screen)), 0, NULL);
           57  }
           58  
           59  void
           60  drw_free(Drw *drw)
           61  {
           62 +        XRenderFreePicture(drw->dpy, drw->picture);
           63          XFreePixmap(drw->dpy, drw->drawable);
           64          XFreeGC(drw->dpy, drw->gc);
           65          free(drw);
           66 @@ -235,6 +241,67 @@ drw_setscheme(Drw *drw, Clr *scm)
           67                  drw->scheme = scm;
           68  }
           69  
           70 +Picture
           71 +drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
           72 +        Pixmap pm;
           73 +        Picture pic;
           74 +        GC gc;
           75 +
           76 +        if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
           77 +                XImage img = {
           78 +                        srcw, srch, 0, ZPixmap, src,
           79 +                        ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
           80 +                        32, 0, 32,
           81 +                        0, 0, 0
           82 +                };
           83 +                XInitImage(&img);
           84 +
           85 +                pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
           86 +                gc = XCreateGC(drw->dpy, pm, 0, NULL);
           87 +                XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
           88 +                XFreeGC(drw->dpy, gc);
           89 +
           90 +                pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
           91 +                XFreePixmap(drw->dpy, pm);
           92 +
           93 +                XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
           94 +                XTransform xf;
           95 +                xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
           96 +                xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
           97 +                xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
           98 +                XRenderSetPictureTransform(drw->dpy, pic, &xf);
           99 +        } else {
          100 +                Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
          101 +                if (!origin) return None;
          102 +                imlib_context_set_image(origin);
          103 +                imlib_image_set_has_alpha(1);
          104 +                Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
          105 +                imlib_free_image_and_decache();
          106 +                if (!scaled) return None;
          107 +                imlib_context_set_image(scaled);
          108 +                imlib_image_set_has_alpha(1);
          109 +
          110 +                XImage img = {
          111 +                    dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
          112 +                    ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
          113 +                    32, 0, 32,
          114 +                    0, 0, 0
          115 +                };
          116 +                XInitImage(&img);
          117 +
          118 +                pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
          119 +                gc = XCreateGC(drw->dpy, pm, 0, NULL);
          120 +                XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
          121 +                imlib_free_image_and_decache();
          122 +                XFreeGC(drw->dpy, gc);
          123 +
          124 +                pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
          125 +                XFreePixmap(drw->dpy, pm);
          126 +        }
          127 +
          128 +        return pic;
          129 +}
          130 +
          131  void
          132  drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
          133  {
          134 @@ -378,6 +445,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
          135          return x + (render ? w : 0);
          136  }
          137  
          138 +void
          139 +drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
          140 +{
          141 +        if (!drw)
          142 +                return;
          143 +        XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
          144 +}
          145 +
          146  void
          147  drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
          148  {
          149 diff --git a/drw.h b/drw.h
          150 index 4bcd5ad..71aefa2 100644
          151 --- a/drw.h
          152 +++ b/drw.h
          153 @@ -21,6 +21,7 @@ typedef struct {
          154          int screen;
          155          Window root;
          156          Drawable drawable;
          157 +        Picture picture;
          158          GC gc;
          159          Clr *scheme;
          160          Fnt *fonts;
          161 @@ -49,9 +50,12 @@ void drw_cur_free(Drw *drw, Cur *cursor);
          162  void drw_setfontset(Drw *drw, Fnt *set);
          163  void drw_setscheme(Drw *drw, Clr *scm);
          164  
          165 +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);
          166 +
          167  /* Drawing functions */
          168  void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
          169  int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
          170 +void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic);
          171  
          172  /* Map functions */
          173  void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
          174 diff --git a/dwm.c b/dwm.c
          175 index 4465af1..2f88466 100644
          176 --- a/dwm.c
          177 +++ b/dwm.c
          178 @@ -28,6 +28,8 @@
          179  #include <stdlib.h>
          180  #include <string.h>
          181  #include <unistd.h>
          182 +#include <limits.h>
          183 +#include <stdint.h>
          184  #include <sys/types.h>
          185  #include <sys/wait.h>
          186  #include <X11/cursorfont.h>
          187 @@ -60,7 +62,7 @@
          188  /* enums */
          189  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
          190  enum { SchemeNorm, SchemeSel }; /* color schemes */
          191 -enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
          192 +enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck,
          193         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
          194         NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
          195  enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
          196 @@ -93,6 +95,7 @@ struct Client {
          197          int bw, oldbw;
          198          unsigned int tags;
          199          int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
          200 +        unsigned int icw, ich; Picture icon;
          201          Client *next;
          202          Client *snext;
          203          Monitor *mon;
          204 @@ -169,6 +172,7 @@ static void focus(Client *c);
          205  static void focusin(XEvent *e);
          206  static void focusmon(const Arg *arg);
          207  static void focusstack(const Arg *arg);
          208 +static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich);
          209  static int getrootptr(int *x, int *y);
          210  static long getstate(Window w);
          211  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
          212 @@ -213,6 +217,7 @@ static void togglebar(const Arg *arg);
          213  static void togglefloating(const Arg *arg);
          214  static void toggletag(const Arg *arg);
          215  static void toggleview(const Arg *arg);
          216 +static void freeicon(Client *c);
          217  static void unfocus(Client *c, int setfocus);
          218  static void unmanage(Client *c, int destroyed);
          219  static void unmapnotify(XEvent *e);
          220 @@ -224,6 +229,7 @@ static void updatenumlockmask(void);
          221  static void updatesizehints(Client *c);
          222  static void updatestatus(void);
          223  static void updatetitle(Client *c);
          224 +static void updateicon(Client *c);
          225  static void updatewindowtype(Client *c);
          226  static void updatewmhints(Client *c);
          227  static void view(const Arg *arg);
          228 @@ -731,7 +737,8 @@ drawbar(Monitor *m)
          229          if ((w = m->ww - sw - x) > bh) {
          230                  if (m->sel) {
          231                          drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
          232 -                        drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
          233 +                        drw_text(drw, x, 0, w, bh, lrpad / 2 + (m->sel->icon ? m->sel->icw + ICONSPACING : 0), m->sel->name, 0);
          234 +                        if (m->sel->icon) drw_pic(drw, x + lrpad / 2, (bh - m->sel->ich) / 2, m->sel->icw, m->sel->ich, m->sel->icon);
          235                          if (m->sel->isfloating)
          236                                  drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
          237                  } else {
          238 @@ -871,6 +878,67 @@ getatomprop(Client *c, Atom prop)
          239          return atom;
          240  }
          241  
          242 +static uint32_t prealpha(uint32_t p) {
          243 +        uint8_t a = p >> 24u;
          244 +        uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
          245 +        uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
          246 +        return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
          247 +}
          248 +
          249 +Picture
          250 +geticonprop(Window win, unsigned int *picw, unsigned int *pich)
          251 +{
          252 +        int format;
          253 +        unsigned long n, extra, *p = NULL;
          254 +        Atom real;
          255 +
          256 +        if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType, 
          257 +                                                   &real, &format, &n, &extra, (unsigned char **)&p) != Success)
          258 +                return None; 
          259 +        if (n == 0 || format != 32) { XFree(p); return None; }
          260 +
          261 +        unsigned long *bstp = NULL;
          262 +        uint32_t w, h, sz;
          263 +        {
          264 +                unsigned long *i; const unsigned long *end = p + n;
          265 +                uint32_t bstd = UINT32_MAX, d, m;
          266 +                for (i = p; i < end - 1; i += sz) {
          267 +                        if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
          268 +                        if ((sz = w * h) > end - i) break;
          269 +                        if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
          270 +                }
          271 +                if (!bstp) {
          272 +                        for (i = p; i < end - 1; i += sz) {
          273 +                                if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
          274 +                                if ((sz = w * h) > end - i) break;
          275 +                                if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
          276 +                        }
          277 +                }
          278 +                if (!bstp) { XFree(p); return None; }
          279 +        }
          280 +
          281 +        if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; }
          282 +
          283 +        uint32_t icw, ich;
          284 +        if (w <= h) {
          285 +                ich = ICONSIZE; icw = w * ICONSIZE / h;
          286 +                if (icw == 0) icw = 1;
          287 +        }
          288 +        else {
          289 +                icw = ICONSIZE; ich = h * ICONSIZE / w;
          290 +                if (ich == 0) ich = 1;
          291 +        }
          292 +        *picw = icw; *pich = ich;
          293 +
          294 +        uint32_t i, *bstp32 = (uint32_t *)bstp;
          295 +        for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]);
          296 +
          297 +        Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich);
          298 +        XFree(p);
          299 +
          300 +        return ret;
          301 +}
          302 +
          303  int
          304  getrootptr(int *x, int *y)
          305  {
          306 @@ -1030,6 +1098,7 @@ manage(Window w, XWindowAttributes *wa)
          307          c->h = c->oldh = wa->height;
          308          c->oldbw = wa->border_width;
          309  
          310 +        updateicon(c);
          311          updatetitle(c);
          312          if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
          313                  c->mon = t->mon;
          314 @@ -1240,6 +1309,11 @@ propertynotify(XEvent *e)
          315                          if (c == c->mon->sel)
          316                                  drawbar(c->mon);
          317                  }
          318 +                else if (ev->atom == netatom[NetWMIcon]) {
          319 +                        updateicon(c);
          320 +                        if (c == c->mon->sel)
          321 +                                drawbar(c->mon);
          322 +                }
          323                  if (ev->atom == netatom[NetWMWindowType])
          324                          updatewindowtype(c);
          325          }
          326 @@ -1556,6 +1630,7 @@ setup(void)
          327          netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
          328          netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
          329          netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
          330 +        netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
          331          netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
          332          netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
          333          netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
          334 @@ -1746,6 +1821,15 @@ toggleview(const Arg *arg)
          335          }
          336  }
          337  
          338 +void
          339 +freeicon(Client *c)
          340 +{
          341 +        if (c->icon) {
          342 +                XRenderFreePicture(dpy, c->icon);
          343 +                c->icon = None;
          344 +        }
          345 +}
          346 +
          347  void
          348  unfocus(Client *c, int setfocus)
          349  {
          350 @@ -1767,6 +1851,7 @@ unmanage(Client *c, int destroyed)
          351  
          352          detach(c);
          353          detachstack(c);
          354 +        freeicon(c);
          355          if (!destroyed) {
          356                  wc.border_width = c->oldbw;
          357                  XGrabServer(dpy); /* avoid race conditions */
          358 @@ -2001,6 +2086,13 @@ updatetitle(Client *c)
          359                  strcpy(c->name, broken);
          360  }
          361  
          362 +void
          363 +updateicon(Client *c)
          364 +{
          365 +        freeicon(c);
          366 +        c->icon = geticonprop(c->win, &c->icw, &c->ich);
          367 +}
          368 +
          369  void
          370  updatewindowtype(Client *c)
          371  {