sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 58e164fcad444582bf29fbe744cdd03c9fd14adb
parent d9d3ea88d7f3d26926eaa943750b517c927a3a22
Author: explosion-mental <explosion0mental@gmail.com>
Date:   Thu,  1 Sep 2022 11:41:14 -0500

[patch][dwm] add tag preview for 6.3

Diffstat:
Adwm.suckless.org/patches/tag-previews/dwm-tag-preview-6.3.diff | 278+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 278 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/patches/tag-previews/dwm-tag-preview-6.3.diff b/dwm.suckless.org/patches/tag-previews/dwm-tag-preview-6.3.diff @@ -0,0 +1,278 @@ +From 0e8deaa65e5193815a883bd1b9f9f74b97d68186 Mon Sep 17 00:00:00 2001 +From: explosion-mental <explosion0mental@gmail.com> +Date: Thu, 1 Sep 2022 11:27:44 -0500 +Subject: [PATCH] [PATCH] tag previews: easier to patch patch + +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. +--- + config.def.h | 2 + + config.mk | 5 +- + dwm.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 132 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index a2ac963..abd6521 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" }; +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..3d8aac7 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,9 @@ 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); ++ + /* variables */ + static const char broken[] = "broken"; + static char stext[256]; +@@ -438,6 +445,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 +510,7 @@ void + cleanupmon(Monitor *mon) + { + Monitor *m; ++ size_t i; + + if (mon == mons) + mons = mons->next; +@@ -505,8 +518,13 @@ 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]); + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); ++ XUnmapWindow(dpy, mon->tagwin); ++ XDestroyWindow(dpy, mon->tagwin); + free(mon); + } + +@@ -641,6 +659,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 +1144,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 +1579,72 @@ 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 + setup(void) + { +@@ -1746,6 +1861,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 +1927,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 +2167,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 +