sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

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