diff --git a/README.md b/README.md index abecc35..5a86f77 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 ### Changelog: + +2022-07-05 - Added the tagpreview patch + 2022-07-04 - Added the shift-tools patch(es) with individual toggles 2022-06-20 - Added the renamed scratchpads patch @@ -736,6 +739,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 - [tagothermonitor](https://dwm.suckless.org/patches/tagothermonitor/) - adds functions and keybindings to tag a window to a desired tag on an adjacent monitor + - [tagpreview](https://dwm.suckless.org/patches/tag-previews/) + - shows a preview of a tag when hovering the tag icon using the mouse + - [tagswapmon](https://github.com/bakkeby/patches/wiki/tagswapmon/) - swap all visible windows on one monitor with those of an adjacent monitor diff --git a/config.def.h b/config.def.h index da67f20..c193308 100644 --- a/config.def.h +++ b/config.def.h @@ -11,6 +11,9 @@ static const unsigned int snap = 32; /* snap pixel */ #if SWALLOW_PATCH static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ #endif // SWALLOW_PATCH +#if BAR_TAGPREVIEW_PATCH +static const int scalepreview = 4; /* Tag preview scaling */ +#endif // BAR_TAGPREVIEW_PATCH #if NO_MOD_BUTTONS_PATCH static int nomodbuttons = 1; /* allow client mouse button bindings that have no modifier */ #endif // NO_MOD_BUTTONS_PATCH @@ -504,80 +507,80 @@ static const Inset default_inset = { * name - does nothing, intended for visual clue and for logging / debugging */ static const BarRule barrules[] = { - /* monitor bar alignment widthfunc drawfunc clickfunc name */ + /* monitor bar alignment widthfunc drawfunc clickfunc hoverfunc name */ #if BAR_STATUSBUTTON_PATCH - { -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, "statusbutton" }, + { -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, NULL, "statusbutton" }, #endif // BAR_STATUSBUTTON_PATCH #if BAR_POWERLINE_TAGS_PATCH - { 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, "powerline_tags" }, + { 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, NULL, "powerline_tags" }, #endif // BAR_POWERLINE_TAGS_PATCH #if BAR_TAGS_PATCH - { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" }, + { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, hover_tags, "tags" }, #endif // BAR_TAGS_PATCH #if BAR_TAGLABELS_PATCH - { -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, "taglabels" }, + { -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, NULL, "taglabels" }, #endif // BAR_TAGLABELS_PATCH #if BAR_TAGGRID_PATCH - { -1, 0, BAR_ALIGN_LEFT, width_taggrid, draw_taggrid, click_taggrid, "taggrid" }, + { -1, 0, BAR_ALIGN_LEFT, width_taggrid, draw_taggrid, click_taggrid, NULL, "taggrid" }, #endif // BAR_TAGGRID_PATCH #if BAR_SYSTRAY_PATCH - { 0, 0, BAR_ALIGN_RIGHT, width_systray, draw_systray, click_systray, "systray" }, + { 0, 0, BAR_ALIGN_RIGHT, width_systray, draw_systray, click_systray, NULL, "systray" }, #endif // BAR_SYSTRAY_PATCH #if BAR_LTSYMBOL_PATCH - { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" }, + { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, NULL, "layout" }, #endif // BAR_LTSYMBOL_PATCH #if BAR_STATUSCOLORS_PATCH && BAR_STATUSCMD_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_statuscolors, draw_statuscolors, click_statuscmd, "statuscolors" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_statuscolors, draw_statuscolors, click_statuscmd, NULL, "statuscolors" }, #elif BAR_STATUSCOLORS_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_statuscolors, draw_statuscolors, click_statuscolors, "statuscolors" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_statuscolors, draw_statuscolors, click_statuscolors, NULL, "statuscolors" }, #elif BAR_STATUS2D_PATCH && BAR_STATUSCMD_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_statuscmd, "status2d" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_statuscmd, NULL, "status2d" }, #elif BAR_STATUS2D_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_status2d, "status2d" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_status2d, NULL, "status2d" }, #elif BAR_POWERLINE_STATUS_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_pwrl_status, draw_pwrl_status, click_pwrl_status, "powerline_status" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_pwrl_status, draw_pwrl_status, click_pwrl_status, NULL, "powerline_status" }, #elif BAR_STATUS_PATCH && BAR_STATUSCMD_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_statuscmd, "status" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_statuscmd, NULL, "status" }, #elif BAR_STATUS_PATCH - { statusmon, 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" }, + { statusmon, 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, NULL, "status" }, #endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH #if XKB_PATCH - { 0, 0, BAR_ALIGN_RIGHT, width_xkb, draw_xkb, click_xkb, "xkb" }, + { 0, 0, BAR_ALIGN_RIGHT, width_xkb, draw_xkb, click_xkb, NULL, "xkb" }, #endif // XKB_PATCH #if BAR_FLEXWINTITLE_PATCH - { -1, 0, BAR_ALIGN_NONE, width_flexwintitle, draw_flexwintitle, click_flexwintitle, "flexwintitle" }, + { -1, 0, BAR_ALIGN_NONE, width_flexwintitle, draw_flexwintitle, click_flexwintitle, NULL, "flexwintitle" }, #elif BAR_TABGROUPS_PATCH - { -1, 0, BAR_ALIGN_NONE, width_bartabgroups, draw_bartabgroups, click_bartabgroups, "bartabgroups" }, + { -1, 0, BAR_ALIGN_NONE, width_bartabgroups, draw_bartabgroups, click_bartabgroups, NULL, "bartabgroups" }, #elif BAR_AWESOMEBAR_PATCH - { -1, 0, BAR_ALIGN_NONE, width_awesomebar, draw_awesomebar, click_awesomebar, "awesomebar" }, + { -1, 0, BAR_ALIGN_NONE, width_awesomebar, draw_awesomebar, click_awesomebar, NULL, "awesomebar" }, #elif BAR_FANCYBAR_PATCH - { -1, 0, BAR_ALIGN_NONE, width_fancybar, draw_fancybar, click_fancybar, "fancybar" }, + { -1, 0, BAR_ALIGN_NONE, width_fancybar, draw_fancybar, click_fancybar, NULL, "fancybar" }, #elif BAR_WINTITLE_PATCH - { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" }, + { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, NULL, "wintitle" }, #endif // BAR_TABGROUPS_PATCH | BAR_AWESOMEBAR_PATCH | BAR_FANCYBAR_PATCH | BAR_WINTITLE_PATCH #if BAR_EXTRASTATUS_PATCH #if BAR_STATUSCOLORS_PATCH && BAR_STATUSCMD_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_statuscolors_es, draw_statuscolors_es, click_statuscmd_es, "statuscolors_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_statuscolors_es, draw_statuscolors_es, click_statuscmd_es, NULL, "statuscolors_es" }, #elif BAR_STATUSCOLORS_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_statuscolors_es, draw_statuscolors_es, click_statuscolors, "statuscolors_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_statuscolors_es, draw_statuscolors_es, click_statuscolors, NULL, "statuscolors_es" }, #elif BAR_STATUS2D_PATCH && BAR_STATUSCMD_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_status2d_es, draw_status2d_es, click_statuscmd_es, "status2d_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_status2d_es, draw_status2d_es, click_statuscmd_es, NULL, "status2d_es" }, #elif BAR_STATUS2D_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_status2d_es, draw_status2d_es, click_status2d, "status2d_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_status2d_es, draw_status2d_es, click_status2d, NULL, "status2d_es" }, #elif BAR_POWERLINE_STATUS_PATCH - { statusmon, 1, BAR_ALIGN_RIGHT, width_pwrl_status_es, draw_pwrl_status_es, click_pwrl_status, "powerline_status" }, + { statusmon, 1, BAR_ALIGN_RIGHT, width_pwrl_status_es, draw_pwrl_status_es, click_pwrl_status, NULL, "powerline_status" }, #elif BAR_STATUSCMD_PATCH && BAR_STATUS_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_status_es, draw_status_es, click_statuscmd_es, "status_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_status_es, draw_status_es, click_statuscmd_es, NULL, "status_es" }, #elif BAR_STATUS_PATCH - { statusmon, 1, BAR_ALIGN_CENTER, width_status_es, draw_status_es, click_status, "status_es" }, + { statusmon, 1, BAR_ALIGN_CENTER, width_status_es, draw_status_es, click_status, NULL, "status_es" }, #endif // BAR_STATUS2D_PATCH | BAR_STATUSCMD_PATCH #endif // BAR_EXTRASTATUS_PATCH #if BAR_FLEXWINTITLE_PATCH #if BAR_WINTITLE_HIDDEN_PATCH - { -1, 1, BAR_ALIGN_RIGHT_RIGHT, width_wintitle_hidden, draw_wintitle_hidden, click_wintitle_hidden, "wintitle_hidden" }, + { -1, 1, BAR_ALIGN_RIGHT_RIGHT, width_wintitle_hidden, draw_wintitle_hidden, click_wintitle_hidden, NULL, "wintitle_hidden" }, #endif #if BAR_WINTITLE_FLOATING_PATCH - { -1, 1, BAR_ALIGN_LEFT, width_wintitle_floating, draw_wintitle_floating, click_wintitle_floating, "wintitle_floating" }, + { -1, 1, BAR_ALIGN_LEFT, width_wintitle_floating, draw_wintitle_floating, click_wintitle_floating, NULL, "wintitle_floating" }, #endif // BAR_WINTITLE_FLOATING_PATCH #endif // BAR_FLEXWINTITLE_PATCH }; diff --git a/config.mk b/config.mk index f1cecb2..8f662cd 100644 --- a/config.mk +++ b/config.mk @@ -48,7 +48,7 @@ FREETYPEINC = /usr/include/freetype2 # Uncomment this for the swallow patch / SWALLOW_PATCH #XCBLIBS = -lX11-xcb -lxcb -lxcb-res -# This is needed for the winicon patch / BAR_WINICON_PATCH +# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH #IMLIB2LIBS = -lImlib2 # includes and libs diff --git a/dwm.c b/dwm.c index 8d8ca19..1c77a15 100644 --- a/dwm.c +++ b/dwm.c @@ -314,6 +314,7 @@ typedef struct { int (*widthfunc)(Bar *bar, BarArg *a); int (*drawfunc)(Bar *bar, BarArg *a); int (*clickfunc)(Bar *bar, Arg *arg, BarArg *a); + int (*hoverfunc)(Bar *bar, BarArg *a, XMotionEvent *ev); char *name; // for debugging int x, w; // position, width for internal use } BarRule; @@ -515,6 +516,11 @@ struct Monitor { Client *lastsel; const Layout *lastlt; #endif // IPC_PATCH + #if BAR_TAGPREVIEW_PATCH + Window tagwin; + int previewshow; + Pixmap tagmap[NUMTAGS]; + #endif // BAR_TAGPREVIEW_PATCH }; typedef struct { @@ -1308,6 +1314,13 @@ cleanupmon(Monitor *mon) #if PERTAG_PATCH free(mon->pertag); #endif // PERTAG_PATCH + #if BAR_TAGPREVIEW_PATCH + for (size_t i = 0; i < NUMTAGS; i++) + if (mon->tagmap[i]) + XFreePixmap(dpy, mon->tagmap[i]); + XUnmapWindow(dpy, mon->tagwin); + XDestroyWindow(dpy, mon->tagwin); + #endif // BAR_TAGPREVIEW_PATCH free(mon); } @@ -2621,11 +2634,22 @@ motionnotify(XEvent *e) { static Monitor *mon = NULL; Monitor *m; + Bar *bar; #if LOSEFULLSCREEN_PATCH Client *sel; #endif // LOSEFULLSCREEN_PATCH XMotionEvent *ev = &e->xmotion; + if ((bar = wintobar(ev->window))) { + barhover(e, bar); + return; + } + + #if BAR_TAGPREVIEW_PATCH + if (selmon->previewshow != 0) + hidetagpreview(selmon); + #endif // BAR_TAGPREVIEW_PATCH + if (ev->window != root) return; if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { @@ -3732,6 +3756,9 @@ setup(void) updatebars(); updatestatus(); + #if BAR_TAGPREVIEW_PATCH + updatepreview(); + #endif // BAR_TAGPREVIEW_PATCH /* supporting window for NetWMCheck */ wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); @@ -4198,6 +4225,9 @@ toggleview(const Arg *arg) #if !EMPTYVIEW_PATCH if (newtagset) { #endif // EMPTYVIEW_PATCH + #if BAR_TAGPREVIEW_PATCH + tagpreviewswitchtag(); + #endif // BAR_TAGPREVIEW_PATCH selmon->tagset[selmon->seltags] = newtagset; #if PERTAG_PATCH @@ -4421,7 +4451,11 @@ updatebars(void) #else .background_pixmap = ParentRelative, #endif // BAR_ALPHA_PATCH + #if BAR_TAGPREVIEW_PATCH + .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask + #else .event_mask = ButtonPressMask|ExposureMask + #endif // BAR_TAGPREVIEW_PATCH }; XClassHint ch = {"dwm", "dwm"}; for (m = mons; m; m = m->next) { @@ -4828,6 +4862,9 @@ view(const Arg *arg) #endif // TOGGLETAG_PATCH return; } + #if BAR_TAGPREVIEW_PATCH + tagpreviewswitchtag(); + #endif // BAR_TAGPREVIEW_PATCH selmon->seltags ^= 1; /* toggle sel tagset */ #if PERTAG_PATCH pertagview(arg); diff --git a/patch/bar.c b/patch/bar.c new file mode 100644 index 0000000..65e1a69 --- /dev/null +++ b/patch/bar.c @@ -0,0 +1,39 @@ +void +barhover(XEvent *e, Bar *bar) +{ + const BarRule *br; + Monitor *m = bar->mon; + XMotionEvent *ev = &e->xmotion; + BarArg barg = { 0, 0, 0, 0 }; + int r; + + for (r = 0; r < LENGTH(barrules); r++) { + br = &barrules[r]; + if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->hoverfunc == NULL) + continue; + if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num) + continue; + if (bar->x[r] > ev->x || ev->x > bar->x[r] + bar->w[r]) + continue; + + barg.x = ev->x - bar->x[r]; + barg.y = ev->y - bar->borderpx; + barg.w = bar->w[r]; + barg.h = bar->bh - 2 * bar->borderpx; + + br->hoverfunc(bar, &barg, ev); + break; + } +} + +Bar * +wintobar(Window win) +{ + Monitor *m; + Bar *bar; + for (m = mons; m; m = m->next) + for (bar = m->bar; bar; bar = bar->next) + if (bar->win == win) + return bar; + return NULL; +} diff --git a/patch/bar.h b/patch/bar.h new file mode 100644 index 0000000..3e006dc --- /dev/null +++ b/patch/bar.h @@ -0,0 +1,2 @@ +static void barhover(XEvent *e, Bar *bar); +static Bar *wintobar(Window win); diff --git a/patch/bar_tagpreview.c b/patch/bar_tagpreview.c new file mode 100644 index 0000000..c92d05f --- /dev/null +++ b/patch/bar_tagpreview.c @@ -0,0 +1,95 @@ +#include + +void +showtagpreview(int tag, int x, int y) +{ + 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); + XMoveWindow(dpy, selmon->tagwin, x, y); + XSync(dpy, False); + XMapWindow(dpy, selmon->tagwin); + } else + XUnmapWindow(dpy, selmon->tagwin); +} + +void +hidetagpreview(Monitor *m) +{ + m->previewshow = 0; + XUnmapWindow(dpy, m->tagwin); +} + +void +tagpreviewswitchtag(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 < NUMTAGS; 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); + #if BAR_ALPHA_PATCH + imlib_image_set_has_alpha(1); + imlib_context_set_blend(0); + imlib_context_set_visual(visual); + #else + imlib_context_set_visual(DefaultVisual(dpy, screen)); + #endif // BAR_ALPHA_PATCH + imlib_context_set_drawable(root); + imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1); + #if BAR_ALPHA_PATCH + selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, depth); + #else + selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, DefaultDepth(dpy, screen)); + #endif // BAR_ALPHA_PATCH + 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 +updatepreview(void) +{ + Monitor *m; + + XSetWindowAttributes wa = { + .override_redirect = True, + #if BAR_ALPHA_PATCH + .background_pixel = 0, + .border_pixel = 0, + .colormap = cmap, + #else + .background_pixmap = ParentRelative, + #endif // BAR_ALPHA_PATCH + .event_mask = ButtonPressMask|ExposureMask + }; + for (m = mons; m; m = m->next) { + m->tagwin = XCreateWindow(dpy, root, m->wx, m->bar->by + bh, m->mw / 4, m->mh / 4, 0, + #if BAR_ALPHA_PATCH + depth, CopyFromParent, visual, + CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa + #else + DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa + #endif // BAR_ALPHA_PATCH + ); + XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->tagwin); + XUnmapWindow(dpy, m->tagwin); + } +} diff --git a/patch/bar_tagpreview.h b/patch/bar_tagpreview.h new file mode 100644 index 0000000..8129187 --- /dev/null +++ b/patch/bar_tagpreview.h @@ -0,0 +1,4 @@ +static void showtagpreview(int tag, int x, int y); +static void hidetagpreview(Monitor *m); +static void tagpreviewswitchtag(void); +static void updatepreview(void); diff --git a/patch/bar_tags.c b/patch/bar_tags.c index 8b9092d..6a420d0 100644 --- a/patch/bar_tags.c +++ b/patch/bar_tags.c @@ -91,3 +91,56 @@ click_tags(Bar *bar, Arg *arg, BarArg *a) return ClkTagBar; } +int +hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev) +{ + #if BAR_TAGPREVIEW_PATCH + int i = 0, x = lrpad / 2; + int px, py; + Monitor *m = bar->mon; + #if VANITYGAPS_PATCH + int ov = gappov; + int oh = gappoh; + #else + int ov = 0; + int oh = 0; + #endif // VANITYGAPS_PATCH + + #if BAR_HIDEVACANTTAGS_PATCH + Client *c; + unsigned int occ = 0; + for (c = bar->mon->clients; c; c = c->next) + occ |= c->tags == 255 ? 0 : c->tags; + #endif // BAR_HIDEVACANTTAGS_PATCH + + do { + #if BAR_HIDEVACANTTAGS_PATCH + if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) + continue; + #endif // BAR_HIDEVACANTTAGS_PATCH + x += TEXTW(tagicon(bar->mon, i)); + } while (a->x >= x && ++i < NUMTAGS); + + if (i < NUMTAGS) { + if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) { + if (bar->by > m->my + m->mh / 2) // bottom bar + py = bar->by - m->mh / scalepreview - oh; + else // top bar + py = bar->by + bar->bh + oh; + px = bar->bx + ev->x - m->mw / scalepreview / 2; + if (px + m->mw / scalepreview > m->mx + m->mw) + px = m->wx + m->ww - m->mw / scalepreview - ov; + else if (px < bar->bx) + px = m->wx + ov; + selmon->previewshow = i + 1; + showtagpreview(i, px, py); + } else if (selmon->tagset[selmon->seltags] & 1 << i) { + hidetagpreview(selmon); + } + } else if (selmon->previewshow != 0) { + hidetagpreview(selmon); + } + #endif // BAR_TAGPREVIEW_PATCH + + return 1; +} diff --git a/patch/bar_tags.h b/patch/bar_tags.h index 9261261..70040d2 100644 --- a/patch/bar_tags.h +++ b/patch/bar_tags.h @@ -1,4 +1,4 @@ static int width_tags(Bar *bar, BarArg *a); static int draw_tags(Bar *bar, BarArg *a); static int click_tags(Bar *bar, Arg *arg, BarArg *a); - +static int hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev); diff --git a/patch/include.c b/patch/include.c index 6f9768a..33232cf 100644 --- a/patch/include.c +++ b/patch/include.c @@ -1,6 +1,7 @@ /* Bar functionality */ #include "bar_indicators.c" #include "bar_tagicons.c" +#include "bar.c" #if BAR_ALPHA_PATCH #include "bar_alpha.c" @@ -50,6 +51,9 @@ #if BAR_TABGROUPS_PATCH #include "bar_tabgroups.c" #endif +#if BAR_TAGPREVIEW_PATCH +#include "bar_tagpreview.c" +#endif #if BAR_TAGS_PATCH #include "bar_tags.c" #endif diff --git a/patch/include.h b/patch/include.h index 2ad61df..2a78292 100644 --- a/patch/include.h +++ b/patch/include.h @@ -1,6 +1,7 @@ /* Bar functionality */ #include "bar_indicators.h" #include "bar_tagicons.h" +#include "bar.h" #if BAR_ALPHA_PATCH #include "bar_alpha.h" @@ -59,6 +60,9 @@ #if BAR_TAGLABELS_PATCH #include "bar_taglabels.h" #endif +#if BAR_TAGPREVIEW_PATCH +#include "bar_tagpreview.h" +#endif #if BAR_TAGGRID_PATCH #include "bar_taggrid.h" #endif diff --git a/patches.def.h b/patches.def.h index 3f5a27f..eec95f9 100644 --- a/patches.def.h +++ b/patches.def.h @@ -115,6 +115,23 @@ */ #define BAR_TAGGRID_PATCH 0 +/* Hover tag icons to see a preview of the windows on that tag. + * + * The patch depends on Imlib2 for icon scaling. + * You need to uncomment the corresponding line in config.mk to use the -lImlib2 library + * + * Arch Linux: + * sudo pacman -S imlib2 + * Debian: + * sudo apt install libimlib2-dev + * + * As with the winicon patch you may want to consider adding the compiler flags of -O3 and + * -march=native to enable auto loop vectorize for better performance. + * + * https://dwm.suckless.org/patches/tag-previews/ + */ +#define BAR_TAGPREVIEW_PATCH 0 + /* Show status in bar */ #define BAR_STATUS_PATCH 1