URI: 
       dwm-tag-preview-6.3.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.3.diff (10565B)
       ---
            1 From 841ad7d5767f945ee9da6c5afc8cff98ca2f8231 Mon Sep 17 00:00:00 2001
            2 From: explosion-mental <explosion0mental@gmail.com>
            3 Date: Thu, 1 Sep 2022 16:21:58 -0500
            4 Subject: [PATCH] [PATCH] tag previews: free() tagmap and add previewtag func
            5 
            6 Allows you to see the contents of an already viewed tag. So a more
            7 accurate description would be to re-view a tag.
            8 
            9 Allows you to see the contents of an already viewed tag. So a more
           10 accurate description would be to re-view a tag.
           11 
           12 Compatibility with the alpha patch (replacing DefaultDepth() and
           13 DefaultVisual() with depth and visual + window masks) and hide vacants can be
           14 achieved, I left some lines to uncomment.
           15 
           16 added:
           17 * more compact structure, more probable to patch on top of other patches
           18   or easier to patch manually (like not moving the Monitor struct..)
           19 * create the window preview in updatebars()
           20 * renamed switchtag() -> takepreview(), makes more sense since it's
           21   "taking" the preview (basically a screenshot).
           22 * option previewbar, whether to show the bar in the preview or not.
           23 * previewtag which takes a tag (unsigned int from 0 to the last tag) and
           24   previews it. This allows to preview tags without using the
           25   cursor/mouse (which avoids a recursive previews preview).
           26   adding it to the TAGKEYS macro makes more sense so I've added it
           27   replacing (keybinding wise, not functionality) toggletag.
           28 ```
           29 \#define TAGKEYS(KEY,TAG) \
           30         { MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
           31         { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
           32         { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
           33 ->        { MODKEY|ControlMask|ShiftMask, KEY,      previewtag,     {.ui = TAG } },
           34 ```
           35 ---
           36  config.def.h |   4 +-
           37  config.mk    |   5 +-
           38  dwm.c        | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-
           39  3 files changed, 145 insertions(+), 3 deletions(-)
           40 
           41 diff --git a/config.def.h b/config.def.h
           42 index a2ac963..eb70348 100644
           43 --- a/config.def.h
           44 +++ b/config.def.h
           45 @@ -3,6 +3,8 @@
           46  /* appearance */
           47  static const unsigned int borderpx  = 1;        /* border pixel of windows */
           48  static const unsigned int snap      = 32;       /* snap pixel */
           49 +static const int scalepreview       = 4;        /* preview scaling (display w and h / scalepreview) */
           50 +static const int previewbar         = 1;        /* show the bar in the preview window */
           51  static const int showbar            = 1;        /* 0 means no bar */
           52  static const int topbar             = 1;        /* 0 means bottom bar */
           53  static const char *fonts[]          = { "monospace:size=10" };
           54 @@ -50,7 +52,7 @@ static const Layout layouts[] = {
           55          { MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
           56          { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
           57          { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
           58 -        { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
           59 +        { MODKEY|ControlMask|ShiftMask, KEY,      previewtag,     {.ui = TAG } },     \
           60  
           61  /* helper for spawning shell commands in the pre dwm-5.0 fashion */
           62  #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
           63 diff --git a/config.mk b/config.mk
           64 index b6eb7e0..6f5129e 100644
           65 --- a/config.mk
           66 +++ b/config.mk
           67 @@ -20,9 +20,12 @@ FREETYPEINC = /usr/include/freetype2
           68  # OpenBSD (uncomment)
           69  #FREETYPEINC = ${X11INC}/freetype2
           70  
           71 +# Imlib2 (tag previews)
           72 +IMLIB2LIBS = -lImlib2
           73 +
           74  # includes and libs
           75  INCS = -I${X11INC} -I${FREETYPEINC}
           76 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
           77 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${IMLIB2LIBS}
           78  
           79  # flags
           80  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
           81 diff --git a/dwm.c b/dwm.c
           82 index a96f33c..0c0ba12 100644
           83 --- a/dwm.c
           84 +++ b/dwm.c
           85 @@ -40,6 +40,7 @@
           86  #include <X11/extensions/Xinerama.h>
           87  #endif /* XINERAMA */
           88  #include <X11/Xft/Xft.h>
           89 +#include <Imlib2.h>
           90  
           91  #include "drw.h"
           92  #include "util.h"
           93 @@ -112,6 +113,9 @@ typedef struct {
           94  } Layout;
           95  
           96  struct Monitor {
           97 +        int previewshow;
           98 +        Window tagwin;
           99 +        Pixmap *tagmap;
          100          char ltsymbol[16];
          101          float mfact;
          102          int nmaster;
          103 @@ -235,6 +239,10 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
          104  static int xerrorstart(Display *dpy, XErrorEvent *ee);
          105  static void zoom(const Arg *arg);
          106  
          107 +static void showtagpreview(unsigned int i);
          108 +static void takepreview(void);
          109 +static void previewtag(const Arg *arg);
          110 +
          111  /* variables */
          112  static const char broken[] = "broken";
          113  static char stext[256];
          114 @@ -438,6 +446,11 @@ buttonpress(XEvent *e)
          115                  if (i < LENGTH(tags)) {
          116                          click = ClkTagBar;
          117                          arg.ui = 1 << i;
          118 +                        /* hide preview if we click the bar */
          119 +                        if (selmon->previewshow) {
          120 +                                selmon->previewshow = 0;
          121 +                                XUnmapWindow(dpy, selmon->tagwin);
          122 +                        }
          123                  } else if (ev->x < x + blw)
          124                          click = ClkLtSymbol;
          125                  else if (ev->x > selmon->ww - (int)TEXTW(stext))
          126 @@ -498,6 +511,7 @@ void
          127  cleanupmon(Monitor *mon)
          128  {
          129          Monitor *m;
          130 +        size_t i;
          131  
          132          if (mon == mons)
          133                  mons = mons->next;
          134 @@ -505,8 +519,14 @@ cleanupmon(Monitor *mon)
          135                  for (m = mons; m && m->next != mon; m = m->next);
          136                  m->next = mon->next;
          137          }
          138 +        for (i = 0; i < LENGTH(tags); i++)
          139 +                if (mon->tagmap[i])
          140 +                        XFreePixmap(dpy, mon->tagmap[i]);
          141 +        free(mon->tagmap);
          142          XUnmapWindow(dpy, mon->barwin);
          143          XDestroyWindow(dpy, mon->barwin);
          144 +        XUnmapWindow(dpy, mon->tagwin);
          145 +        XDestroyWindow(dpy, mon->tagwin);
          146          free(mon);
          147  }
          148  
          149 @@ -641,6 +661,7 @@ createmon(void)
          150          m->topbar = topbar;
          151          m->lt[0] = &layouts[0];
          152          m->lt[1] = &layouts[1 % LENGTH(layouts)];
          153 +        m->tagmap = ecalloc(LENGTH(tags), sizeof(Pixmap));
          154          strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
          155          return m;
          156  }
          157 @@ -1125,6 +1146,36 @@ motionnotify(XEvent *e)
          158          static Monitor *mon = NULL;
          159          Monitor *m;
          160          XMotionEvent *ev = &e->xmotion;
          161 +        unsigned int i, x;
          162 +
          163 +        if (ev->window == selmon->barwin) {
          164 +                i = x = 0;
          165 +                do
          166 +                        x += TEXTW(tags[i]);
          167 +                while (ev->x >= x && ++i < LENGTH(tags));
          168 +        /* FIXME when hovering the mouse over the tags and we view the tag,
          169 +         *       the preview window get's in the preview shot */
          170 +
          171 +                     if (i < LENGTH(tags)) {
          172 +                        if (selmon->previewshow != (i + 1)
          173 +                        && !(selmon->tagset[selmon->seltags] & 1 << i)) {
          174 +                                selmon->previewshow = i + 1;
          175 +                                showtagpreview(i);
          176 +                        } else if (selmon->tagset[selmon->seltags] & 1 << i) {
          177 +                                selmon->previewshow = 0;
          178 +                                XUnmapWindow(dpy, selmon->tagwin);
          179 +                        }
          180 +                } else if (selmon->previewshow) {
          181 +                        selmon->previewshow = 0;
          182 +                        XUnmapWindow(dpy, selmon->tagwin);
          183 +                }
          184 +        } else if (ev->window == selmon->tagwin) {
          185 +                selmon->previewshow = 0;
          186 +                XUnmapWindow(dpy, selmon->tagwin);
          187 +        } else if (selmon->previewshow) {
          188 +                selmon->previewshow = 0;
          189 +                XUnmapWindow(dpy, selmon->tagwin);
          190 +        }
          191  
          192          if (ev->window != root)
          193                  return;
          194 @@ -1530,6 +1581,82 @@ setmfact(const Arg *arg)
          195          arrange(selmon);
          196  }
          197  
          198 +void
          199 +showtagpreview(unsigned int i)
          200 +{
          201 +        if (!selmon->previewshow || !selmon->tagmap[i]) {
          202 +                XUnmapWindow(dpy, selmon->tagwin);
          203 +                return;
          204 +        }
          205 +
          206 +        XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[i]);
          207 +        XCopyArea(dpy, selmon->tagmap[i], selmon->tagwin, drw->gc, 0, 0,
          208 +                        selmon->mw / scalepreview, selmon->mh / scalepreview,
          209 +                        0, 0);
          210 +        XSync(dpy, False);
          211 +        XMapRaised(dpy, selmon->tagwin);
          212 +}
          213 +
          214 +void
          215 +takepreview(void)
          216 +{
          217 +        Client *c;
          218 +        Imlib_Image image;
          219 +        unsigned int occ = 0, i;
          220 +
          221 +        for (c = selmon->clients; c; c = c->next)
          222 +                occ |= c->tags;
          223 +                //occ |= c->tags == 255 ? 0 : c->tags; /* hide vacants */
          224 +
          225 +        for (i = 0; i < LENGTH(tags); i++) {
          226 +                /* searching for tags that are occupied && selected */
          227 +                if (!(occ & 1 << i) || !(selmon->tagset[selmon->seltags] & 1 << i))
          228 +                        continue;
          229 +
          230 +                if (selmon->tagmap[i]) { /* tagmap exist, clean it */
          231 +                        XFreePixmap(dpy, selmon->tagmap[i]);
          232 +                        selmon->tagmap[i] = 0;
          233 +                }
          234 +
          235 +                /* try to unmap the window so it doesn't show the preview on the preview */
          236 +                selmon->previewshow = 0;
          237 +                XUnmapWindow(dpy, selmon->tagwin);
          238 +                XSync(dpy, False);
          239 +
          240 +                if (!(image = imlib_create_image(sw, sh))) {
          241 +                        fprintf(stderr, "dwm: imlib: failed to create image, skipping.");
          242 +                        continue;
          243 +                }
          244 +                imlib_context_set_image(image);
          245 +                imlib_context_set_display(dpy);
          246 +                /* uncomment if using alpha patch */
          247 +                //imlib_image_set_has_alpha(1);
          248 +                //imlib_context_set_blend(0);
          249 +                //imlib_context_set_visual(visual);
          250 +                imlib_context_set_visual(DefaultVisual(dpy, screen));
          251 +                imlib_context_set_drawable(root);
          252 +
          253 +                if (previewbar)
          254 +                        imlib_copy_drawable_to_image(0, selmon->wx, selmon->wy, selmon->ww, selmon->wh, 0, 0, 1);
          255 +                else
          256 +                        imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1);
          257 +                selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, DefaultDepth(dpy, screen));
          258 +                imlib_context_set_drawable(selmon->tagmap[i]);
          259 +                imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw, selmon->mh, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview);
          260 +                imlib_free_image();
          261 +        }
          262 +}
          263 +
          264 +void
          265 +previewtag(const Arg *arg)
          266 +{
          267 +        if (selmon->previewshow != (arg->ui + 1))
          268 +                selmon->previewshow = arg->ui + 1;
          269 +        else
          270 +                selmon->previewshow = 0;
          271 +        showtagpreview(arg->ui);
          272 +}
          273 +
          274  void
          275  setup(void)
          276  {
          277 @@ -1746,6 +1873,7 @@ toggleview(const Arg *arg)
          278          unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
          279  
          280          if (newtagset) {
          281 +                takepreview();
          282                  selmon->tagset[selmon->seltags] = newtagset;
          283                  focus(NULL);
          284                  arrange(selmon);
          285 @@ -1811,10 +1939,18 @@ 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 +
          293          XClassHint ch = {"dwm", "dwm"};
          294          for (m = mons; m; m = m->next) {
          295 +                if (!m->tagwin) {
          296 +                        m->tagwin = XCreateWindow(dpy, root, m->wx, m->by + bh, m->mw / scalepreview,
          297 +                                m->mh / scalepreview, 0, DefaultDepth(dpy, screen), CopyFromParent,
          298 +                                DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
          299 +                        XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
          300 +                        XUnmapWindow(dpy, m->tagwin);
          301 +                }
          302                  if (m->barwin)
          303                          continue;
          304                  m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
          305 @@ -2043,6 +2179,7 @@ view(const Arg *arg)
          306  {
          307          if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
          308                  return;
          309 +        takepreview();
          310          selmon->seltags ^= 1; /* toggle sel tagset */
          311          if (arg->ui & TAGMASK)
          312                  selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
          313 -- 
          314 2.37.3
          315