URI: 
       dwm-tag-preview-6.2.diff - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
       dwm-tag-preview-6.2.diff (9776B)
       ---
            1 From 64c79048e03345937c66fbee01b871e44cd579bc Mon Sep 17 00:00:00 2001
            2 From: explosion-mental <explosion0mental@gmail.com>
            3 Date: Tue, 12 Oct 2021 11:57:54 -0500
            4 Subject: [PATCH] [update] fixed scale preview on `XCreateWindow` and added
            5  some comments Allows you to see the contents of an already viewed tag. So a
            6  more accurate description would be to re-view a tag.
            7 
            8 ---
            9  config.def.h |   1 +
           10  config.mk    |   5 +-
           11  dwm.c        | 164 ++++++++++++++++++++++++++++++++++++++++++++-------
           12  3 files changed, 147 insertions(+), 23 deletions(-)
           13 
           14 diff --git a/config.def.h b/config.def.h
           15 index 1c0b587..897bf0c 100644
           16 --- a/config.def.h
           17 +++ b/config.def.h
           18 @@ -3,6 +3,7 @@
           19  /* appearance */
           20  static const unsigned int borderpx  = 1;        /* border pixel of windows */
           21  static const unsigned int snap      = 32;       /* snap pixel */
           22 +static const int scalepreview       = 4;        /* tag preview scaling */
           23  static const int showbar            = 1;        /* 0 means no bar */
           24  static const int topbar             = 1;        /* 0 means bottom bar */
           25  static const char *fonts[]          = { "monospace:size=10" };
           26 diff --git a/config.mk b/config.mk
           27 index 6d36cb7..699007f 100644
           28 --- a/config.mk
           29 +++ b/config.mk
           30 @@ -20,9 +20,12 @@ FREETYPEINC = /usr/include/freetype2
           31  # OpenBSD (uncomment)
           32  #FREETYPEINC = ${X11INC}/freetype2
           33  
           34 +# Imlib2 (tag previews)
           35 +IMLIB2LIBS = -lImlib2
           36 +
           37  # includes and libs
           38  INCS = -I${X11INC} -I${FREETYPEINC}
           39 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
           40 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${IMLIB2LIBS}
           41  
           42  # flags
           43  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           44 diff --git a/dwm.c b/dwm.c
           45 index 4465af1..878abc1 100644
           46 --- a/dwm.c
           47 +++ b/dwm.c
           48 @@ -40,6 +40,7 @@
           49  #include <X11/extensions/Xinerama.h>
           50  #endif /* XINERAMA */
           51  #include <X11/Xft/Xft.h>
           52 +#include <Imlib2.h>
           53  
           54  #include "drw.h"
           55  #include "util.h"
           56 @@ -111,27 +112,6 @@ typedef struct {
           57          void (*arrange)(Monitor *);
           58  } Layout;
           59  
           60 -struct Monitor {
           61 -        char ltsymbol[16];
           62 -        float mfact;
           63 -        int nmaster;
           64 -        int num;
           65 -        int by;               /* bar geometry */
           66 -        int mx, my, mw, mh;   /* screen size */
           67 -        int wx, wy, ww, wh;   /* window area  */
           68 -        unsigned int seltags;
           69 -        unsigned int sellt;
           70 -        unsigned int tagset[2];
           71 -        int showbar;
           72 -        int topbar;
           73 -        Client *clients;
           74 -        Client *sel;
           75 -        Client *stack;
           76 -        Monitor *next;
           77 -        Window barwin;
           78 -        const Layout *lt[2];
           79 -};
           80 -
           81  typedef struct {
           82          const char *class;
           83          const char *instance;
           84 @@ -204,8 +184,10 @@ static void setmfact(const Arg *arg);
           85  static void setup(void);
           86  static void seturgent(Client *c, int urg);
           87  static void showhide(Client *c);
           88 +static void showtagpreview(int tag);
           89  static void sigchld(int unused);
           90  static void spawn(const Arg *arg);
           91 +static void switchtag(void);
           92  static void tag(const Arg *arg);
           93  static void tagmon(const Arg *arg);
           94  static void tile(Monitor *);
           95 @@ -224,6 +206,7 @@ static void updatenumlockmask(void);
           96  static void updatesizehints(Client *c);
           97  static void updatestatus(void);
           98  static void updatetitle(Client *c);
           99 +static void updatepreview(void);
          100  static void updatewindowtype(Client *c);
          101  static void updatewmhints(Client *c);
          102  static void view(const Arg *arg);
          103 @@ -271,6 +254,36 @@ static Window root, wmcheckwin;
          104  /* configuration, allows nested code to access above variables */
          105  #include "config.h"
          106  
          107 +/* We only move this here to get the length of the `tags` array, which probably
          108 + * will generate compatibility issues with other patches. To avoid it, I
          109 + * reccomend patching this at the end or continue with the comment below */
          110 +struct Monitor {
          111 +        char ltsymbol[16];
          112 +        float mfact;
          113 +        int nmaster;
          114 +        int num;
          115 +        int by;               /* bar geometry */
          116 +        int mx, my, mw, mh;   /* screen size */
          117 +        int wx, wy, ww, wh;   /* window area  */
          118 +        unsigned int seltags;
          119 +        unsigned int sellt;
          120 +        unsigned int tagset[2];
          121 +        int previewshow;
          122 +        int showbar;
          123 +        int topbar;
          124 +        Client *clients;
          125 +        Client *sel;
          126 +        Client *stack;
          127 +        Monitor *next;
          128 +        Window barwin;
          129 +        Window tagwin;
          130 +        //change 'LENGTH(tags)' to the actual number of tags you have (9 by def)
          131 +        //if you wish to move this below config.h
          132 +        Pixmap tagmap[LENGTH(tags)];
          133 +        const Layout *lt[2];
          134 +};
          135 +
          136 +
          137  /* compile-time check if all tags fit into an unsigned int bit array. */
          138  struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
          139  
          140 @@ -430,6 +443,10 @@ buttonpress(XEvent *e)
          141                  focus(NULL);
          142          }
          143          if (ev->window == selmon->barwin) {
          144 +                if (selmon->previewshow) {
          145 +                        XUnmapWindow(dpy, selmon->tagwin);
          146 +                                selmon->previewshow = 0;
          147 +                }
          148                  i = x = 0;
          149                  do
          150                          x += TEXTW(tags[i]);
          151 @@ -497,6 +514,7 @@ void
          152  cleanupmon(Monitor *mon)
          153  {
          154          Monitor *m;
          155 +        size_t i;
          156  
          157          if (mon == mons)
          158                  mons = mons->next;
          159 @@ -504,8 +522,13 @@ cleanupmon(Monitor *mon)
          160                  for (m = mons; m && m->next != mon; m = m->next);
          161                  m->next = mon->next;
          162          }
          163 +        for (i = 0; i < LENGTH(tags); i++)
          164 +                if (mon->tagmap[i])
          165 +                        XFreePixmap(dpy, mon->tagmap[i]);
          166          XUnmapWindow(dpy, mon->barwin);
          167          XDestroyWindow(dpy, mon->barwin);
          168 +        XUnmapWindow(dpy, mon->tagwin);
          169 +        XDestroyWindow(dpy, mon->tagwin);
          170          free(mon);
          171  }
          172  
          173 @@ -1121,7 +1144,30 @@ motionnotify(XEvent *e)
          174          static Monitor *mon = NULL;
          175          Monitor *m;
          176          XMotionEvent *ev = &e->xmotion;
          177 +        unsigned int i, x;
          178 +
          179 +        if (ev->window == selmon->barwin) {
          180 +                i = x = 0;
          181 +                do
          182 +                        x += TEXTW(tags[i]);
          183 +                while (ev->x >= x && ++i < LENGTH(tags));
          184  
          185 +                if (i < LENGTH(tags)) {
          186 +                        if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) {
          187 +                                selmon->previewshow = i + 1;
          188 +                                showtagpreview(i);
          189 +                        } else if (selmon->tagset[selmon->seltags] & 1 << i) {
          190 +                                selmon->previewshow = 0;
          191 +                                showtagpreview(0);
          192 +                        }
          193 +                } else if (selmon->previewshow != 0) {
          194 +                        selmon->previewshow = 0;
          195 +                        showtagpreview(0);
          196 +                }
          197 +        } else if (selmon->previewshow != 0) {
          198 +                selmon->previewshow = 0;
          199 +                showtagpreview(0);
          200 +        }
          201          if (ev->window != root)
          202                  return;
          203          if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
          204 @@ -1573,6 +1619,7 @@ setup(void)
          205          /* init bars */
          206          updatebars();
          207          updatestatus();
          208 +        updatepreview();
          209          /* supporting window for NetWMCheck */
          210          wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
          211          XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
          212 @@ -1628,6 +1675,23 @@ showhide(Client *c)
          213          }
          214  }
          215  
          216 +void
          217 +showtagpreview(int tag)
          218 +{
          219 +        if (!selmon->previewshow) {
          220 +                XUnmapWindow(dpy, selmon->tagwin);
          221 +                return;
          222 +        }
          223 +
          224 +        if (selmon->tagmap[tag]) {
          225 +                XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[tag]);
          226 +                XCopyArea(dpy, selmon->tagmap[tag], selmon->tagwin, drw->gc, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview, 0, 0);
          227 +                XSync(dpy, False);
          228 +                XMapWindow(dpy, selmon->tagwin);
          229 +        } else
          230 +                XUnmapWindow(dpy, selmon->tagwin);
          231 +}
          232 +
          233  void
          234  sigchld(int unused)
          235  {
          236 @@ -1652,6 +1716,40 @@ spawn(const Arg *arg)
          237          }
          238  }
          239  
          240 +void
          241 +switchtag(void)
          242 +{
          243 +        int i;
          244 +        unsigned int occ = 0;
          245 +        Client *c;
          246 +        Imlib_Image image;
          247 +
          248 +        for (c = selmon->clients; c; c = c->next)
          249 +                occ |= c->tags;
          250 +        for (i = 0; i < LENGTH(tags); i++) {
          251 +                if (selmon->tagset[selmon->seltags] & 1 << i) {
          252 +                        if (selmon->tagmap[i] != 0) {
          253 +                                XFreePixmap(dpy, selmon->tagmap[i]);
          254 +                                selmon->tagmap[i] = 0;
          255 +                        }
          256 +                        if (occ & 1 << i) {
          257 +                                image = imlib_create_image(sw, sh);
          258 +                                imlib_context_set_image(image);
          259 +                                imlib_context_set_display(dpy);
          260 +                                imlib_context_set_visual(DefaultVisual(dpy, screen));
          261 +                                imlib_context_set_drawable(RootWindow(dpy, screen));
          262 +                                //uncomment the following line and comment the other imlin_copy.. line if you don't want the bar showing on the preview
          263 +                                //imlib_copy_drawable_to_image(0, selmon->wx, selmon->wy, selmon->ww ,selmon->wh, 0, 0, 1);
          264 +                                imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1);
          265 +                                selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, DefaultDepth(dpy, screen));
          266 +                                imlib_context_set_drawable(selmon->tagmap[i]);
          267 +                                imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw, selmon->mh, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview);
          268 +                                imlib_free_image();
          269 +                        }
          270 +                }
          271 +        }
          272 +}
          273 +
          274  void
          275  tag(const Arg *arg)
          276  {
          277 @@ -1740,6 +1838,7 @@ toggleview(const Arg *arg)
          278          unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
          279  
          280          if (newtagset) {
          281 +                switchtag();
          282                  selmon->tagset[selmon->seltags] = newtagset;
          283                  focus(NULL);
          284                  arrange(selmon);
          285 @@ -1805,7 +1904,7 @@ updatebars(void)
          286          XSetWindowAttributes wa = {
          287                  .override_redirect = True,
          288                  .background_pixmap = ParentRelative,
          289 -                .event_mask = ButtonPressMask|ExposureMask
          290 +                .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
          291          };
          292          XClassHint ch = {"dwm", "dwm"};
          293          for (m = mons; m; m = m->next) {
          294 @@ -2001,6 +2100,26 @@ updatetitle(Client *c)
          295                  strcpy(c->name, broken);
          296  }
          297  
          298 +void
          299 +updatepreview(void)
          300 +{
          301 +        Monitor *m;
          302 +
          303 +        XSetWindowAttributes wa = {
          304 +                .override_redirect = True,
          305 +                .background_pixmap = ParentRelative,
          306 +                .event_mask = ButtonPressMask|ExposureMask
          307 +        };
          308 +        for (m = mons; m; m = m->next) {
          309 +                m->tagwin = XCreateWindow(dpy, root, m->wx, m->by + bh, m->mw / scalepreview, m->mh / scalepreview, 0,
          310 +                                DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
          311 +                                CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
          312 +                XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
          313 +                XMapRaised(dpy, m->tagwin);
          314 +                XUnmapWindow(dpy, m->tagwin);
          315 +        }
          316 +}
          317 +
          318  void
          319  updatewindowtype(Client *c)
          320  {
          321 @@ -2037,6 +2156,7 @@ view(const Arg *arg)
          322  {
          323          if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
          324                  return;
          325 +        switchtag();
          326          selmon->seltags ^= 1; /* toggle sel tagset */
          327          if (arg->ui & TAGMASK)
          328                  selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
          329 -- 
          330 2.33.0
          331