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