1 /* |
1 /* |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
3 * See LICENSE file for license details. |
3 * See LICENSE file for license details. |
4 */ |
4 */ |
5 |
5 |
6 #include <math.h> |
|
7 #include <stdlib.h> |
6 #include <stdlib.h> |
|
7 #include <stdio.h> |
8 #include <string.h> |
8 #include <string.h> |
9 #include <X11/Xatom.h> |
9 #include <X11/Xatom.h> |
10 #include <X11/Xutil.h> |
10 #include <X11/Xutil.h> |
11 |
11 |
12 #include "dwm.h" |
12 #include "dwm.h" |
13 |
13 |
14 static void (*arrange)(Arg *) = floating; |
14 static void (*arrange)(Arg *) = tiling; |
15 |
15 |
16 static void |
16 static Rule rule[] = { |
17 center(Client *c) |
17 { "Firefox-bin", "Gecko", { [Twww] = "www" } }, |
18 { |
18 }; |
19 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); |
|
20 } |
|
21 |
19 |
22 static Client * |
20 static Client * |
23 next(Client *c) |
21 next(Client *c) |
24 { |
22 { |
25 for(; c && !c->tags[tsel]; c = c->next); |
23 for(; c && !c->tags[tsel]; c = c->next); |
117 |
115 |
118 void |
116 void |
119 tiling(Arg *arg) |
117 tiling(Arg *arg) |
120 { |
118 { |
121 Client *c; |
119 Client *c; |
122 int n, cols, rows, gw, gh, i, j; |
120 int n, i, w, h; |
123 float rt, fd; |
121 |
124 |
122 w = sw - mw; |
125 arrange = tiling; |
123 arrange = tiling; |
126 for(n = 0, c = clients; c; c = next(c->next), n++); |
124 for(n = 0, c = clients; c; c = c->next) |
127 if(n) { |
125 if(c->tags[tsel]) |
128 rt = sqrt(n); |
126 n++; |
129 if(modff(rt, &fd) < 0.5) |
127 |
130 rows = floor(rt); |
128 h = (n > 2) ? sh / (n - 2) : sh; |
131 else |
129 |
132 rows = ceil(rt); |
130 for(i = 0, c = clients; c; c = c->next) { |
133 if(rows * rows < n) |
|
134 cols = rows + 1; |
|
135 else |
|
136 cols = rows; |
|
137 |
|
138 gw = (sw - 2) / cols; |
|
139 gh = (sh - 2) / rows; |
|
140 } |
|
141 else |
|
142 cols = rows = gw = gh = 0; |
|
143 |
|
144 for(i = j = 0, c = clients; c; c = c->next) { |
|
145 if(c->tags[tsel]) { |
131 if(c->tags[tsel]) { |
146 c->x = i * gw; |
132 if(n == 1) { |
147 c->y = j * gh; |
133 c->x = sx; |
148 c->w = gw; |
134 c->y = sy; |
149 c->h = gh; |
135 c->w = sw; |
|
136 c->h = sh; |
|
137 } |
|
138 else if(i == 1) { |
|
139 c->x = sx; |
|
140 c->y = sy; |
|
141 c->w = mw; |
|
142 c->h = sh; |
|
143 } |
|
144 else { |
|
145 c->x = sx + mw; |
|
146 c->y = sy + (i - 2) * h; |
|
147 c->w = w; |
|
148 c->h = h; |
|
149 } |
150 resize(c); |
150 resize(c); |
151 if(++i == cols) { |
151 i++; |
152 j++; |
|
153 i = 0; |
|
154 } |
|
155 } |
152 } |
156 else |
153 else |
157 ban_client(c); |
154 ban_client(c); |
158 } |
155 } |
159 if(sel && !sel->tags[tsel]) { |
156 if(sel && !sel->tags[tsel]) { |
319 XSetWindowBorder(dpy, c->win, dc.fg); |
314 XSetWindowBorder(dpy, c->win, dc.fg); |
320 draw_client(c); |
315 draw_client(c); |
321 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
316 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
322 XFlush(dpy); |
317 XFlush(dpy); |
323 discard_events(EnterWindowMask); |
318 discard_events(EnterWindowMask); |
|
319 } |
|
320 |
|
321 static void |
|
322 init_tags(Client *c) |
|
323 { |
|
324 XClassHint ch; |
|
325 static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; |
|
326 unsigned int i, j; |
|
327 Bool matched = False; |
|
328 |
|
329 if(!len) { |
|
330 c->tags[tsel] = tags[tsel]; |
|
331 return; |
|
332 } |
|
333 |
|
334 if(XGetClassHint(dpy, c->win, &ch)) { |
|
335 if(ch.res_class && ch.res_name) { |
|
336 fprintf(stderr, "%s:%s\n", ch.res_class, ch.res_name); |
|
337 for(i = 0; i < len; i++) |
|
338 if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) |
|
339 && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) |
|
340 { |
|
341 fprintf(stderr, "->>>%s:%s\n", ch.res_class, ch.res_name); |
|
342 for(j = 0; j < TLast; j++) |
|
343 c->tags[j] = rule[i].tags[j]; |
|
344 matched = True; |
|
345 break; |
|
346 } |
|
347 } |
|
348 if(ch.res_class) |
|
349 XFree(ch.res_class); |
|
350 if(ch.res_name) |
|
351 XFree(ch.res_name); |
|
352 } |
|
353 |
|
354 if(!matched) |
|
355 c->tags[tsel] = tags[tsel]; |
324 } |
356 } |
325 |
357 |
326 void |
358 void |
327 manage(Window w, XWindowAttributes *wa) |
359 manage(Window w, XWindowAttributes *wa) |
328 { |
360 { |
344 XGetTransientForHint(dpy, c->win, &c->trans); |
376 XGetTransientForHint(dpy, c->win, &c->trans); |
345 twa.override_redirect = 1; |
377 twa.override_redirect = 1; |
346 twa.background_pixmap = ParentRelative; |
378 twa.background_pixmap = ParentRelative; |
347 twa.event_mask = ExposureMask; |
379 twa.event_mask = ExposureMask; |
348 |
380 |
349 c->tags[tsel] = tags[tsel]; |
|
350 c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th, |
381 c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th, |
351 0, DefaultDepth(dpy, screen), CopyFromParent, |
382 0, DefaultDepth(dpy, screen), CopyFromParent, |
352 DefaultVisual(dpy, screen), |
383 DefaultVisual(dpy, screen), |
353 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); |
384 CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa); |
354 |
385 |
355 update_name(c); |
386 update_name(c); |
|
387 init_tags(c); |
356 |
388 |
357 for(l = &clients; *l; l = &(*l)->next); |
389 for(l = &clients; *l; l = &(*l)->next); |
358 c->next = *l; /* *l == nil */ |
390 c->next = *l; /* *l == nil */ |
359 *l = c; |
391 *l = c; |
360 |
392 |
366 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask, |
398 XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask, |
367 GrabModeAsync, GrabModeSync, None, None); |
399 GrabModeAsync, GrabModeSync, None, None); |
368 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, |
400 XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask, |
369 GrabModeAsync, GrabModeSync, None, None); |
401 GrabModeAsync, GrabModeSync, None, None); |
370 arrange(NULL); |
402 arrange(NULL); |
371 center(c); |
403 if(c->tags[tsel]) |
372 focus(c); |
404 focus(c); |
|
405 else |
|
406 ban_client(c); |
373 } |
407 } |
374 |
408 |
375 void |
409 void |
376 gravitate(Client *c, Bool invert) |
410 gravitate(Client *c, Bool invert) |
377 { |
411 { |