commit ea1f3406af87ecd227a6e9a2ca41ed6180309c7b
parent 3a291bab1640a9095e7061527cae896359eba964
Author: explosion-mental <explosion0mental@gmail.com>
Date:   Wed, 11 Aug 2021 23:10:47 -0500
[dwm][patch][tag preview] add
See the contents of a tag by hovering on it.
Diffstat:
3 files changed, 340 insertions(+), 0 deletions(-)
diff --git a/dwm.suckless.org/patches/tag-previews/dwm-tag-preview-6.2.diff b/dwm.suckless.org/patches/tag-previews/dwm-tag-preview-6.2.diff
@@ -0,0 +1,318 @@
+From 7381bf4e11b76ad8f51c94bd226296bf971ad430 Mon Sep 17 00:00:00 2001
+From: explosion-mental <explosion0mental@gmail.com>
+Date: Wed, 11 Aug 2021 17:28:32 -0500
+Subject: [PATCH] Tag preview This is a patch extracted from
+ https://github.com/siduck76/chadwm build. First view a tag with at least a
+ client, then move to any other tag. Finally hover you mouse over the tag you
+ were previously and you got a tag preview.
+
+---
+ config.def.h |   1 +
+ config.mk    |   5 +-
+ dwm.c        | 157 +++++++++++++++++++++++++++++++++++++++++++--------
+ 3 files changed, 140 insertions(+), 23 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..81a3d3d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,7 @@
+ /* appearance */
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
+ static const unsigned int snap      = 32;       /* snap pixel */
++static const int scalepreview       = 4;        /* Tag preview scaling */
+ 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" };
+diff --git a/config.mk b/config.mk
+index 6d36cb7..70b2a3a 100644
+--- a/config.mk
++++ b/config.mk
+@@ -20,9 +20,12 @@ FREETYPEINC = /usr/include/freetype2
+ # OpenBSD (uncomment)
+ #FREETYPEINC = ${X11INC}/freetype2
+ 
++# Tag previews are done with Imlib2
++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=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index 4465af1..aafdccc 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"
+@@ -111,27 +112,6 @@ typedef struct {
+ 	void (*arrange)(Monitor *);
+ } Layout;
+ 
+-struct Monitor {
+-	char ltsymbol[16];
+-	float mfact;
+-	int nmaster;
+-	int num;
+-	int by;               /* bar geometry */
+-	int mx, my, mw, mh;   /* screen size */
+-	int wx, wy, ww, wh;   /* window area  */
+-	unsigned int seltags;
+-	unsigned int sellt;
+-	unsigned int tagset[2];
+-	int showbar;
+-	int topbar;
+-	Client *clients;
+-	Client *sel;
+-	Client *stack;
+-	Monitor *next;
+-	Window barwin;
+-	const Layout *lt[2];
+-};
+-
+ typedef struct {
+ 	const char *class;
+ 	const char *instance;
+@@ -204,8 +184,10 @@ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
++static void showtagpreview(int tag);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static void switchtag(void);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+@@ -224,6 +206,7 @@ static void updatenumlockmask(void);
+ static void updatesizehints(Client *c);
+ static void updatestatus(void);
+ static void updatetitle(Client *c);
++static void updatepreview(void);
+ static void updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+@@ -271,6 +254,31 @@ static Window root, wmcheckwin;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++struct Monitor {
++	char ltsymbol[16];
++	float mfact;
++	int nmaster;
++	int num;
++	int by;               /* bar geometry */
++	int mx, my, mw, mh;   /* screen size */
++	int wx, wy, ww, wh;   /* window area  */
++	unsigned int seltags;
++	unsigned int sellt;
++	unsigned int tagset[2];
++	int showbar;
++	int topbar;
++	Client *clients;
++	Client *sel;
++	Client *stack;
++	Monitor *next;
++	Window barwin;
++	Window tagwin;
++	int previewshow;
++	Pixmap tagmap[LENGTH(tags)];
++	const Layout *lt[2];
++};
++
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -430,6 +438,10 @@ buttonpress(XEvent *e)
+ 		focus(NULL);
+ 	}
+ 	if (ev->window == selmon->barwin) {
++		if (selmon->previewshow) {
++			XUnmapWindow(dpy, selmon->tagwin);
++				selmon->previewshow = 0;
++		}
+ 		i = x = 0;
+ 		do
+ 			x += TEXTW(tags[i]);
+@@ -504,8 +516,13 @@ cleanupmon(Monitor *mon)
+ 		for (m = mons; m && m->next != mon; m = m->next);
+ 		m->next = mon->next;
+ 	}
++	for (size_t i = 0; i < LENGTH(tags); i++)
++		if (mon->tagmap[i])
++			XFreePixmap(dpy, mon->tagmap[i]);
+ 	XUnmapWindow(dpy, mon->barwin);
+ 	XDestroyWindow(dpy, mon->barwin);
++	XUnmapWindow(dpy, mon->tagwin);
++	XDestroyWindow(dpy, mon->tagwin);
+ 	free(mon);
+ }
+ 
+@@ -1121,7 +1138,31 @@ 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));
+ 
++	     	if (i < LENGTH(tags)) {
++			if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) {
++	     			selmon->previewshow = i + 1;
++	     			showtagpreview(i);
++			}
++		else if (selmon->tagset[selmon->seltags] & 1 << i) {
++				selmon->previewshow = 0;
++				showtagpreview(0);
++		  }
++		} else if (selmon->previewshow != 0) {
++	     		selmon->previewshow = 0;
++	     		showtagpreview(0);
++	     	}
++	} else if (selmon->previewshow != 0) {
++		selmon->previewshow = 0;
++	     	showtagpreview(0);
++	}
+ 	if (ev->window != root)
+ 		return;
+ 	if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
+@@ -1573,6 +1614,7 @@ setup(void)
+ 	/* init bars */
+ 	updatebars();
+ 	updatestatus();
++	updatepreview();
+ 	/* supporting window for NetWMCheck */
+ 	wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
+ 	XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
+@@ -1628,6 +1670,23 @@ showhide(Client *c)
+ 	}
+ }
+ 
++void
++showtagpreview(int tag)
++{
++	if (!selmon->previewshow) {
++		XUnmapWindow(dpy, selmon->tagwin);
++		return;
++	}
++
++        if (selmon->tagmap[tag]) {
++		XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[tag]);
++		XCopyArea(dpy, selmon->tagmap[tag], selmon->tagwin, drw->gc, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview, 0, 0);
++		XSync(dpy, False);
++		XMapWindow(dpy, selmon->tagwin);
++	} else
++		XUnmapWindow(dpy, selmon->tagwin);
++}
++
+ void
+ sigchld(int unused)
+ {
+@@ -1652,6 +1711,38 @@ spawn(const Arg *arg)
+ 	}
+ }
+ 
++void
++switchtag(void)
++{
++  	int i;
++	unsigned int occ = 0;
++	Client *c;
++	Imlib_Image image;
++
++	for (c = selmon->clients; c; c = c->next)
++		occ |= c->tags;
++	for (i = 0; i < LENGTH(tags); i++) {
++		if (selmon->tagset[selmon->seltags] & 1 << i) {
++                  	if (selmon->tagmap[i] != 0) {
++ 				XFreePixmap(dpy, selmon->tagmap[i]);
++ 				selmon->tagmap[i] = 0;
++ 			}
++			if (occ & 1 << i) {
++				image = imlib_create_image(sw, sh);
++				imlib_context_set_image(image);
++				imlib_context_set_display(dpy);
++				imlib_context_set_visual(DefaultVisual(dpy, screen));
++				imlib_context_set_drawable(RootWindow(dpy, screen));
++				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
+ tag(const Arg *arg)
+ {
+@@ -1740,6 +1831,7 @@ toggleview(const Arg *arg)
+ 	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ 
+ 	if (newtagset) {
++		switchtag();
+ 		selmon->tagset[selmon->seltags] = newtagset;
+ 		focus(NULL);
+ 		arrange(selmon);
+@@ -1805,7 +1897,7 @@ 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) {
+@@ -2001,6 +2093,26 @@ updatetitle(Client *c)
+ 		strcpy(c->name, broken);
+ }
+ 
++void
++updatepreview(void)
++{
++	Monitor *m;
++
++	XSetWindowAttributes wa = {
++		.override_redirect = True,
++		.background_pixmap = ParentRelative,
++		.event_mask = ButtonPressMask|ExposureMask
++	};
++	for (m = mons; m; m = m->next) {
++		m->tagwin = XCreateWindow(dpy, root, m->wx, m->by + bh, m->mw / 4, m->mh / 4, 0,
++				DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
++				CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
++		XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
++		XMapRaised(dpy, m->tagwin);
++		XUnmapWindow(dpy, m->tagwin);
++	}
++}
++
+ void
+ updatewindowtype(Client *c)
+ {
+@@ -2037,6 +2149,7 @@ view(const Arg *arg)
+ {
+ 	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+ 		return;
++	switchtag();
+ 	selmon->seltags ^= 1; /* toggle sel tagset */
+ 	if (arg->ui & TAGMASK)
+ 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+-- 
+2.32.0
+
diff --git a/dwm.suckless.org/patches/tag-previews/index.md b/dwm.suckless.org/patches/tag-previews/index.md
@@ -0,0 +1,22 @@
+tag previews
+================
+
+Description
+-----------
+Allows you to see the contents of an already viewed tag. So a more accurate
+description would be to re-view a tag. This patch is extracted from
+https://github.com/siduck76/chadwm. Keep in mind that this uses Imlib2, which
+on the diff is already put on.
+
+
+
+
+
+Download
+--------
+* [dwm-tag-preview-6.2.diff](dwm-tag-preview-6.2.diff)
+* [Github mirror](https://github.com/explosion-mental/Dwm/blob/main/Patches/dwm-tag-preview-6.2.diff)
+
+Authors
+-------
+* explosion-mental - <explosion0mental@gmail.com>
diff --git a/dwm.suckless.org/patches/tag-previews/screenshot.png b/dwm.suckless.org/patches/tag-previews/screenshot.png
Binary files differ.