feat(patches): add tag-preview patche
This commit is contained in:
parent
aca76592a2
commit
f48d1b5e86
@ -3,6 +3,8 @@
|
|||||||
/* appearance */
|
/* appearance */
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
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 unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
||||||
static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
|
static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
|
||||||
static const unsigned int systrayspacing = 2; /* systray spacing */
|
static const unsigned int systrayspacing = 2; /* systray spacing */
|
||||||
@ -61,7 +63,7 @@ static const Layout layouts[] = {
|
|||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ShiftMask, KEY, tag, {.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 */
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
@ -21,9 +21,12 @@ FREETYPEINC = /usr/include/freetype2
|
|||||||
#FREETYPEINC = ${X11INC}/freetype2
|
#FREETYPEINC = ${X11INC}/freetype2
|
||||||
#MANPREFIX = ${PREFIX}/man
|
#MANPREFIX = ${PREFIX}/man
|
||||||
|
|
||||||
|
# Imlib2 (tag previews)
|
||||||
|
IMLIB2LIBS = -lImlib2
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${IMLIB2LIBS}
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||||
|
141
dwm.c
141
dwm.c
@ -41,6 +41,7 @@
|
|||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#endif /* XINERAMA */
|
#endif /* XINERAMA */
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <Imlib2.h>
|
||||||
|
|
||||||
#include "drw.h"
|
#include "drw.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -130,6 +131,9 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct Pertag Pertag;
|
typedef struct Pertag Pertag;
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
|
int previewshow;
|
||||||
|
Window tagwin;
|
||||||
|
Pixmap *tagmap;
|
||||||
char ltsymbol[16];
|
char ltsymbol[16];
|
||||||
float mfact;
|
float mfact;
|
||||||
int nmaster;
|
int nmaster;
|
||||||
@ -287,6 +291,10 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
static void zoom(const Arg *arg);
|
static void zoom(const Arg *arg);
|
||||||
|
|
||||||
|
static void showtagpreview(unsigned int i);
|
||||||
|
static void takepreview(void);
|
||||||
|
static void previewtag(const Arg *arg);
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
static Systray *systray = NULL;
|
static Systray *systray = NULL;
|
||||||
static const char autostartblocksh[] = "autostart_blocking.sh";
|
static const char autostartblocksh[] = "autostart_blocking.sh";
|
||||||
@ -515,6 +523,11 @@ buttonpress(XEvent *e)
|
|||||||
if (i < LENGTH(tags)) {
|
if (i < LENGTH(tags)) {
|
||||||
click = ClkTagBar;
|
click = ClkTagBar;
|
||||||
arg.ui = 1 << i;
|
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 + TEXTW(selmon->ltsymbol))
|
} else if (ev->x < x + TEXTW(selmon->ltsymbol))
|
||||||
click = ClkLtSymbol;
|
click = ClkLtSymbol;
|
||||||
/* 2px right padding */
|
/* 2px right padding */
|
||||||
@ -598,6 +611,7 @@ void
|
|||||||
cleanupmon(Monitor *mon)
|
cleanupmon(Monitor *mon)
|
||||||
{
|
{
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if (mon == mons)
|
if (mon == mons)
|
||||||
mons = mons->next;
|
mons = mons->next;
|
||||||
@ -605,8 +619,14 @@ cleanupmon(Monitor *mon)
|
|||||||
for (m = mons; m && m->next != mon; m = m->next);
|
for (m = mons; m && m->next != mon; m = m->next);
|
||||||
m->next = mon->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);
|
XUnmapWindow(dpy, mon->barwin);
|
||||||
XDestroyWindow(dpy, mon->barwin);
|
XDestroyWindow(dpy, mon->barwin);
|
||||||
|
XUnmapWindow(dpy, mon->tagwin);
|
||||||
|
XDestroyWindow(dpy, mon->tagwin);
|
||||||
free(mon);
|
free(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,6 +811,7 @@ createmon(void)
|
|||||||
m->topbar = topbar;
|
m->topbar = topbar;
|
||||||
m->lt[0] = &layouts[0];
|
m->lt[0] = &layouts[0];
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
m->tagmap = ecalloc(LENGTH(tags), sizeof(Pixmap));
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
m->pertag = ecalloc(1, sizeof(Pertag));
|
m->pertag = ecalloc(1, sizeof(Pertag));
|
||||||
m->pertag->curtag = m->pertag->prevtag = 1;
|
m->pertag->curtag = m->pertag->prevtag = 1;
|
||||||
@ -1449,11 +1470,41 @@ monocle(Monitor *m)
|
|||||||
void
|
void
|
||||||
motionnotify(XEvent *e)
|
motionnotify(XEvent *e)
|
||||||
{
|
{
|
||||||
int x, i;
|
// int x, i;
|
||||||
static Monitor *mon = NULL;
|
static Monitor *mon = NULL;
|
||||||
Client *c;
|
Client *c;
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
XMotionEvent *ev = &e->xmotion;
|
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 != selmon->barwin) {
|
if (ev->window != selmon->barwin) {
|
||||||
if (selmon->hov) {
|
if (selmon->hov) {
|
||||||
@ -2108,6 +2159,82 @@ setmfact(const Arg *arg)
|
|||||||
arrange(selmon);
|
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
|
void
|
||||||
setup(void)
|
setup(void)
|
||||||
{
|
{
|
||||||
@ -2419,6 +2546,7 @@ toggleview(const Arg *arg)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (newtagset) {
|
if (newtagset) {
|
||||||
|
takepreview();
|
||||||
selmon->tagset[selmon->seltags] = newtagset;
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
|
|
||||||
if (newtagset == ~0) {
|
if (newtagset == ~0) {
|
||||||
@ -2532,10 +2660,18 @@ updatebars(void)
|
|||||||
XSetWindowAttributes wa = {
|
XSetWindowAttributes wa = {
|
||||||
.override_redirect = True,
|
.override_redirect = True,
|
||||||
.background_pixmap = ParentRelative,
|
.background_pixmap = ParentRelative,
|
||||||
.event_mask = ButtonPressMask|ExposureMask
|
.event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
|
||||||
};
|
};
|
||||||
|
|
||||||
XClassHint ch = {"dwm", "dwm"};
|
XClassHint ch = {"dwm", "dwm"};
|
||||||
for (m = mons; m; m = m->next) {
|
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)
|
if (m->barwin)
|
||||||
continue;
|
continue;
|
||||||
w = m->ww;
|
w = m->ww;
|
||||||
@ -2893,6 +3029,7 @@ view(const Arg *arg)
|
|||||||
|
|
||||||
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||||
return;
|
return;
|
||||||
|
takepreview();
|
||||||
selmon->seltags ^= 1; /* toggle sel tagset */
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
||||||
if (arg->ui & TAGMASK) {
|
if (arg->ui & TAGMASK) {
|
||||||
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||||
|
315
patches/dwm-tag-preview-6.3.diff
Normal file
315
patches/dwm-tag-preview-6.3.diff
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user