summaryrefslogtreecommitdiff
path: root/dwm/unpatched
diff options
context:
space:
mode:
Diffstat (limited to 'dwm/unpatched')
-rw-r--r--dwm/unpatched/dwm-preview-all-windows-6.5.diff287
-rw-r--r--dwm/unpatched/dwm-tag-preview-6.3.diff314
2 files changed, 601 insertions, 0 deletions
diff --git a/dwm/unpatched/dwm-preview-all-windows-6.5.diff b/dwm/unpatched/dwm-preview-all-windows-6.5.diff
new file mode 100644
index 0000000..93e5d25
--- /dev/null
+++ b/dwm/unpatched/dwm-preview-all-windows-6.5.diff
@@ -0,0 +1,287 @@
+diff --git a/config.def.h b/config.def.h
+index 9efa774..f462e32 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -95,6 +95,7 @@ static const Key keys[] = {
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_r, previewallwin, {0} },
+ };
+
+ /* button definitions */
+diff --git a/config.mk b/config.mk
+index 8efca9a..8d7c303 100644
+--- a/config.mk
++++ b/config.mk
+@@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 -lXrender -lXcomposite ${XINERAMALIBS} ${FREETYPELIBS}
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index 67c6b2b..0ddd58e 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -40,6 +40,8 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <X11/extensions/Xcomposite.h>
++#include <X11/extensions/Xrender.h>
+
+ #include "drw.h"
+ #include "util.h"
+@@ -84,6 +86,16 @@ typedef struct {
+
+ typedef struct Monitor Monitor;
+ typedef struct Client Client;
++
++typedef struct Preview Preview;
++struct Preview {
++ XImage *orig_image;
++ XImage *scaled_image;
++ Window win;
++ unsigned int x, y;
++ Preview *next;
++};
++
+ struct Client {
+ char name[256];
+ float mina, maxa;
+@@ -97,6 +109,7 @@ struct Client {
+ Client *snext;
+ Monitor *mon;
+ Window win;
++ Preview pre;
+ };
+
+ typedef struct {
+@@ -233,6 +246,10 @@ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
++static void previewallwin();
++static void setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi);
++static XImage *getwindowximage(Client *c);
++static XImage *scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch);
+
+ /* variables */
+ static const char broken[] = "broken";
+@@ -2140,6 +2157,212 @@ zoom(const Arg *arg)
+ pop(c);
+ }
+
++void
++previewallwin(){
++ int composite_event_base, composite_error_base;
++ if (!XCompositeQueryExtension(dpy, &composite_event_base, &composite_error_base)) {
++ fprintf(stderr, "Error: XComposite extension not available.\n");
++ return;
++ }
++ Monitor *m = selmon;
++ Client *c, *focus_c = NULL;
++ unsigned int n;
++ for (n = 0, c = m->clients; c; c = c->next, n++){
++ /* If you hit actualfullscreen patch Unlock the notes below */
++ // if (c->isfullscreen)
++ // togglefullscr(&(Arg){0});
++ /* If you hit awesomebar patch Unlock the notes below */
++ // if (HIDDEN(c))
++ // continue;
++ c->pre.orig_image = getwindowximage(c);
++ }
++ if (n == 0)
++ return;
++ setpreviewwindowsizepositions(n, m, 60, 15);
++ XEvent event;
++ for(c = m->clients; c; c = c->next){
++ if (!c->pre.win)
++ c->pre.win = XCreateSimpleWindow(dpy, root, c->pre.x, c->pre.y, c->pre.scaled_image->width, c->pre.scaled_image->height, 1, BlackPixel(dpy, screen), WhitePixel(dpy, screen));
++ else
++ XMoveResizeWindow(dpy, c->pre.win, c->pre.x, c->pre.y, c->pre.scaled_image->width, c->pre.scaled_image->height);
++ XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel);
++ XSetWindowBorderWidth(dpy, c->pre.win, borderpx);
++ XUnmapWindow(dpy, c->win);
++ if (c->pre.win){
++ XSelectInput(dpy, c->pre.win, ButtonPress | EnterWindowMask | LeaveWindowMask );
++ XMapWindow(dpy, c->pre.win);
++ XPutImage(dpy, c->pre.win, drw->gc, c->pre.scaled_image, 0, 0, 0, 0, c->pre.scaled_image->width, c->pre.scaled_image->height);
++ }
++ }
++ while (1) {
++ XNextEvent(dpy, &event);
++ if (event.type == ButtonPress)
++ if (event.xbutton.button == Button1){
++ for(c = m->clients; c; c = c->next){
++ XUnmapWindow(dpy, c->pre.win);
++ if (event.xbutton.window == c->pre.win){
++ selmon->seltags ^= 1; /* toggle sel tagset */
++ m->tagset[selmon->seltags] = c->tags;
++ focus_c = c;
++ focus(NULL);
++ /* If you hit awesomebar patch Unlock the notes below */
++ // if (HIDDEN(c)){
++ // showwin(c);
++ // continue;
++ // }
++ }
++ /* If you hit awesomebar patch Unlock the notes below;
++ * And you should add the following line to "hidewin" Function
++ * c->pre.orig_image = getwindowximage(c);
++ * */
++ // if (HIDDEN(c)){
++ // continue;
++ // }
++ XMapWindow(dpy, c->win);
++ XDestroyImage(c->pre.orig_image);
++ XDestroyImage(c->pre.scaled_image);
++ }
++ break;
++ }
++ if (event.type == EnterNotify)
++ for(c = m->clients; c; c = c->next)
++ if (event.xcrossing.window == c->pre.win){
++ XSetWindowBorder(dpy, c->pre.win, scheme[SchemeSel][ColBorder].pixel);
++ break;
++ }
++ if (event.type == LeaveNotify)
++ for(c = m->clients; c; c = c->next)
++ if (event.xcrossing.window == c->pre.win){
++ XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel);
++ break;
++ }
++ }
++ arrange(m);
++ focus(focus_c);
++}
++
++void
++setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi){
++ unsigned int i, j;
++ unsigned int cx, cy, cw, ch, cmaxh;
++ unsigned int cols, rows;
++ Client *c, *tmpc;
++
++ if (n == 1) {
++ c = m->clients;
++ cw = (m->ww - 2 * gappo) * 0.8;
++ ch = (m->wh - 2 * gappo) * 0.9;
++ c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
++ c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width) / 2;
++ c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2;
++ return;
++ }
++ if (n == 2) {
++ c = m->clients;
++ cw = (m->ww - 2 * gappo - gappi) / 2;
++ ch = (m->wh - 2 * gappo) * 0.7;
++ c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
++ c->next->pre.scaled_image = scaledownimage(c->next->pre.orig_image, cw, ch);
++ c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width - gappi - c->next->pre.scaled_image->width) / 2;
++ c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2;
++ c->next->pre.x = c->pre.x + c->pre.scaled_image->width + gappi;
++ c->next->pre.y = m->my + (m->mh - c->next->pre.scaled_image->height) / 2;
++ return;
++ }
++ for (cols = 0; cols <= n / 2; cols++)
++ if (cols * cols >= n)
++ break;
++ rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols;
++ ch = (m->wh - 2 * gappo) / rows;
++ cw = (m->ww - 2 * gappo) / cols;
++ c = m->clients;
++ cy = 0;
++ for (i = 0; i < rows; i++) {
++ cx = 0;
++ cmaxh = 0;
++ tmpc = c;
++ for (int j = 0; j < cols; j++) {
++ if (!c)
++ break;
++ c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
++ c->pre.x = cx;
++ cmaxh = c->pre.scaled_image->height > cmaxh ? c->pre.scaled_image->height : cmaxh;
++ cx += c->pre.scaled_image->width + gappi;
++ c = c->next;
++ }
++ c = tmpc;
++ cx = m->wx + (m->ww - cx) / 2;
++ for (j = 0; j < cols; j++) {
++ if (!c)
++ break;
++ c->pre.x += cx;
++ c->pre.y = cy + (cmaxh - c->pre.scaled_image->height) / 2;
++ c = c->next;
++ }
++ cy += cmaxh + gappi;
++ }
++ cy = m->wy + (m->wh - cy) / 2;
++ for (c = m->clients; c; c = c->next)
++ c->pre.y += cy;
++}
++
++XImage
++*getwindowximage(Client *c) {
++ XCompositeRedirectWindow(dpy, c->win, CompositeRedirectAutomatic);
++ XWindowAttributes attr;
++ XGetWindowAttributes( dpy, c->win, &attr );
++ XRenderPictFormat *format = XRenderFindVisualFormat( dpy, attr.visual );
++ int hasAlpha = ( format->type == PictTypeDirect && format->direct.alphaMask );
++ XRenderPictureAttributes pa;
++ pa.subwindow_mode = IncludeInferiors;
++ Picture picture = XRenderCreatePicture( dpy, c->win, format, CPSubwindowMode, &pa );
++ Pixmap pixmap = XCreatePixmap(dpy, root, c->w, c->h, 32);
++ XRenderPictureAttributes pa2;
++ XRenderPictFormat *format2 = XRenderFindStandardFormat(dpy, PictStandardARGB32);
++ Picture pixmapPicture = XRenderCreatePicture( dpy, pixmap, format2, 0, &pa2 );
++ XRenderColor color;
++ color.red = 0x0000;
++ color.green = 0x0000;
++ color.blue = 0x0000;
++ color.alpha = 0x0000;
++ XRenderFillRectangle (dpy, PictOpSrc, pixmapPicture, &color, 0, 0, c->w, c->h);
++ XRenderComposite(dpy, hasAlpha ? PictOpOver : PictOpSrc, picture, 0,
++ pixmapPicture, 0, 0, 0, 0, 0, 0,
++ c->w, c->h);
++ XImage* temp = XGetImage( dpy, pixmap, 0, 0, c->w, c->h, AllPlanes, ZPixmap );
++ temp->red_mask = format2->direct.redMask << format2->direct.red;
++ temp->green_mask = format2->direct.greenMask << format2->direct.green;
++ temp->blue_mask = format2->direct.blueMask << format2->direct.blue;
++ temp->depth = DefaultDepth(dpy, screen);
++ XCompositeUnredirectWindow(dpy, c->win, CompositeRedirectAutomatic);
++ return temp;
++}
++
++XImage
++*scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch) {
++ int factor_w = orig_image->width / cw + 1;
++ int factor_h = orig_image->height / ch + 1;
++ int scale_factor = factor_w > factor_h ? factor_w : factor_h;
++ int scaled_width = orig_image->width / scale_factor;
++ int scaled_height = orig_image->height / scale_factor;
++ XImage *scaled_image = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)),
++ orig_image->depth,
++ ZPixmap, 0, NULL,
++ scaled_width, scaled_height,
++ 32, 0);
++ scaled_image->data = malloc(scaled_image->height * scaled_image->bytes_per_line);
++ for (int y = 0; y < scaled_height; y++) {
++ for (int x = 0; x < scaled_width; x++) {
++ int orig_x = x * scale_factor;
++ int orig_y = y * scale_factor;
++ unsigned long pixel = XGetPixel(orig_image, orig_x, orig_y);
++ XPutPixel(scaled_image, x, y, pixel);
++ }
++ }
++ scaled_image->depth = orig_image->depth;
++ return scaled_image;
++}
++
+ int
+ main(int argc, char *argv[])
+ {
diff --git a/dwm/unpatched/dwm-tag-preview-6.3.diff b/dwm/unpatched/dwm-tag-preview-6.3.diff
new file mode 100644
index 0000000..514690c
--- /dev/null
+++ b/dwm/unpatched/dwm-tag-preview-6.3.diff
@@ -0,0 +1,314 @@
+# From 841ad7d5767f945ee9da6c5afc8cff98ca2f8231 Mon Sep 17 00:00:00 2001
+# From: explosion-mental <explosion0mental@gmail.com>
+# Date: Thu, 1 Sep 2022 16:21:58 -0500
+# Subject: [PATCH] [PATCH] tag previews: free() tagmap and add previewtag func
+#
+# Allows you to see the contents of an already viewed tag. So a more
+# accurate description would be to re-view a tag.
+#
+# Allows you to see the contents of an already viewed tag. So a more
+# accurate description would be to re-view a tag.
+#
+# Compatibility with the alpha patch (replacing DefaultDepth() and
+# DefaultVisual() with depth and visual + window masks) and hide vacants can be
+# achieved, I left some lines to uncomment.
+#
+# added:
+# * more compact structure, more probable to patch on top of other patches
+# or easier to patch manually (like not moving the Monitor struct..)
+# * create the window preview in updatebars()
+# * renamed switchtag() -> takepreview(), makes more sense since it's
+# "taking" the preview (basically a screenshot).
+# * option previewbar, whether to show the bar in the preview or not.
+# * previewtag which takes a tag (unsigned int from 0 to the last tag) and
+# previews it. This allows to preview tags without using the
+# cursor/mouse (which avoids a recursive previews preview).
+# adding it to the TAGKEYS macro makes more sense so I've added it
+# replacing (keybinding wise, not functionality) toggletag.
+# ```
+# \#define TAGKEYS(KEY,TAG) \
+# { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
+# { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
+# { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
+# -> { MODKEY|ControlMask|ShiftMask, KEY, previewtag, {.ui = TAG } },
+# ```
+# ---
+# config.def.h | 4 +-
+# config.mk | 5 +-
+# dwm.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+# 3 files changed, 145 insertions(+), 3 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..eb70348 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,8 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const int scalepreview = 4; /* preview scaling (display w and h / scalepreview) */
++static const int previewbar = 1; /* show the bar in the preview window */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "monospace:size=10" };
+@@ -50,7 +52,7 @@ static const Layout layouts[] = {
+ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
+ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
+ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
+- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
++ { MODKEY|ControlMask|ShiftMask, KEY, previewtag, {.ui = TAG } }, \
+
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+diff --git a/config.mk b/config.mk
+index b6eb7e0..6f5129e 100644
+--- a/config.mk
++++ b/config.mk
+@@ -20,9 +20,12 @@ FREETYPEINC = /usr/include/freetype2
+ # OpenBSD (uncomment)
+ #FREETYPEINC = ${X11INC}/freetype2
+
++# Imlib2 (tag previews)
++IMLIB2LIBS = -lImlib2
++
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${IMLIB2LIBS}
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index a96f33c..0c0ba12 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -40,6 +40,7 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <Imlib2.h>
+
+ #include "drw.h"
+ #include "util.h"
+@@ -112,6 +113,9 @@ typedef struct {
+ } Layout;
+
+ struct Monitor {
++ int previewshow;
++ Window tagwin;
++ Pixmap *tagmap;
+ char ltsymbol[16];
+ float mfact;
+ int nmaster;
+@@ -235,6 +239,10 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
+
++static void showtagpreview(unsigned int i);
++static void takepreview(void);
++static void previewtag(const Arg *arg);
++
+ /* variables */
+ static const char broken[] = "broken";
+ static char stext[256];
+@@ -438,6 +446,11 @@ buttonpress(XEvent *e)
+ if (i < LENGTH(tags)) {
+ click = ClkTagBar;
+ arg.ui = 1 << i;
++ /* hide preview if we click the bar */
++ if (selmon->previewshow) {
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ }
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+ else if (ev->x > selmon->ww - (int)TEXTW(stext))
+@@ -498,6 +511,7 @@ void
+ cleanupmon(Monitor *mon)
+ {
+ Monitor *m;
++ size_t i;
+
+ if (mon == mons)
+ mons = mons->next;
+@@ -505,8 +519,14 @@ cleanupmon(Monitor *mon)
+ for (m = mons; m && m->next != mon; m = m->next);
+ m->next = mon->next;
+ }
++ for (i = 0; i < LENGTH(tags); i++)
++ if (mon->tagmap[i])
++ XFreePixmap(dpy, mon->tagmap[i]);
++ free(mon->tagmap);
+ XUnmapWindow(dpy, mon->barwin);
+ XDestroyWindow(dpy, mon->barwin);
++ XUnmapWindow(dpy, mon->tagwin);
++ XDestroyWindow(dpy, mon->tagwin);
+ free(mon);
+ }
+
+@@ -641,6 +661,7 @@ createmon(void)
+ m->topbar = topbar;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
++ m->tagmap = ecalloc(LENGTH(tags), sizeof(Pixmap));
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ return m;
+ }
+@@ -1125,6 +1146,36 @@ motionnotify(XEvent *e)
+ static Monitor *mon = NULL;
+ Monitor *m;
+ XMotionEvent *ev = &e->xmotion;
++ unsigned int i, x;
++
++ if (ev->window == selmon->barwin) {
++ i = x = 0;
++ do
++ x += TEXTW(tags[i]);
++ while (ev->x >= x && ++i < LENGTH(tags));
++ /* FIXME when hovering the mouse over the tags and we view the tag,
++ * the preview window get's in the preview shot */
++
++ if (i < LENGTH(tags)) {
++ if (selmon->previewshow != (i + 1)
++ && !(selmon->tagset[selmon->seltags] & 1 << i)) {
++ selmon->previewshow = i + 1;
++ showtagpreview(i);
++ } else if (selmon->tagset[selmon->seltags] & 1 << i) {
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ }
++ } else if (selmon->previewshow) {
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ }
++ } else if (ev->window == selmon->tagwin) {
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ } else if (selmon->previewshow) {
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ }
+
+ if (ev->window != root)
+ return;
+@@ -1530,6 +1581,82 @@ setmfact(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++showtagpreview(unsigned int i)
++{
++ if (!selmon->previewshow || !selmon->tagmap[i]) {
++ XUnmapWindow(dpy, selmon->tagwin);
++ return;
++ }
++
++ XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[i]);
++ XCopyArea(dpy, selmon->tagmap[i], selmon->tagwin, drw->gc, 0, 0,
++ selmon->mw / scalepreview, selmon->mh / scalepreview,
++ 0, 0);
++ XSync(dpy, False);
++ XMapRaised(dpy, selmon->tagwin);
++}
++
++void
++takepreview(void)
++{
++ Client *c;
++ Imlib_Image image;
++ unsigned int occ = 0, i;
++
++ for (c = selmon->clients; c; c = c->next)
++ occ |= c->tags;
++ //occ |= c->tags == 255 ? 0 : c->tags; /* hide vacants */
++
++ for (i = 0; i < LENGTH(tags); i++) {
++ /* searching for tags that are occupied && selected */
++ if (!(occ & 1 << i) || !(selmon->tagset[selmon->seltags] & 1 << i))
++ continue;
++
++ if (selmon->tagmap[i]) { /* tagmap exist, clean it */
++ XFreePixmap(dpy, selmon->tagmap[i]);
++ selmon->tagmap[i] = 0;
++ }
++
++ /* try to unmap the window so it doesn't show the preview on the preview */
++ selmon->previewshow = 0;
++ XUnmapWindow(dpy, selmon->tagwin);
++ XSync(dpy, False);
++
++ if (!(image = imlib_create_image(sw, sh))) {
++ fprintf(stderr, "dwm: imlib: failed to create image, skipping.");
++ continue;
++ }
++ imlib_context_set_image(image);
++ imlib_context_set_display(dpy);
++ /* uncomment if using alpha patch */
++ // imlib_image_set_has_alpha(1);
++ // imlib_context_set_blend(0);
++ // imlib_context_set_visual(visual);
++ imlib_context_set_visual(DefaultVisual(dpy, screen));
++ imlib_context_set_drawable(root);
++
++ if (previewbar)
++ imlib_copy_drawable_to_image(0, selmon->wx, selmon->wy, selmon->ww, selmon->wh, 0, 0, 1);
++ else
++ imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1);
++ selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, DefaultDepth(dpy, screen));
++ imlib_context_set_drawable(selmon->tagmap[i]);
++ imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw, selmon->mh, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview);
++ imlib_free_image();
++ }
++}
++
++void
++previewtag(const Arg *arg)
++{
++ if (selmon->previewshow != (arg->ui + 1))
++ selmon->previewshow = arg->ui + 1;
++ else
++ selmon->previewshow = 0;
++ showtagpreview(arg->ui);
++}
++
+ void
+ setup(void)
+ {
+@@ -1746,6 +1873,7 @@ toggleview(const Arg *arg)
+ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+
+ if (newtagset) {
++ takepreview();
+ selmon->tagset[selmon->seltags] = newtagset;
+ focus(NULL);
+ arrange(selmon);
+@@ -1811,10 +1939,18 @@ updatebars(void)
+ XSetWindowAttributes wa = {
+ .override_redirect = True,
+ .background_pixmap = ParentRelative,
+- .event_mask = ButtonPressMask|ExposureMask
++ .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
+ };
++
+ XClassHint ch = {"dwm", "dwm"};
+ for (m = mons; m; m = m->next) {
++ if (!m->tagwin) {
++ m->tagwin = XCreateWindow(dpy, root, m->wx, m->by + bh, m->mw / scalepreview,
++ m->mh / scalepreview, 0, DefaultDepth(dpy, screen), CopyFromParent,
++ DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
++ XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
++ XUnmapWindow(dpy, m->tagwin);
++ }
+ if (m->barwin)
+ continue;
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+@@ -2043,6 +2179,7 @@ view(const Arg *arg)
+ {
+ if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+ return;
++ takepreview();
+ selmon->seltags ^= 1; /* toggle sel tagset */
+ if (arg->ui & TAGMASK)
+ selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+--
+2.37.3