[dwm][patches][preview-all-win] - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit eab1efe2663368fe804d099e439b0eb648ed3e44
 (DIR) parent 415383b09670c5081f7bfe291144c80c38227722
 (HTM) Author: elbachir-one <bachiralfa@gmail.com>
       Date:   Mon,  7 Apr 2025 05:05:02 +0100
       
       [dwm][patches][preview-all-win]
       
       * Updated index.md
       * Updating the patch to fix some issues
       
       Diffstat:
         A dwm.suckless.org/patches/preview-a… |     403 +++++++++++++++++++++++++++++++
         M dwm.suckless.org/patches/preview-a… |     429 ++++++++++++++++---------------
         M dwm.suckless.org/patches/preview-a… |      32 ++++++++++++++++++++-----------
       
       3 files changed, 643 insertions(+), 221 deletions(-)
       ---
 (DIR) diff --git a/dwm.suckless.org/patches/preview-all-win/dwm-preview-all-windows-20250407-e381933.diff b/dwm.suckless.org/patches/preview-all-win/dwm-preview-all-windows-20250407-e381933.diff
       @@ -0,0 +1,403 @@
       +From e381933255718c6ed30e1b930d8fd76d62ccda75 Mon Sep 17 00:00:00 2001
       +From: elbachir-one <bachiralfa@gmail.com>
       +Date: Mon, 7 Apr 2025 06:02:14 +0100
       +Subject: [PATCH] Added some keys to move/select around windows in the preview
       +
       +---
       + config.def.h |   4 +
       + config.mk    |   2 +-
       + dwm.c        | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++
       + 3 files changed, 312 insertions(+), 1 deletion(-)
       +
       +diff --git a/config.def.h b/config.def.h
       +index 4412cb1..37feaf7 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -1,5 +1,8 @@
       + /* See LICENSE file for copyright and license details. */
       + 
       ++//#define ACTUALFULLSCREEN /* Uncomment if the actualfullscreen patch is added */
       ++//#define AWESOMEBAR /* Uncommnet if the awesomebar patch is used */
       ++
       + /* appearance */
       + static const unsigned int borderpx  = 1;        /* border pixel of windows */
       + static const unsigned int snap      = 32;       /* snap pixel */
       +@@ -95,6 +98,7 @@ static const Key keys[] = {
       +         TAGKEYS(                        XK_8,                      7)
       +         TAGKEYS(                        XK_9,                      8)
       +         { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
       ++        { MODKEY,                       XK_r,      togglepreviewallwin,  {0} },
       + };
       + 
       + /* button definitions */
       +diff --git a/config.mk b/config.mk
       +index 8efca9a..8df2978 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 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
       + 
       + # flags
       + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
       +diff --git a/dwm.c b/dwm.c
       +index 1443802..6d38874 100644
       +--- a/dwm.c
       ++++ b/dwm.c
       +@@ -40,6 +40,7 @@
       + #include <X11/extensions/Xinerama.h>
       + #endif /* XINERAMA */
       + #include <X11/Xft/Xft.h>
       ++#include <X11/extensions/Xrender.h>
       + 
       + #include "drw.h"
       + #include "util.h"
       +@@ -83,6 +84,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;
       +@@ -96,6 +107,7 @@ struct Client {
       +         Client *snext;
       +         Monitor *mon;
       +         Window win;
       ++        Preview pre;
       + };
       + 
       + typedef struct {
       +@@ -232,8 +244,14 @@ 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 togglepreviewallwin();
       ++static void highlightwindow(int idx, Monitor *m);
       ++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";
       + static char stext[256];
       + static int screen;
       +@@ -266,6 +284,7 @@ static Display *dpy;
       + static Drw *drw;
       + static Monitor *mons, *selmon;
       + static Window root, wmcheckwin;
       ++static int previewallwin = 0;
       + 
       + /* configuration, allows nested code to access above variables */
       + #include "config.h"
       +@@ -2139,6 +2158,294 @@ zoom(const Arg *arg)
       +         pop(c);
       + }
       + 
       ++void
       ++togglepreviewallwin() {
       ++        if (previewallwin) {  /* If already active, disable preview */
       ++                previewallwin = 0;
       ++                for (Client *c = selmon->clients; c; c = c->next) {
       ++                        XUnmapWindow(dpy, c->pre.win);
       ++                        XMapWindow(dpy, c->win);
       ++                        if (c->pre.orig_image)
       ++                                XDestroyImage(c->pre.orig_image);
       ++                        if (c->pre.scaled_image)
       ++                                XDestroyImage(c->pre.scaled_image);
       ++                }
       ++                arrange(selmon);
       ++                focus(NULL);
       ++                return;  /* Exit function early to prevent running again */
       ++        }
       ++
       ++        previewallwin = 1;  /* Enable preview mode */
       ++        Monitor *m = selmon;
       ++        Client *c, *focus_c = NULL;
       ++        unsigned int n = 0;
       ++
       ++        for (c = m->clients; c; c = c->next, n++) {
       ++#ifdef ACTUALFULLSCREEN
       ++                if (c->isfullscreen)
       ++                        togglefullscr(&(Arg){0});
       ++#endif
       ++#ifdef AWESOMEBAR
       ++                if (HIDDEN(c))
       ++                        continue;
       ++#endif
       ++                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);
       ++                XUnmapWindow(dpy, c->win);
       ++
       ++                if (c->pre.win) {
       ++                        XSelectInput(dpy, c->pre.win, ButtonPress | EnterWindowMask | LeaveWindowMask);
       ++                        XMapWindow(dpy, c->pre.win);
       ++                        GC gc = XCreateGC(dpy, c->pre.win, 0, NULL);
       ++                        XPutImage(dpy, c->pre.win, gc, c->pre.scaled_image, 0, 0, 0, 0,
       ++                                        c->pre.scaled_image->width, c->pre.scaled_image->height);
       ++                }
       ++        }
       ++
       ++        int selected_idx = 0;
       ++
       ++        while (previewallwin) {
       ++                XNextEvent(dpy, &event);
       ++                if (event.type == ButtonPress) {
       ++                        if (event.xbutton.button == Button1) { /* Left-click to select a window */
       ++                                for (c = selmon->clients; c; c = c->next) {
       ++                                        if (event.xbutton.window == c->pre.win) {
       ++                                                previewallwin = 0;
       ++                                                selmon->tagset[selmon->seltags] = c->tags;
       ++                                                focus(c);
       ++                                                arrange(selmon); /* Ensure layout updates correctly */
       ++                                                break;
       ++                                        }
       ++                                }
       ++                        }
       ++                }
       ++                if (event.type == KeyPress) {
       ++                        if (event.xkey.keycode == XKeysymToKeycode(dpy, XK_j)) {
       ++                                if (selected_idx < n - 1) {
       ++                                        selected_idx++;
       ++                                }
       ++                                highlightwindow(selected_idx, m);
       ++                        }
       ++                        if (event.xkey.keycode == XKeysymToKeycode(dpy, XK_k)) {
       ++                                if (selected_idx > 0) {
       ++                                        selected_idx--;
       ++                                }
       ++                                highlightwindow(selected_idx, m);
       ++                        }
       ++                        if (event.xkey.keycode == XKeysymToKeycode(dpy, XK_Return)) {
       ++                                previewallwin = 0;
       ++                                Client *selected_client = NULL;
       ++                                int idx = 0;
       ++
       ++                                for (c = m->clients; c; c = c->next, idx++) {
       ++                                        if (idx == selected_idx) {
       ++                                                selected_client = c;
       ++                                                break;
       ++                                        }
       ++                                }
       ++                                if (selected_client) {
       ++                                        selmon->tagset[selmon->seltags] = selected_client->tags;
       ++                                        focus(selected_client);
       ++                                        arrange(selmon);
       ++                                }
       ++                        }
       ++                        if (event.xkey.keycode == XKeysymToKeycode(dpy, XK_r)) {
       ++                                previewallwin = 0;
       ++                                Client *selected_client = NULL;
       ++                                int idx = 0;
       ++
       ++                                for (c = m->clients; c; c = c->next, idx++) {
       ++                                        if (idx == selected_idx) {
       ++                                                selected_client = c;
       ++                                                break;
       ++                                        }
       ++                                }
       ++                                if (selected_client) {
       ++                                        selmon->tagset[selmon->seltags] = selected_client->tags;
       ++                                        focus(selected_client);
       ++                                        arrange(selmon);
       ++                                }
       ++                        }
       ++                }
       ++
       ++                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;
       ++                                }
       ++                        }
       ++                }
       ++        }
       ++        for (c = selmon->clients; c; c = c->next) { /* Restore all windows when exiting */
       ++                XUnmapWindow(dpy, c->pre.win);
       ++                XMapWindow(dpy, c->win);
       ++                if (c->pre.orig_image)
       ++                        XDestroyImage(c->pre.orig_image);
       ++                if (c->pre.scaled_image)
       ++                        XDestroyImage(c->pre.scaled_image);
       ++        }
       ++        arrange(m);
       ++        focus(focus_c);
       ++}
       ++
       ++void
       ++highlightwindow(int idx, Monitor *m) {
       ++        int i = 0;
       ++        Client *c;
       ++        for (c = m->clients; c; c = c->next, i++) {
       ++                if (i == idx) {
       ++                        XSetWindowBorder(dpy, c->pre.win, scheme[SchemeSel][ColBorder].pixel); /* Highlight selected window */
       ++                } else {
       ++                        XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel); /* Reset border for other windows */
       ++                }
       ++        }
       ++}
       ++
       ++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) {
       ++        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);
       ++        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[])
       + {
       +-- 
       +2.48.1
       +
 (DIR) diff --git a/dwm.suckless.org/patches/preview-all-win/dwm-preview-all-windows-6.5.diff b/dwm.suckless.org/patches/preview-all-win/dwm-preview-all-windows-6.5.diff
       @@ -1,8 +1,17 @@
        diff --git a/config.def.h b/config.def.h
       -index 9efa774..f462e32 100644
       +index 4412cb1..24f39a7 100644
        --- a/config.def.h
        +++ b/config.def.h
       -@@ -95,6 +95,7 @@ static const Key keys[] = {
       +@@ -1,5 +1,8 @@
       + /* See LICENSE file for copyright and license details. */
       + 
       ++//#define ACTUALFULLSCREEN /* Uncomment if the actualfullscreen patch is added */
       ++//#define AWESOMEBAR       /* Uncommnet if the awesomebar patch is used */
       ++
       + /* appearance */
       + static const unsigned int borderpx  = 1;        /* border pixel of windows */
       + static const unsigned int snap      = 32;       /* snap pixel */
       +@@ -95,6 +98,7 @@ static const Key keys[] = {
                 TAGKEYS(                        XK_8,                      7)
                 TAGKEYS(                        XK_9,                      8)
                 { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
       @@ -11,7 +20,7 @@ index 9efa774..f462e32 100644
         
         /* button definitions */
        diff --git a/config.mk b/config.mk
       -index 8efca9a..8d7c303 100644
       +index 8efca9a..8df2978 100644
        --- a/config.mk
        +++ b/config.mk
        @@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2
       @@ -19,49 +28,48 @@ index 8efca9a..8d7c303 100644
         # includes and libs
         INCS = -I${X11INC} -I${FREETYPEINC}
        -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
       -+LIBS = -L${X11LIB} -lX11 -lXrender -lXcomposite ${XINERAMALIBS} ${FREETYPELIBS}
       ++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
         
         # 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
       +index 1443802..ac561fa 100644
        --- a/dwm.c
        +++ b/dwm.c
       -@@ -40,6 +40,8 @@
       +@@ -40,6 +40,7 @@
         #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 {
       +@@ -83,6 +84,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;
       ++        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 {
       +@@ -96,6 +107,7 @@ struct Client {
                 Client *snext;
                 Monitor *mon;
                 Window win;
       -+  Preview pre;
       ++        Preview pre;
         };
         
         typedef struct {
       -@@ -233,6 +246,10 @@ static int xerror(Display *dpy, XErrorEvent *ee);
       +@@ -232,6 +244,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);
       @@ -72,216 +80,217 @@ index 67c6b2b..0ddd58e 100644
         
         /* variables */
         static const char broken[] = "broken";
       -@@ -2140,6 +2157,212 @@ zoom(const Arg *arg)
       +@@ -2139,6 +2155,210 @@ 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);
       ++        Monitor *m = selmon;
       ++        Client *c, *focus_c = NULL;
       ++        unsigned int n;
       ++        for (n = 0, c = m->clients; c; c = c->next, n++){
       ++#ifdef ACTUALFULLSCREEN
       ++                if (c->isfullscreen)
       ++                        togglefullscr(&(Arg){0});
       ++#endif
       ++#ifdef AWESOMEBAR
       ++                if (HIDDEN(c))
       ++                        continue;
       ++#endif
       ++                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);
       ++                XUnmapWindow(dpy, c->win);
       ++                if (c->pre.win){
       ++                        XSelectInput(dpy, c->pre.win, ButtonPress | EnterWindowMask | LeaveWindowMask );
       ++                        XMapWindow(dpy, c->pre.win);
       ++                        GC gc = XCreateGC(dpy, c->pre.win, 0, NULL);
       ++                        XPutImage(dpy, c->pre.win, 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);
       ++#ifdef AWESOMEBAR
       ++                                                if (HIDDEN(c)){
       ++                                                        showwin(c);
       ++                                                        continue;
       ++                                                }
       ++#endif
       ++                                        }
       ++                                        /* 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);
       ++                                         * */
       ++#ifdef AWESOMEBAR
       ++                                        if (HIDDEN(c)){
       ++                                                continue;
       ++                                        }
       ++#endif
       ++                                        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;
       ++        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;
       ++        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*
       ++getwindowximage(Client *c) {
       ++        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);
       ++        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;
       ++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[])
         {
       +-- 
       +2.48.1
       +
 (DIR) diff --git a/dwm.suckless.org/patches/preview-all-win/index.md b/dwm.suckless.org/patches/preview-all-win/index.md
       @@ -3,25 +3,35 @@ preview all windows
        
        Description
        -----------
       -Allows you to preview all window image thumbnails under the current display, and when clicked, it will jump to the corresponding application window
       +Allows you to preview all window image thumbnails under the current display,
       +and when clicked, it will jump to the corresponding application window.
        
       -![preview all windows](./preview-all-windows.png)
       -
       -I used two x11 extensions, xcomposite's off-screen storage feature and xrender to get the window image
       +[![preview all windows](preview-all-windows.png)](preview-all-windows.png)
        
       +I used two X11 extensions — XComposite's off-screen storage feature
       +and XRender — to capture the window image.
        
        > [!WARNING]
        
       -> If you're using patches for fullscreen and hidewin, please follow the comments in my patches and adjust the code to suit the effects of other patches
       -
       -> The project is still in the development stage, and there are still many problems, such as: without using a renderer like picom, the window image will not be available, but fortunately there is no crash
       +> The project is still in development.
        
       -> (I'm sorry because I've been using picom and this issue didn't come to me until I was making diff)
       +> If you're using patches like `actualfullscreen` or `awesomebar`, please uncomment
       +> the corresponding one in `config.def.h`.
       +```
       +#define ACTUALFULLSCREEN
       +#define AWESOMEBAR
       +```
        
        Download
        --------
       -* [dwm-preview-all-windows-6.5.diff](./dwm-preview-all-windows-6.5.diff)
       +* [dwm-preview-all-windows-6.5.diff](dwm-preview-all-windows-6.5.diff)
       +
       +This patch is like the above, with keys to select windows in the preview.
       +`Mod + j`/`Mod + k` to setect a window, `Mod + Return` to open it.
       +
       +* [dwm-preview-all-windows-20250407-e381933.diff](dwm-preview-all-windows-20250407-e381933.diff)
        
       -Author
       -------
       +Authors
       +-------
        * HJ-Zhang - <hjzhang216@gmail.com>
       +* El Bachir - <bachiralfa@gmail.com>