Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-preview-all-windows-20250407-e381933.diff - sites - public wiki contents of…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-preview-all-windows-20250407-e381933.diff (12466B)
---
1 From e381933255718c6ed30e1b930d8fd76d62ccda75 Mon Sep 17 00:00:00 2001
2 From: elbachir-one <[email protected]>
3 Date: Mon, 7 Apr 2025 06:02:14 +0100
4 Subject: [PATCH] Added some keys to move/select around windows in the pr…
5
6 ---
7 config.def.h | 4 +
8 config.mk | 2 +-
9 dwm.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 312 insertions(+), 1 deletion(-)
11
12 diff --git a/config.def.h b/config.def.h
13 index 4412cb1..37feaf7 100644
14 --- a/config.def.h
15 +++ b/config.def.h
16 @@ -1,5 +1,8 @@
17 /* See LICENSE file for copyright and license details. */
18
19 +//#define ACTUALFULLSCREEN /* Uncomment if the actualfullscreen patch i…
20 +//#define AWESOMEBAR /* Uncommnet if the awesomebar patch is used */
21 +
22 /* appearance */
23 static const unsigned int borderpx = 1; /* border pixel of wind…
24 static const unsigned int snap = 32; /* snap pixel */
25 @@ -95,6 +98,7 @@ static const Key keys[] = {
26 TAGKEYS( XK_8, 7)
27 TAGKEYS( XK_9, 8)
28 { MODKEY|ShiftMask, XK_q, quit, {0} …
29 + { MODKEY, XK_r, togglepreviewallwin,…
30 };
31
32 /* button definitions */
33 diff --git a/config.mk b/config.mk
34 index 8efca9a..8df2978 100644
35 --- a/config.mk
36 +++ b/config.mk
37 @@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2
38
39 # includes and libs
40 INCS = -I${X11INC} -I${FREETYPEINC}
41 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
42 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender
43
44 # flags
45 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSI…
46 diff --git a/dwm.c b/dwm.c
47 index 1443802..6d38874 100644
48 --- a/dwm.c
49 +++ b/dwm.c
50 @@ -40,6 +40,7 @@
51 #include <X11/extensions/Xinerama.h>
52 #endif /* XINERAMA */
53 #include <X11/Xft/Xft.h>
54 +#include <X11/extensions/Xrender.h>
55
56 #include "drw.h"
57 #include "util.h"
58 @@ -83,6 +84,16 @@ typedef struct {
59
60 typedef struct Monitor Monitor;
61 typedef struct Client Client;
62 +
63 +typedef struct Preview Preview;
64 +struct Preview {
65 + XImage *orig_image;
66 + XImage *scaled_image;
67 + Window win;
68 + unsigned int x, y;
69 + Preview *next;
70 +};
71 +
72 struct Client {
73 char name[256];
74 float mina, maxa;
75 @@ -96,6 +107,7 @@ struct Client {
76 Client *snext;
77 Monitor *mon;
78 Window win;
79 + Preview pre;
80 };
81
82 typedef struct {
83 @@ -232,8 +244,14 @@ static int xerror(Display *dpy, XErrorEvent *ee);
84 static int xerrordummy(Display *dpy, XErrorEvent *ee);
85 static int xerrorstart(Display *dpy, XErrorEvent *ee);
86 static void zoom(const Arg *arg);
87 +static void togglepreviewallwin();
88 +static void highlightwindow(int idx, Monitor *m);
89 +static void setpreviewwindowsizepositions(unsigned int n, Monitor *m, u…
90 +static XImage *getwindowximage(Client *c);
91 +static XImage *scaledownimage(XImage *orig_image, unsigned int cw, unsi…
92
93 /* variables */
94 +
95 static const char broken[] = "broken";
96 static char stext[256];
97 static int screen;
98 @@ -266,6 +284,7 @@ static Display *dpy;
99 static Drw *drw;
100 static Monitor *mons, *selmon;
101 static Window root, wmcheckwin;
102 +static int previewallwin = 0;
103
104 /* configuration, allows nested code to access above variables */
105 #include "config.h"
106 @@ -2139,6 +2158,294 @@ zoom(const Arg *arg)
107 pop(c);
108 }
109
110 +void
111 +togglepreviewallwin() {
112 + if (previewallwin) { /* If already active, disable preview */
113 + previewallwin = 0;
114 + for (Client *c = selmon->clients; c; c = c->next) {
115 + XUnmapWindow(dpy, c->pre.win);
116 + XMapWindow(dpy, c->win);
117 + if (c->pre.orig_image)
118 + XDestroyImage(c->pre.orig_image);
119 + if (c->pre.scaled_image)
120 + XDestroyImage(c->pre.scaled_image);
121 + }
122 + arrange(selmon);
123 + focus(NULL);
124 + return; /* Exit function early to prevent running agai…
125 + }
126 +
127 + previewallwin = 1; /* Enable preview mode */
128 + Monitor *m = selmon;
129 + Client *c, *focus_c = NULL;
130 + unsigned int n = 0;
131 +
132 + for (c = m->clients; c; c = c->next, n++) {
133 +#ifdef ACTUALFULLSCREEN
134 + if (c->isfullscreen)
135 + togglefullscr(&(Arg){0});
136 +#endif
137 +#ifdef AWESOMEBAR
138 + if (HIDDEN(c))
139 + continue;
140 +#endif
141 + c->pre.orig_image = getwindowximage(c);
142 + }
143 +
144 + if (n == 0) return;
145 +
146 + setpreviewwindowsizepositions(n, m, 60, 15);
147 + XEvent event;
148 +
149 + for (c = m->clients; c; c = c->next) {
150 + if (!c->pre.win)
151 + c->pre.win = XCreateSimpleWindow(dpy, root, c->…
152 + c->pre.scaled_image->width, c->…
153 + 1, BlackPixel(dpy, screen), Whi…
154 + else
155 + XMoveResizeWindow(dpy, c->pre.win, c->pre.x, c-…
156 + c->pre.scaled_image->width, c->…
157 +
158 + XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][Co…
159 + XUnmapWindow(dpy, c->win);
160 +
161 + if (c->pre.win) {
162 + XSelectInput(dpy, c->pre.win, ButtonPress | Ent…
163 + XMapWindow(dpy, c->pre.win);
164 + GC gc = XCreateGC(dpy, c->pre.win, 0, NULL);
165 + XPutImage(dpy, c->pre.win, gc, c->pre.scaled_im…
166 + c->pre.scaled_image->width, c->…
167 + }
168 + }
169 +
170 + int selected_idx = 0;
171 +
172 + while (previewallwin) {
173 + XNextEvent(dpy, &event);
174 + if (event.type == ButtonPress) {
175 + if (event.xbutton.button == Button1) { /* Left-…
176 + for (c = selmon->clients; c; c = c->nex…
177 + if (event.xbutton.window == c->…
178 + previewallwin = 0;
179 + selmon->tagset[selmon->…
180 + focus(c);
181 + arrange(selmon); /* Ens…
182 + break;
183 + }
184 + }
185 + }
186 + }
187 + if (event.type == KeyPress) {
188 + if (event.xkey.keycode == XKeysymToKeycode(dpy,…
189 + if (selected_idx < n - 1) {
190 + selected_idx++;
191 + }
192 + highlightwindow(selected_idx, m);
193 + }
194 + if (event.xkey.keycode == XKeysymToKeycode(dpy,…
195 + if (selected_idx > 0) {
196 + selected_idx--;
197 + }
198 + highlightwindow(selected_idx, m);
199 + }
200 + if (event.xkey.keycode == XKeysymToKeycode(dpy,…
201 + previewallwin = 0;
202 + Client *selected_client = NULL;
203 + int idx = 0;
204 +
205 + for (c = m->clients; c; c = c->next, id…
206 + if (idx == selected_idx) {
207 + selected_client = c;
208 + break;
209 + }
210 + }
211 + if (selected_client) {
212 + selmon->tagset[selmon->seltags]…
213 + focus(selected_client);
214 + arrange(selmon);
215 + }
216 + }
217 + if (event.xkey.keycode == XKeysymToKeycode(dpy,…
218 + previewallwin = 0;
219 + Client *selected_client = NULL;
220 + int idx = 0;
221 +
222 + for (c = m->clients; c; c = c->next, id…
223 + if (idx == selected_idx) {
224 + selected_client = c;
225 + break;
226 + }
227 + }
228 + if (selected_client) {
229 + selmon->tagset[selmon->seltags]…
230 + focus(selected_client);
231 + arrange(selmon);
232 + }
233 + }
234 + }
235 +
236 + if (event.type == EnterNotify) {
237 + for (c = m->clients; c; c = c->next) {
238 + if (event.xcrossing.window == c->pre.wi…
239 + XSetWindowBorder(dpy, c->pre.wi…
240 + break;
241 + }
242 + }
243 + }
244 + if (event.type == LeaveNotify) {
245 + for (c = m->clients; c; c = c->next) {
246 + if (event.xcrossing.window == c->pre.wi…
247 + XSetWindowBorder(dpy, c->pre.wi…
248 + break;
249 + }
250 + }
251 + }
252 + }
253 + for (c = selmon->clients; c; c = c->next) { /* Restore all wind…
254 + XUnmapWindow(dpy, c->pre.win);
255 + XMapWindow(dpy, c->win);
256 + if (c->pre.orig_image)
257 + XDestroyImage(c->pre.orig_image);
258 + if (c->pre.scaled_image)
259 + XDestroyImage(c->pre.scaled_image);
260 + }
261 + arrange(m);
262 + focus(focus_c);
263 +}
264 +
265 +void
266 +highlightwindow(int idx, Monitor *m) {
267 + int i = 0;
268 + Client *c;
269 + for (c = m->clients; c; c = c->next, i++) {
270 + if (i == idx) {
271 + XSetWindowBorder(dpy, c->pre.win, scheme[Scheme…
272 + } else {
273 + XSetWindowBorder(dpy, c->pre.win, scheme[Scheme…
274 + }
275 + }
276 +}
277 +
278 +void
279 +setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int …
280 + unsigned int i, j;
281 + unsigned int cx, cy, cw, ch, cmaxh;
282 + unsigned int cols, rows;
283 + Client *c, *tmpc;
284 +
285 + if (n == 1) {
286 + c = m->clients;
287 + cw = (m->ww - 2 * gappo) * 0.8;
288 + ch = (m->wh - 2 * gappo) * 0.9;
289 + c->pre.scaled_image = scaledownimage(c->pre.orig_image,…
290 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width)…
291 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height…
292 + return;
293 + }
294 + if (n == 2) {
295 + c = m->clients;
296 + cw = (m->ww - 2 * gappo - gappi) / 2;
297 + ch = (m->wh - 2 * gappo) * 0.7;
298 + c->pre.scaled_image = scaledownimage(c->pre.orig_image,…
299 + c->next->pre.scaled_image = scaledownimage(c->next->pre…
300 + c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width …
301 + c->pre.y = m->my + (m->mh - c->pre.scaled_image->height…
302 + c->next->pre.x = c->pre.x + c->pre.scaled_image->width …
303 + c->next->pre.y = m->my + (m->mh - c->next->pre.scaled_i…
304 + return;
305 + }
306 + for (cols = 0; cols <= n / 2; cols++)
307 + if (cols * cols >= n)
308 + break;
309 + rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols;
310 + ch = (m->wh - 2 * gappo) / rows;
311 + cw = (m->ww - 2 * gappo) / cols;
312 + c = m->clients;
313 + cy = 0;
314 + for (i = 0; i < rows; i++) {
315 + cx = 0;
316 + cmaxh = 0;
317 + tmpc = c;
318 + for (int j = 0; j < cols; j++) {
319 + if (!c)
320 + break;
321 + c->pre.scaled_image = scaledownimage(c->pre.ori…
322 + c->pre.x = cx;
323 + cmaxh = c->pre.scaled_image->height > cmaxh ? c…
324 + cx += c->pre.scaled_image->width + gappi;
325 + c = c->next;
326 + }
327 + c = tmpc;
328 + cx = m->wx + (m->ww - cx) / 2;
329 + for (j = 0; j < cols; j++) {
330 + if (!c)
331 + break;
332 + c->pre.x += cx;
333 + c->pre.y = cy + (cmaxh - c->pre.scaled_image->h…
334 + c = c->next;
335 + }
336 + cy += cmaxh + gappi;
337 + }
338 + cy = m->wy + (m->wh - cy) / 2;
339 + for (c = m->clients; c; c = c->next)
340 + c->pre.y += cy;
341 +}
342 +
343 +XImage*
344 +getwindowximage(Client *c) {
345 + XWindowAttributes attr;
346 + XGetWindowAttributes( dpy, c->win, &attr );
347 + XRenderPictFormat *format = XRenderFindVisualFormat( dpy, attr.…
348 + int hasAlpha = ( format->type == PictTypeDirect && format->dire…
349 + XRenderPictureAttributes pa;
350 + pa.subwindow_mode = IncludeInferiors;
351 + Picture picture = XRenderCreatePicture( dpy, c->win, format, CP…
352 + Pixmap pixmap = XCreatePixmap(dpy, root, c->w, c->h, 32);
353 + XRenderPictureAttributes pa2;
354 + XRenderPictFormat *format2 = XRenderFindStandardFormat(dpy, Pic…
355 + Picture pixmapPicture = XRenderCreatePicture( dpy, pixmap, form…
356 + XRenderColor color;
357 + color.red = 0x0000;
358 + color.green = 0x0000;
359 + color.blue = 0x0000;
360 + color.alpha = 0x0000;
361 + XRenderFillRectangle (dpy, PictOpSrc, pixmapPicture, &color, 0,…
362 + XRenderComposite(dpy, hasAlpha ? PictOpOver : PictOpSrc, pictur…
363 + pixmapPicture, 0, 0, 0, 0, 0, 0,
364 + c->w, c->h);
365 + XImage* temp = XGetImage( dpy, pixmap, 0, 0, c->w, c->h, AllPla…
366 + temp->red_mask = format2->direct.redMask << format2->direct.red;
367 + temp->green_mask = format2->direct.greenMask << format2->direct…
368 + temp->blue_mask = format2->direct.blueMask << format2->direct.b…
369 + temp->depth = DefaultDepth(dpy, screen);
370 + return temp;
371 +}
372 +
373 +XImage*
374 +scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch) {
375 + int factor_w = orig_image->width / cw + 1;
376 + int factor_h = orig_image->height / ch + 1;
377 + int scale_factor = factor_w > factor_h ? factor_w : factor_h;
378 + int scaled_width = orig_image->width / scale_factor;
379 + int scaled_height = orig_image->height / scale_factor;
380 + XImage *scaled_image = XCreateImage(dpy, DefaultVisual(dpy, Def…
381 + orig_image->depth,
382 + ZPixmap, 0, NULL,
383 + scaled_width, scaled_height,
384 + 32, 0);
385 + scaled_image->data = malloc(scaled_image->height * scaled_image…
386 + for (int y = 0; y < scaled_height; y++) {
387 + for (int x = 0; x < scaled_width; x++) {
388 + int orig_x = x * scale_factor;
389 + int orig_y = y * scale_factor;
390 + unsigned long pixel = XGetPixel(orig_image, ori…
391 + XPutPixel(scaled_image, x, y, pixel);
392 + }
393 + }
394 + scaled_image->depth = orig_image->depth;
395 + return scaled_image;
396 +}
397 +
398 int
399 main(int argc, char *argv[])
400 {
401 --
402 2.48.1
403
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.