dwm-preview-all-windows-6.5.diff - 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 i… | |
9 +//#define AWESOMEBAR /* Uncommnet if the awesomebar patch is used… | |
10 + | |
11 /* appearance */ | |
12 static const unsigned int borderpx = 1; /* border pixel of wind… | |
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 -DVERSI… | |
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, u… | |
78 +static XImage *getwindowximage(Client *c); | |
79 +static XImage *scaledownimage(XImage *orig_image, unsigned int cw, unsi… | |
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->… | |
110 + else | |
111 + XMoveResizeWindow(dpy, c->pre.win, c->pre.x, c-… | |
112 + XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][Co… | |
113 + XUnmapWindow(dpy, c->win); | |
114 + if (c->pre.win){ | |
115 + XSelectInput(dpy, c->pre.win, ButtonPress | Ent… | |
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_im… | |
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->… | |
128 + selmon->seltags ^= 1; /… | |
129 + m->tagset[selmon->selta… | |
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 … | |
140 + * And you should add the follo… | |
141 + * c->pre.orig_image = getwindo… | |
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_ima… | |
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.wi… | |
157 + XSetWindowBorder(dpy, c->pre.wi… | |
158 + break; | |
159 + } | |
160 + if (event.type == LeaveNotify) | |
161 + for(c = m->clients; c; c = c->next) | |
162 + if (event.xcrossing.window == c->pre.wi… | |
163 + XSetWindowBorder(dpy, c->pre.wi… | |
164 + break; | |
165 + } | |
166 + } | |
167 + arrange(m); | |
168 + focus(focus_c); | |
169 +} | |
170 + | |
171 +void | |
172 +setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int … | |
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,… | |
183 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width)… | |
184 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height… | |
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,… | |
192 + c->next->pre.scaled_image = scaledownimage(c->next->pre… | |
193 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width … | |
194 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height… | |
195 + c->next->pre.x = c->pre.x + c->pre.scaled_image->width … | |
196 + c->next->pre.y = m->my + (m->mh - c->next->pre.scaled_i… | |
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.ori… | |
215 + c->pre.x = cx; | |
216 + cmaxh = c->pre.scaled_image->height > cmaxh ? c… | |
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->h… | |
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.… | |
241 + int hasAlpha = ( format->type == PictTypeDirect && format->dire… | |
242 + XRenderPictureAttributes pa; | |
243 + pa.subwindow_mode = IncludeInferiors; | |
244 + Picture picture = XRenderCreatePicture( dpy, c->win, format, CP… | |
245 + Pixmap pixmap = XCreatePixmap(dpy, root, c->w, c->h, 32); | |
246 + XRenderPictureAttributes pa2; | |
247 + XRenderPictFormat *format2 = XRenderFindStandardFormat(dpy, Pic… | |
248 + Picture pixmapPicture = XRenderCreatePicture( dpy, pixmap, form… | |
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,… | |
255 + XRenderComposite(dpy, hasAlpha ? PictOpOver : PictOpSrc, pictur… | |
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, AllPla… | |
259 + temp->red_mask = format2->direct.redMask << format2->direct.red; | |
260 + temp->green_mask = format2->direct.greenMask << format2->direct… | |
261 + temp->blue_mask = format2->direct.blueMask << format2->direct.b… | |
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, Def… | |
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… | |
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, ori… | |
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 |