dwm-preview-all-windows-6.5.diff (9620B)
1 diff --git a/config.def.h b/config.def.h 2 index 4412cb1..24f39a7 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -1,5 +1,8 @@ 6 /* See LICENSE file for copyright and license details. */ 7 8 +//#define ACTUALFULLSCREEN /* Uncomment if the actualfullscreen patch is added */ 9 +//#define AWESOMEBAR /* Uncommnet if the awesomebar patch is used */ 10 + 11 /* appearance */ 12 static const unsigned int borderpx = 1; /* border pixel of windows */ 13 static const unsigned int snap = 32; /* snap pixel */ 14 @@ -95,6 +98,7 @@ static const Key keys[] = { 15 TAGKEYS( XK_8, 7) 16 TAGKEYS( XK_9, 8) 17 { MODKEY|ShiftMask, XK_q, quit, {0} }, 18 + { MODKEY, XK_r, previewallwin, {0} }, 19 }; 20 21 /* button definitions */ 22 diff --git a/config.mk b/config.mk 23 index 8efca9a..8df2978 100644 24 --- a/config.mk 25 +++ b/config.mk 26 @@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2 27 28 # includes and libs 29 INCS = -I${X11INC} -I${FREETYPEINC} 30 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} 31 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender 32 33 # flags 34 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 35 diff --git a/dwm.c b/dwm.c 36 index 1443802..ac561fa 100644 37 --- a/dwm.c 38 +++ b/dwm.c 39 @@ -40,6 +40,7 @@ 40 #include <X11/extensions/Xinerama.h> 41 #endif /* XINERAMA */ 42 #include <X11/Xft/Xft.h> 43 +#include <X11/extensions/Xrender.h> 44 45 #include "drw.h" 46 #include "util.h" 47 @@ -83,6 +84,16 @@ typedef struct { 48 49 typedef struct Monitor Monitor; 50 typedef struct Client Client; 51 + 52 +typedef struct Preview Preview; 53 +struct Preview { 54 + XImage *orig_image; 55 + XImage *scaled_image; 56 + Window win; 57 + unsigned int x, y; 58 + Preview *next; 59 +}; 60 + 61 struct Client { 62 char name[256]; 63 float mina, maxa; 64 @@ -96,6 +107,7 @@ struct Client { 65 Client *snext; 66 Monitor *mon; 67 Window win; 68 + Preview pre; 69 }; 70 71 typedef struct { 72 @@ -232,6 +244,10 @@ static int xerror(Display *dpy, XErrorEvent *ee); 73 static int xerrordummy(Display *dpy, XErrorEvent *ee); 74 static int xerrorstart(Display *dpy, XErrorEvent *ee); 75 static void zoom(const Arg *arg); 76 +static void previewallwin(); 77 +static void setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi); 78 +static XImage *getwindowximage(Client *c); 79 +static XImage *scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch); 80 81 /* variables */ 82 static const char broken[] = "broken"; 83 @@ -2139,6 +2155,210 @@ zoom(const Arg *arg) 84 pop(c); 85 } 86 87 +void 88 +previewallwin(){ 89 + Monitor *m = selmon; 90 + Client *c, *focus_c = NULL; 91 + unsigned int n; 92 + for (n = 0, c = m->clients; c; c = c->next, n++){ 93 +#ifdef ACTUALFULLSCREEN 94 + if (c->isfullscreen) 95 + togglefullscr(&(Arg){0}); 96 +#endif 97 +#ifdef AWESOMEBAR 98 + if (HIDDEN(c)) 99 + continue; 100 +#endif 101 + c->pre.orig_image = getwindowximage(c); 102 + } 103 + if (n == 0) 104 + return; 105 + setpreviewwindowsizepositions(n, m, 60, 15); 106 + XEvent event; 107 + for(c = m->clients; c; c = c->next){ 108 + if (!c->pre.win) 109 + 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)); 110 + else 111 + XMoveResizeWindow(dpy, c->pre.win, c->pre.x, c->pre.y, c->pre.scaled_image->width, c->pre.scaled_image->height); 112 + XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel); 113 + XUnmapWindow(dpy, c->win); 114 + if (c->pre.win){ 115 + XSelectInput(dpy, c->pre.win, ButtonPress | EnterWindowMask | LeaveWindowMask ); 116 + XMapWindow(dpy, c->pre.win); 117 + GC gc = XCreateGC(dpy, c->pre.win, 0, NULL); 118 + XPutImage(dpy, c->pre.win, gc, c->pre.scaled_image, 0, 0, 0, 0, c->pre.scaled_image->width, c->pre.scaled_image->height); 119 + } 120 + } 121 + while (1) { 122 + XNextEvent(dpy, &event); 123 + if (event.type == ButtonPress) 124 + if (event.xbutton.button == Button1){ 125 + for(c = m->clients; c; c = c->next){ 126 + XUnmapWindow(dpy, c->pre.win); 127 + if (event.xbutton.window == c->pre.win){ 128 + selmon->seltags ^= 1; /* toggle sel tagset */ 129 + m->tagset[selmon->seltags] = c->tags; 130 + focus_c = c; 131 + focus(NULL); 132 +#ifdef AWESOMEBAR 133 + if (HIDDEN(c)){ 134 + showwin(c); 135 + continue; 136 + } 137 +#endif 138 + } 139 + /* If you hit awesomebar patch Unlock the notes below; 140 + * And you should add the following line to "hidewin" Function 141 + * c->pre.orig_image = getwindowximage(c); 142 + * */ 143 +#ifdef AWESOMEBAR 144 + if (HIDDEN(c)){ 145 + continue; 146 + } 147 +#endif 148 + XMapWindow(dpy, c->win); 149 + XDestroyImage(c->pre.orig_image); 150 + XDestroyImage(c->pre.scaled_image); 151 + } 152 + break; 153 + } 154 + if (event.type == EnterNotify) 155 + for(c = m->clients; c; c = c->next) 156 + if (event.xcrossing.window == c->pre.win){ 157 + XSetWindowBorder(dpy, c->pre.win, scheme[SchemeSel][ColBorder].pixel); 158 + break; 159 + } 160 + if (event.type == LeaveNotify) 161 + for(c = m->clients; c; c = c->next) 162 + if (event.xcrossing.window == c->pre.win){ 163 + XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel); 164 + break; 165 + } 166 + } 167 + arrange(m); 168 + focus(focus_c); 169 +} 170 + 171 +void 172 +setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi){ 173 + unsigned int i, j; 174 + unsigned int cx, cy, cw, ch, cmaxh; 175 + unsigned int cols, rows; 176 + Client *c, *tmpc; 177 + 178 + if (n == 1) { 179 + c = m->clients; 180 + cw = (m->ww - 2 * gappo) * 0.8; 181 + ch = (m->wh - 2 * gappo) * 0.9; 182 + c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch); 183 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width) / 2; 184 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2; 185 + return; 186 + } 187 + if (n == 2) { 188 + c = m->clients; 189 + cw = (m->ww - 2 * gappo - gappi) / 2; 190 + ch = (m->wh - 2 * gappo) * 0.7; 191 + c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch); 192 + c->next->pre.scaled_image = scaledownimage(c->next->pre.orig_image, cw, ch); 193 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width - gappi - c->next->pre.scaled_image->width) / 2; 194 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2; 195 + c->next->pre.x = c->pre.x + c->pre.scaled_image->width + gappi; 196 + c->next->pre.y = m->my + (m->mh - c->next->pre.scaled_image->height) / 2; 197 + return; 198 + } 199 + for (cols = 0; cols <= n / 2; cols++) 200 + if (cols * cols >= n) 201 + break; 202 + rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols; 203 + ch = (m->wh - 2 * gappo) / rows; 204 + cw = (m->ww - 2 * gappo) / cols; 205 + c = m->clients; 206 + cy = 0; 207 + for (i = 0; i < rows; i++) { 208 + cx = 0; 209 + cmaxh = 0; 210 + tmpc = c; 211 + for (int j = 0; j < cols; j++) { 212 + if (!c) 213 + break; 214 + c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch); 215 + c->pre.x = cx; 216 + cmaxh = c->pre.scaled_image->height > cmaxh ? c->pre.scaled_image->height : cmaxh; 217 + cx += c->pre.scaled_image->width + gappi; 218 + c = c->next; 219 + } 220 + c = tmpc; 221 + cx = m->wx + (m->ww - cx) / 2; 222 + for (j = 0; j < cols; j++) { 223 + if (!c) 224 + break; 225 + c->pre.x += cx; 226 + c->pre.y = cy + (cmaxh - c->pre.scaled_image->height) / 2; 227 + c = c->next; 228 + } 229 + cy += cmaxh + gappi; 230 + } 231 + cy = m->wy + (m->wh - cy) / 2; 232 + for (c = m->clients; c; c = c->next) 233 + c->pre.y += cy; 234 +} 235 + 236 +XImage* 237 +getwindowximage(Client *c) { 238 + XWindowAttributes attr; 239 + XGetWindowAttributes( dpy, c->win, &attr ); 240 + XRenderPictFormat *format = XRenderFindVisualFormat( dpy, attr.visual ); 241 + int hasAlpha = ( format->type == PictTypeDirect && format->direct.alphaMask ); 242 + XRenderPictureAttributes pa; 243 + pa.subwindow_mode = IncludeInferiors; 244 + Picture picture = XRenderCreatePicture( dpy, c->win, format, CPSubwindowMode, &pa ); 245 + Pixmap pixmap = XCreatePixmap(dpy, root, c->w, c->h, 32); 246 + XRenderPictureAttributes pa2; 247 + XRenderPictFormat *format2 = XRenderFindStandardFormat(dpy, PictStandardARGB32); 248 + Picture pixmapPicture = XRenderCreatePicture( dpy, pixmap, format2, 0, &pa2 ); 249 + XRenderColor color; 250 + color.red = 0x0000; 251 + color.green = 0x0000; 252 + color.blue = 0x0000; 253 + color.alpha = 0x0000; 254 + XRenderFillRectangle (dpy, PictOpSrc, pixmapPicture, &color, 0, 0, c->w, c->h); 255 + XRenderComposite(dpy, hasAlpha ? PictOpOver : PictOpSrc, picture, 0, 256 + pixmapPicture, 0, 0, 0, 0, 0, 0, 257 + c->w, c->h); 258 + XImage* temp = XGetImage( dpy, pixmap, 0, 0, c->w, c->h, AllPlanes, ZPixmap ); 259 + temp->red_mask = format2->direct.redMask << format2->direct.red; 260 + temp->green_mask = format2->direct.greenMask << format2->direct.green; 261 + temp->blue_mask = format2->direct.blueMask << format2->direct.blue; 262 + temp->depth = DefaultDepth(dpy, screen); 263 + return temp; 264 +} 265 + 266 +XImage* 267 +scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch) { 268 + int factor_w = orig_image->width / cw + 1; 269 + int factor_h = orig_image->height / ch + 1; 270 + int scale_factor = factor_w > factor_h ? factor_w : factor_h; 271 + int scaled_width = orig_image->width / scale_factor; 272 + int scaled_height = orig_image->height / scale_factor; 273 + XImage *scaled_image = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), 274 + orig_image->depth, 275 + ZPixmap, 0, NULL, 276 + scaled_width, scaled_height, 277 + 32, 0); 278 + scaled_image->data = malloc(scaled_image->height * scaled_image->bytes_per_line); 279 + for (int y = 0; y < scaled_height; y++) { 280 + for (int x = 0; x < scaled_width; x++) { 281 + int orig_x = x * scale_factor; 282 + int orig_y = y * scale_factor; 283 + unsigned long pixel = XGetPixel(orig_image, orig_x, orig_y); 284 + XPutPixel(scaled_image, x, y, pixel); 285 + } 286 + } 287 + scaled_image->depth = orig_image->depth; 288 + return scaled_image; 289 +} 290 + 291 int 292 main(int argc, char *argv[]) 293 { 294 -- 295 2.48.1 296