| 38 |
38 |
|
#include <X11/Xutil.h> |
| 39 |
39 |
|
#ifdef XINERAMA |
| 40 |
40 |
|
#include <X11/extensions/Xinerama.h> |
| 41 |
|
- |
#endif |
|
41 |
+ |
#endif /* XINERAMA */ |
| 42 |
42 |
|
|
| 43 |
43 |
|
/* macros */ |
| 44 |
44 |
|
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) |
| 45 |
45 |
|
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask)) |
| 46 |
46 |
|
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) |
| 47 |
|
- |
#define ISVISIBLE(x) (x->tags & tagset[selmon->seltags]) |
|
47 |
+ |
#define ISVISIBLE(x) (x->tags & tagset[mon[x->mon].seltags]) |
| 48 |
48 |
|
#define LENGTH(x) (sizeof x / sizeof x[0]) |
| 49 |
49 |
|
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
| 50 |
50 |
|
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
|
| 115 |
115 |
|
} Key; |
| 116 |
116 |
|
|
| 117 |
117 |
|
typedef struct { |
| 118 |
|
- |
const char *symbol; |
| 119 |
|
- |
void (*arrange)(void); |
| 120 |
|
- |
} Layout; |
| 121 |
|
- |
|
| 122 |
|
- |
typedef struct { |
| 123 |
|
- |
int wx, wy, ww, wh; |
|
118 |
+ |
char symbol[4]; |
|
119 |
+ |
int by, btx; /* bar geometry */ |
|
120 |
+ |
int wx, wy, ww, wh; /* window area */ |
| 124 |
121 |
|
unsigned int seltags; |
| 125 |
122 |
|
unsigned int sellt; |
|
123 |
+ |
Bool showbar; |
|
124 |
+ |
Bool topbar; |
|
125 |
+ |
Window barwin; |
| 126 |
126 |
|
} Monitor; |
| 127 |
127 |
|
|
| 128 |
128 |
|
typedef struct { |
|
129 |
+ |
const char *symbol; |
|
130 |
+ |
void (*arrange)(Monitor *); |
|
131 |
+ |
} Layout; |
|
132 |
+ |
|
|
133 |
+ |
typedef struct { |
| 129 |
134 |
|
const char *class; |
| 130 |
135 |
|
const char *instance; |
| 131 |
136 |
|
const char *title; |
|
| 150 |
155 |
|
static void detach(Client *c); |
| 151 |
156 |
|
static void detachstack(Client *c); |
| 152 |
157 |
|
static void die(const char *errstr, ...); |
| 153 |
|
- |
static void drawbar(void); |
|
158 |
+ |
static void drawbar(Monitor *m); |
|
159 |
+ |
static void drawbars(); |
| 154 |
160 |
|
static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
| 155 |
161 |
|
static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
| 156 |
162 |
|
static void enternotify(XEvent *e); |
|
| 171 |
177 |
|
static void manage(Window w, XWindowAttributes *wa); |
| 172 |
178 |
|
static void mappingnotify(XEvent *e); |
| 173 |
179 |
|
static void maprequest(XEvent *e); |
| 174 |
|
- |
static void monocle(void); |
|
180 |
+ |
static void monocle(Monitor *m); |
| 175 |
181 |
|
static void movemouse(const Arg *arg); |
| 176 |
|
- |
static Client *nexttiled(Client *c); |
|
182 |
+ |
static Client *nexttiled(Monitor *m, Client *c); |
| 177 |
183 |
|
static void propertynotify(XEvent *e); |
| 178 |
184 |
|
static void quit(const Arg *arg); |
| 179 |
185 |
|
static void resize(Client *c, int x, int y, int w, int h); |
| 180 |
186 |
|
static void resizemouse(const Arg *arg); |
| 181 |
|
- |
static void restack(void); |
|
187 |
+ |
static void restack(Monitor *m); |
| 182 |
188 |
|
static void run(void); |
| 183 |
189 |
|
static void scan(void); |
| 184 |
190 |
|
static void setclientstate(Client *c, long state); |
|
| 190 |
196 |
|
static void spawn(const Arg *arg); |
| 191 |
197 |
|
static void tag(const Arg *arg); |
| 192 |
198 |
|
static int textnw(const char *text, unsigned int len); |
| 193 |
|
- |
static void tile(void); |
|
199 |
+ |
static void tile(Monitor *); |
| 194 |
200 |
|
static void togglebar(const Arg *arg); |
| 195 |
201 |
|
static void togglefloating(const Arg *arg); |
| 196 |
202 |
|
static void toggletag(const Arg *arg); |
| 197 |
203 |
|
static void toggleview(const Arg *arg); |
| 198 |
204 |
|
static void unmanage(Client *c); |
| 199 |
205 |
|
static void unmapnotify(XEvent *e); |
| 200 |
|
- |
static void updatebar(void); |
| 201 |
206 |
|
static void updategeom(void); |
| 202 |
207 |
|
static void updatenumlockmask(void); |
| 203 |
208 |
|
static void updatesizehints(Client *c); |
|
| 209 |
214 |
|
static int xerrordummy(Display *dpy, XErrorEvent *ee); |
| 210 |
215 |
|
static int xerrorstart(Display *dpy, XErrorEvent *ee); |
| 211 |
216 |
|
static void zoom(const Arg *arg); |
|
217 |
+ |
#ifdef XINERAMA |
|
218 |
+ |
static void focusmon(const Arg *arg); |
|
219 |
+ |
static void tagmon(const Arg *arg); |
|
220 |
+ |
#endif /* XINERAMA */ |
| 212 |
221 |
|
|
| 213 |
222 |
|
/* variables */ |
| 214 |
223 |
|
static char stext[256]; |
| 215 |
224 |
|
static int screen; |
| 216 |
|
- |
static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */ |
| 217 |
|
- |
static int by, bh, blw; /* bar geometry y, height and layout symbol width */ |
|
225 |
+ |
static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */ |
|
226 |
+ |
static int bh, blw = 0; /* bar geometry */ |
| 218 |
227 |
|
static int (*xerrorxlib)(Display *, XErrorEvent *); |
| 219 |
228 |
|
static unsigned int numlockmask = 0; |
| 220 |
229 |
|
static void (*handler[LASTEvent]) (XEvent *) = { |
|
| 243 |
252 |
|
static Layout *lt[] = { NULL, NULL }; |
| 244 |
253 |
|
static Monitor *mon = NULL, *selmon = NULL; |
| 245 |
254 |
|
static unsigned int nmons; |
| 246 |
|
- |
static Window root, barwin; |
|
255 |
+ |
static Window root; |
| 247 |
256 |
|
/* configuration, allows nested code to access above variables */ |
| 248 |
257 |
|
#include "config.h" |
| 249 |
258 |
|
|
|
| 266 |
275 |
|
&& (!r->class || (ch.res_class && strstr(ch.res_class, r->class))) |
| 267 |
276 |
|
&& (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) { |
| 268 |
277 |
|
c->isfloating = r->isfloating; |
| 269 |
|
- |
c->tags |= r->tags; |
|
278 |
+ |
c->tags |= r->tags; |
| 270 |
279 |
|
} |
| 271 |
280 |
|
} |
| 272 |
281 |
|
if(ch.res_class) |
|
| 344 |
353 |
|
|
| 345 |
354 |
|
void |
| 346 |
355 |
|
arrange(void) { |
|
356 |
+ |
unsigned int i; |
| 347 |
357 |
|
showhide(stack); |
| 348 |
358 |
|
focus(NULL); |
| 349 |
|
- |
if(lt[selmon->sellt]->arrange) |
| 350 |
|
- |
lt[selmon->sellt]->arrange(); |
| 351 |
|
- |
restack(); |
|
359 |
+ |
for(i = 0; i < nmons; i++) { |
|
360 |
+ |
if(lt[mon[i].sellt]->arrange) |
|
361 |
+ |
lt[mon[i].sellt]->arrange(&mon[i]); |
|
362 |
+ |
restack(&mon[i]); |
|
363 |
+ |
} |
| 352 |
364 |
|
} |
| 353 |
365 |
|
|
| 354 |
366 |
|
void |
|
| 371 |
383 |
|
XButtonPressedEvent *ev = &e->xbutton; |
| 372 |
384 |
|
|
| 373 |
385 |
|
click = ClkRootWin; |
| 374 |
|
- |
if(ev->window == barwin) { |
| 375 |
|
- |
i = x = 0; |
| 376 |
|
- |
do x += TEXTW(tags[i]); while(ev->x >= x && ++i < LENGTH(tags)); |
|
386 |
+ |
if(ev->window == selmon->barwin) { |
|
387 |
+ |
i = 0; |
|
388 |
+ |
x = selmon->btx; |
|
389 |
+ |
do |
|
390 |
+ |
x += TEXTW(tags[i]); |
|
391 |
+ |
while(ev->x >= x && ++i < LENGTH(tags)); |
| 377 |
392 |
|
if(i < LENGTH(tags)) { |
| 378 |
393 |
|
click = ClkTagBar; |
| 379 |
394 |
|
arg.ui = 1 << i; |
|
| 412 |
427 |
|
|
| 413 |
428 |
|
void |
| 414 |
429 |
|
cleanup(void) { |
|
430 |
+ |
unsigned int i; |
| 415 |
431 |
|
Arg a = {.ui = ~0}; |
| 416 |
432 |
|
Layout foo = { "", NULL }; |
| 417 |
433 |
|
|
|
| 429 |
445 |
|
XFreeCursor(dpy, cursor[CurNormal]); |
| 430 |
446 |
|
XFreeCursor(dpy, cursor[CurResize]); |
| 431 |
447 |
|
XFreeCursor(dpy, cursor[CurMove]); |
| 432 |
|
- |
XDestroyWindow(dpy, barwin); |
|
448 |
+ |
for(i = 0; i < nmons; i++) |
|
449 |
+ |
XDestroyWindow(dpy, mon[i].barwin); |
|
450 |
+ |
free(mon); |
| 433 |
451 |
|
XSync(dpy, False); |
| 434 |
452 |
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
| 435 |
453 |
|
} |
|
| 466 |
484 |
|
|
| 467 |
485 |
|
void |
| 468 |
486 |
|
configurenotify(XEvent *e) { |
|
487 |
+ |
unsigned int i; |
| 469 |
488 |
|
XConfigureEvent *ev = &e->xconfigure; |
| 470 |
489 |
|
|
| 471 |
490 |
|
if(ev->window == root && (ev->width != sw || ev->height != sh)) { |
| 472 |
491 |
|
sw = ev->width; |
| 473 |
492 |
|
sh = ev->height; |
| 474 |
493 |
|
updategeom(); |
| 475 |
|
- |
updatebar(); |
|
494 |
+ |
if(dc.drawable != 0) |
|
495 |
+ |
XFreePixmap(dpy, dc.drawable); |
|
496 |
+ |
dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); |
|
497 |
+ |
for(i = 0; i < nmons; i++) |
|
498 |
+ |
XMoveResizeWindow(dpy, mon[i].barwin, mon[i].wx, mon[i].by, mon[i].ww, bh); |
| 476 |
499 |
|
arrange(); |
| 477 |
500 |
|
} |
| 478 |
501 |
|
} |
|
| 556 |
579 |
|
} |
| 557 |
580 |
|
|
| 558 |
581 |
|
void |
| 559 |
|
- |
drawbar(void) { |
|
582 |
+ |
drawbar(Monitor *m) { |
| 560 |
583 |
|
int x; |
| 561 |
584 |
|
unsigned int i, occ = 0, urg = 0; |
| 562 |
585 |
|
unsigned long *col; |
| 563 |
586 |
|
Client *c; |
| 564 |
587 |
|
|
| 565 |
588 |
|
for(c = clients; c; c = c->next) { |
| 566 |
|
- |
occ |= c->tags; |
| 567 |
|
- |
if(c->isurgent) |
| 568 |
|
- |
urg |= c->tags; |
|
589 |
+ |
if(m == &mon[c->mon]) { |
|
590 |
+ |
occ |= c->tags; |
|
591 |
+ |
if(c->isurgent) |
|
592 |
+ |
urg |= c->tags; |
|
593 |
+ |
} |
| 569 |
594 |
|
} |
| 570 |
595 |
|
|
| 571 |
596 |
|
dc.x = 0; |
|
597 |
+ |
#ifdef XINERAMA |
|
598 |
+ |
{ |
|
599 |
+ |
dc.w = TEXTW(m->symbol); |
|
600 |
+ |
drawtext(m->symbol, selmon == m ? dc.sel : dc.norm, False); |
|
601 |
+ |
dc.x += dc.w; |
|
602 |
+ |
} |
|
603 |
+ |
#endif /* XINERAMA */ |
|
604 |
+ |
m->btx = dc.x; |
| 572 |
605 |
|
for(i = 0; i < LENGTH(tags); i++) { |
| 573 |
606 |
|
dc.w = TEXTW(tags[i]); |
| 574 |
|
- |
col = tagset[selmon->seltags] & 1 << i ? dc.sel : dc.norm; |
|
607 |
+ |
col = tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; |
| 575 |
608 |
|
drawtext(tags[i], col, urg & 1 << i); |
| 576 |
|
- |
drawsquare(sel && sel->tags & 1 << i, occ & 1 << i, urg & 1 << i, col); |
|
609 |
+ |
drawsquare(m == selmon && sel && sel->tags & 1 << i, |
|
610 |
+ |
occ & 1 << i, urg & 1 << i, col); |
| 577 |
611 |
|
dc.x += dc.w; |
| 578 |
612 |
|
} |
| 579 |
613 |
|
if(blw > 0) { |
| 580 |
614 |
|
dc.w = blw; |
| 581 |
|
- |
drawtext(lt[selmon->sellt]->symbol, dc.norm, False); |
|
615 |
+ |
drawtext(lt[m->sellt]->symbol, dc.norm, False); |
| 582 |
616 |
|
x = dc.x + dc.w; |
| 583 |
617 |
|
} |
| 584 |
618 |
|
else |
| 585 |
619 |
|
x = dc.x; |
| 586 |
|
- |
dc.w = TEXTW(stext); |
| 587 |
|
- |
dc.x = selmon->ww - dc.w; |
| 588 |
|
- |
if(dc.x < x) { |
| 589 |
|
- |
dc.x = x; |
| 590 |
|
- |
dc.w = selmon->ww - x; |
|
620 |
+ |
if(m == selmon) { |
|
621 |
+ |
dc.w = TEXTW(stext); |
|
622 |
+ |
dc.x = m->ww - dc.w; |
|
623 |
+ |
if(dc.x < x) { |
|
624 |
+ |
dc.x = x; |
|
625 |
+ |
dc.w = m->ww - x; |
|
626 |
+ |
} |
|
627 |
+ |
drawtext(stext, dc.norm, False); |
|
628 |
+ |
if((dc.w = dc.x - x) > bh) { |
|
629 |
+ |
dc.x = x; |
|
630 |
+ |
if(sel) { |
|
631 |
+ |
drawtext(sel->name, dc.sel, False); |
|
632 |
+ |
drawsquare(sel->isfixed, sel->isfloating, False, dc.sel); |
|
633 |
+ |
} |
|
634 |
+ |
else |
|
635 |
+ |
drawtext(NULL, dc.norm, False); |
|
636 |
+ |
} |
| 591 |
637 |
|
} |
| 592 |
|
- |
drawtext(stext, dc.norm, False); |
| 593 |
|
- |
if((dc.w = dc.x - x) > bh) { |
| 594 |
|
- |
dc.x = x; |
| 595 |
|
- |
if(sel) { |
| 596 |
|
- |
drawtext(sel->name, dc.sel, False); |
| 597 |
|
- |
drawsquare(sel->isfixed, sel->isfloating, False, dc.sel); |
| 598 |
|
- |
} |
| 599 |
|
- |
else |
| 600 |
|
- |
drawtext(NULL, dc.norm, False); |
|
638 |
+ |
else { |
|
639 |
+ |
dc.w = m->ww - x; |
|
640 |
+ |
drawtext(NULL, dc.norm, False); |
| 601 |
641 |
|
} |
| 602 |
|
- |
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, selmon->ww, bh, 0, 0); |
|
642 |
+ |
XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); |
| 603 |
643 |
|
XSync(dpy, False); |
|
644 |
+ |
} |
|
645 |
+ |
|
|
646 |
+ |
void |
|
647 |
+ |
drawbars() { |
|
648 |
+ |
unsigned int i; |
|
649 |
+ |
|
|
650 |
+ |
for(i = 0; i < nmons; i++) |
|
651 |
+ |
drawbar(&mon[i]); |
| 604 |
652 |
|
} |
| 605 |
653 |
|
|
| 606 |
654 |
|
void |
|
| 667 |
715 |
|
|
| 668 |
716 |
|
void |
| 669 |
717 |
|
expose(XEvent *e) { |
|
718 |
+ |
unsigned int i; |
| 670 |
719 |
|
XExposeEvent *ev = &e->xexpose; |
| 671 |
720 |
|
|
| 672 |
|
- |
if(ev->count == 0 && (ev->window == barwin)) |
| 673 |
|
- |
drawbar(); |
|
721 |
+ |
for(i = 0; i < nmons; i++) |
|
722 |
+ |
if(ev->count == 0 && (ev->window == mon[i].barwin)) { |
|
723 |
+ |
drawbar(&mon[i]); |
|
724 |
+ |
break; |
|
725 |
+ |
} |
| 674 |
726 |
|
} |
| 675 |
727 |
|
|
| 676 |
728 |
|
void |
|
| 693 |
745 |
|
else |
| 694 |
746 |
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
| 695 |
747 |
|
sel = c; |
| 696 |
|
- |
drawbar(); |
|
748 |
+ |
if(c) |
|
749 |
+ |
selmon = &mon[c->mon]; |
|
750 |
+ |
drawbars(); |
| 697 |
751 |
|
} |
| 698 |
752 |
|
|
| 699 |
753 |
|
void |
|
| 704 |
758 |
|
XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime); |
| 705 |
759 |
|
} |
| 706 |
760 |
|
|
|
761 |
+ |
#ifdef XINERAMA |
|
762 |
+ |
void |
|
763 |
+ |
focusmon(const Arg *arg) { |
|
764 |
+ |
if(arg->ui >= nmons) |
|
765 |
+ |
return; |
|
766 |
+ |
selmon = &mon[arg->ui]; |
|
767 |
+ |
focus(NULL); |
|
768 |
+ |
drawbars(); |
|
769 |
+ |
} |
|
770 |
+ |
#endif /* XINERAMA */ |
|
771 |
+ |
|
| 707 |
772 |
|
void |
| 708 |
773 |
|
focusstack(const Arg *arg) { |
| 709 |
774 |
|
Client *c = NULL, *i; |
| 710 |
775 |
|
|
| 711 |
776 |
|
if(!sel) |
| 712 |
777 |
|
return; |
| 713 |
|
- |
if (arg->i > 0) { |
|
778 |
+ |
if(arg->i > 0) { |
| 714 |
779 |
|
for(c = sel->next; c && !ISVISIBLE(c); c = c->next); |
| 715 |
780 |
|
if(!c) |
| 716 |
781 |
|
for(c = clients; c && !ISVISIBLE(c); c = c->next); |
|
| 726 |
791 |
|
} |
| 727 |
792 |
|
if(c) { |
| 728 |
793 |
|
focus(c); |
| 729 |
|
- |
restack(); |
|
794 |
+ |
restack(selmon); |
| 730 |
795 |
|
} |
| 731 |
796 |
|
} |
| 732 |
797 |
|
|
|
| 946 |
1011 |
|
c->y = sy + sh - HEIGHT(c); |
| 947 |
1012 |
|
c->x = MAX(c->x, sx); |
| 948 |
1013 |
|
/* only fix client y-offset, if the client center might cover the bar */ |
| 949 |
|
- |
/* TODO: is c always attached to selmon? */ |
| 950 |
|
- |
c->y = MAX(c->y, ((by == 0) && (c->x + (c->w / 2) >= selmon->wx) |
| 951 |
|
- |
&& (c->x + (c->w / 2) < selmon->wx + selmon->ww)) ? bh : sy); |
|
1014 |
+ |
c->y = MAX(c->y, ((selmon->by == 0) && (c->x + (c->w / 2) >= selmon->wx) |
|
1015 |
+ |
&& (c->x + (c->w / 2) < selmon->wx + selmon->ww)) ? bh : sy); |
| 952 |
1016 |
|
c->bw = borderpx; |
| 953 |
1017 |
|
} |
| 954 |
1018 |
|
|
|
| 1001 |
1065 |
|
} |
| 1002 |
1066 |
|
|
| 1003 |
1067 |
|
void |
| 1004 |
|
- |
monocle(void) { |
|
1068 |
+ |
monocle(Monitor *m) { |
| 1005 |
1069 |
|
Client *c; |
| 1006 |
|
- |
Monitor *m; |
| 1007 |
1070 |
|
|
| 1008 |
|
- |
for(c = nexttiled(clients); c; c = nexttiled(c->next)) { |
| 1009 |
|
- |
m = &mon[c->mon]; |
|
1071 |
+ |
for(c = nexttiled(m, clients); c; c = nexttiled(m, c->next)) |
| 1010 |
1072 |
|
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw); |
| 1011 |
|
- |
} |
| 1012 |
1073 |
|
} |
| 1013 |
1074 |
|
|
| 1014 |
1075 |
|
void |
|
| 1021 |
1082 |
|
|
| 1022 |
1083 |
|
if(!(c = sel)) |
| 1023 |
1084 |
|
return; |
| 1024 |
|
- |
restack(); |
|
1085 |
+ |
restack(selmon); |
| 1025 |
1086 |
|
ocx = c->x; |
| 1026 |
1087 |
|
ocy = c->y; |
| 1027 |
1088 |
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
| 1063 |
1124 |
|
} |
| 1064 |
1125 |
|
|
| 1065 |
1126 |
|
Client * |
| 1066 |
|
- |
nexttiled(Client *c) { |
| 1067 |
|
- |
for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); |
|
1127 |
+ |
nexttiled(Monitor *m, Client *c) { |
|
1128 |
+ |
// TODO: m handling |
|
1129 |
+ |
for(; c && (c->isfloating || m != &mon[c->mon] || !ISVISIBLE(c)); c = c->next); |
| 1068 |
1130 |
|
return c; |
| 1069 |
1131 |
|
} |
| 1070 |
1132 |
|
|
|
| 1091 |
1153 |
|
break; |
| 1092 |
1154 |
|
case XA_WM_HINTS: |
| 1093 |
1155 |
|
updatewmhints(c); |
| 1094 |
|
- |
drawbar(); |
|
1156 |
+ |
drawbars(); |
| 1095 |
1157 |
|
break; |
| 1096 |
1158 |
|
} |
| 1097 |
1159 |
|
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { |
| 1098 |
1160 |
|
updatetitle(c); |
| 1099 |
1161 |
|
if(c == sel) |
| 1100 |
|
- |
drawbar(); |
|
1162 |
+ |
drawbars(); |
| 1101 |
1163 |
|
} |
| 1102 |
1164 |
|
} |
| 1103 |
1165 |
|
} |
|
| 1133 |
1195 |
|
|
| 1134 |
1196 |
|
if(!(c = sel)) |
| 1135 |
1197 |
|
return; |
| 1136 |
|
- |
restack(); |
|
1198 |
+ |
restack(selmon); |
| 1137 |
1199 |
|
ocx = c->x; |
| 1138 |
1200 |
|
ocy = c->y; |
| 1139 |
1201 |
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
| 1170 |
1232 |
|
} |
| 1171 |
1233 |
|
|
| 1172 |
1234 |
|
void |
| 1173 |
|
- |
restack(void) { |
|
1235 |
+ |
restack(Monitor *m) { |
| 1174 |
1236 |
|
Client *c; |
| 1175 |
1237 |
|
XEvent ev; |
| 1176 |
1238 |
|
XWindowChanges wc; |
| 1177 |
1239 |
|
|
| 1178 |
|
- |
drawbar(); |
|
1240 |
+ |
drawbars(); |
| 1179 |
1241 |
|
if(!sel) |
| 1180 |
1242 |
|
return; |
| 1181 |
|
- |
if(sel->isfloating || !lt[selmon->sellt]->arrange) |
|
1243 |
+ |
if(m == selmon && (sel->isfloating || !lt[m->sellt]->arrange)) |
| 1182 |
1244 |
|
XRaiseWindow(dpy, sel->win); |
| 1183 |
|
- |
if(lt[selmon->sellt]->arrange) { |
|
1245 |
+ |
if(lt[m->sellt]->arrange) { |
| 1184 |
1246 |
|
wc.stack_mode = Below; |
| 1185 |
|
- |
wc.sibling = barwin; |
|
1247 |
+ |
wc.sibling = m->barwin; |
| 1186 |
1248 |
|
for(c = stack; c; c = c->snext) |
| 1187 |
|
- |
if(!c->isfloating && ISVISIBLE(c)) { |
|
1249 |
+ |
if(!c->isfloating && m == &mon[c->mon] && ISVISIBLE(c)) { |
| 1188 |
1250 |
|
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); |
| 1189 |
1251 |
|
wc.sibling = c->win; |
| 1190 |
1252 |
|
} |
|
| 1248 |
1310 |
|
if(sel) |
| 1249 |
1311 |
|
arrange(); |
| 1250 |
1312 |
|
else |
| 1251 |
|
- |
drawbar(); |
|
1313 |
+ |
drawbars(); |
| 1252 |
1314 |
|
} |
| 1253 |
1315 |
|
|
| 1254 |
1316 |
|
/* arg > 1.0 will set mfact absolutly */ |
|
| 1309 |
1371 |
|
if(!dc.font.set) |
| 1310 |
1372 |
|
XSetFont(dpy, dc.gc, dc.font.xfont->fid); |
| 1311 |
1373 |
|
|
| 1312 |
|
- |
/* init bar */ |
|
1374 |
+ |
/* init bars */ |
|
1375 |
+ |
wa.override_redirect = True; |
|
1376 |
+ |
wa.background_pixmap = ParentRelative; |
|
1377 |
+ |
wa.event_mask = ButtonPressMask|ExposureMask; |
| 1313 |
1378 |
|
for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { |
| 1314 |
1379 |
|
w = TEXTW(layouts[i].symbol); |
| 1315 |
1380 |
|
blw = MAX(blw, w); |
| 1316 |
1381 |
|
} |
| 1317 |
1382 |
|
|
| 1318 |
|
- |
wa.override_redirect = True; |
| 1319 |
|
- |
wa.background_pixmap = ParentRelative; |
| 1320 |
|
- |
wa.event_mask = ButtonPressMask|ExposureMask; |
|
1383 |
+ |
for(i = 0; i < nmons; i++) { |
|
1384 |
+ |
mon[i].barwin = XCreateWindow(dpy, root, mon[i].wx, mon[i].by, mon[i].ww, bh, 0, DefaultDepth(dpy, screen), |
| 1321 |
1385 |
|
|
| 1322 |
|
- |
barwin = XCreateWindow(dpy, root, selmon->wx, by, selmon->ww, bh, 0, DefaultDepth(dpy, screen), |
| 1323 |
|
- |
CopyFromParent, DefaultVisual(dpy, screen), |
| 1324 |
|
- |
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); |
| 1325 |
|
- |
XDefineCursor(dpy, barwin, cursor[CurNormal]); |
| 1326 |
|
- |
XMapRaised(dpy, barwin); |
|
1386 |
+ |
CopyFromParent, DefaultVisual(dpy, screen), |
|
1387 |
+ |
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); |
|
1388 |
+ |
XDefineCursor(dpy, mon[i].barwin, cursor[CurNormal]); |
|
1389 |
+ |
XMapRaised(dpy, mon[i].barwin); |
|
1390 |
+ |
} |
| 1327 |
1391 |
|
updatestatus(); |
| 1328 |
1392 |
|
|
| 1329 |
1393 |
|
/* EWMH support per view */ |
|
| 1384 |
1448 |
|
} |
| 1385 |
1449 |
|
} |
| 1386 |
1450 |
|
|
|
1451 |
+ |
#ifdef XINERAMA |
|
1452 |
+ |
void |
|
1453 |
+ |
tagmon(const Arg *arg) { |
|
1454 |
+ |
if(!sel || arg->ui >= nmons) |
|
1455 |
+ |
return; |
|
1456 |
+ |
sel->mon = arg->ui; |
|
1457 |
+ |
arrange(); |
|
1458 |
+ |
} |
|
1459 |
+ |
#endif /* XINERAMA */ |
|
1460 |
+ |
|
| 1387 |
1461 |
|
int |
| 1388 |
1462 |
|
textnw(const char *text, unsigned int len) { |
| 1389 |
1463 |
|
XRectangle r; |
|
| 1396 |
1470 |
|
} |
| 1397 |
1471 |
|
|
| 1398 |
1472 |
|
void |
| 1399 |
|
- |
tile(void) { |
|
1473 |
+ |
tile(Monitor *m) { |
| 1400 |
1474 |
|
int x, y, h, w, mw; |
| 1401 |
1475 |
|
unsigned int i, n; |
| 1402 |
1476 |
|
Client *c; |
| 1403 |
|
- |
Monitor *m; |
| 1404 |
1477 |
|
|
| 1405 |
|
- |
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++); |
|
1478 |
+ |
for(n = 0, c = nexttiled(m, clients); c; c = nexttiled(m, c->next), n++); |
| 1406 |
1479 |
|
if(n == 0) |
| 1407 |
1480 |
|
return; |
| 1408 |
1481 |
|
|
| 1409 |
1482 |
|
/* master */ |
| 1410 |
|
- |
c = nexttiled(clients); |
| 1411 |
|
- |
m = &mon[c->mon]; |
|
1483 |
+ |
c = nexttiled(m, clients); |
| 1412 |
1484 |
|
mw = mfact * m->ww; |
| 1413 |
1485 |
|
resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw); |
| 1414 |
1486 |
|
|
|
| 1423 |
1495 |
|
if(h < bh) |
| 1424 |
1496 |
|
h = m->wh; |
| 1425 |
1497 |
|
|
| 1426 |
|
- |
for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { |
|
1498 |
+ |
for(i = 0, c = nexttiled(m, c->next); c; c = nexttiled(m, c->next), i++) { |
| 1427 |
1499 |
|
resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) |
| 1428 |
1500 |
|
? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw)); |
| 1429 |
1501 |
|
if(h != m->wh) |
|
| 1433 |
1505 |
|
|
| 1434 |
1506 |
|
void |
| 1435 |
1507 |
|
togglebar(const Arg *arg) { |
| 1436 |
|
- |
showbar = !showbar; |
|
1508 |
+ |
selmon->showbar = !selmon->showbar; |
| 1437 |
1509 |
|
updategeom(); |
| 1438 |
|
- |
updatebar(); |
|
1510 |
+ |
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); |
| 1439 |
1511 |
|
arrange(); |
| 1440 |
1512 |
|
} |
| 1441 |
1513 |
|
|
|
| 1453 |
1525 |
|
toggletag(const Arg *arg) { |
| 1454 |
1526 |
|
unsigned int mask; |
| 1455 |
1527 |
|
|
| 1456 |
|
- |
if (!sel) |
|
1528 |
+ |
if(!sel) |
| 1457 |
1529 |
|
return; |
| 1458 |
1530 |
|
|
| 1459 |
1531 |
|
mask = sel->tags ^ (arg->ui & TAGMASK); |
|
| 1505 |
1577 |
|
} |
| 1506 |
1578 |
|
|
| 1507 |
1579 |
|
void |
| 1508 |
|
- |
updatebar(void) { |
| 1509 |
|
- |
if(dc.drawable != 0) |
| 1510 |
|
- |
XFreePixmap(dpy, dc.drawable); |
| 1511 |
|
- |
dc.drawable = XCreatePixmap(dpy, root, selmon->ww, bh, DefaultDepth(dpy, screen)); |
| 1512 |
|
- |
XMoveResizeWindow(dpy, barwin, selmon->wx, by, selmon->ww, bh); |
| 1513 |
|
- |
} |
| 1514 |
|
- |
|
| 1515 |
|
- |
void |
| 1516 |
1580 |
|
updategeom(void) { |
| 1517 |
1581 |
|
#ifdef XINERAMA |
| 1518 |
1582 |
|
int di, x, y, n; |
|
| 1523 |
1587 |
|
XineramaScreenInfo *info = NULL; |
| 1524 |
1588 |
|
|
| 1525 |
1589 |
|
/* window area geometry */ |
| 1526 |
|
- |
if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { |
|
1590 |
+ |
if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { |
| 1527 |
1591 |
|
nmons = (unsigned int)n; |
| 1528 |
1592 |
|
for(c = clients; c; c = c->next) |
| 1529 |
1593 |
|
if(c->mon >= nmons) |
|
| 1533 |
1597 |
|
pquery = XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui); |
| 1534 |
1598 |
|
for(i = 0; i < nmons; i++) { |
| 1535 |
1599 |
|
/* TODO: consider re-using XineramaScreenInfo */ |
|
1600 |
+ |
mon[i].symbol[0] = '['; |
|
1601 |
+ |
mon[i].symbol[1] = '0' + info[i].screen_number; |
|
1602 |
+ |
mon[i].symbol[2] = ']'; |
|
1603 |
+ |
mon[i].symbol[3] = 0; |
|
1604 |
+ |
mon[i].showbar = showbar; |
|
1605 |
+ |
mon[i].topbar = topbar; |
| 1536 |
1606 |
|
mon[i].wx = info[i].x_org; |
| 1537 |
|
- |
mon[i].wy = info[i].y_org; |
|
1607 |
+ |
mon[i].wy = mon[i].showbar && mon[i].topbar ? info[i].y_org + bh : info[i].y_org; |
| 1538 |
1608 |
|
mon[i].ww = info[i].width; |
| 1539 |
|
- |
mon[i].wh = info[i].height; |
|
1609 |
+ |
mon[i].wh = mon[i].showbar ? info[i].height - bh : info[i].height; |
| 1540 |
1610 |
|
mon[i].seltags = 0; |
| 1541 |
1611 |
|
mon[i].sellt = 0; |
|
1612 |
+ |
if(mon[i].showbar) |
|
1613 |
+ |
mon[i].by = mon[i].topbar ? info[i].y_org : mon[i].wy + mon[i].wh; |
|
1614 |
+ |
else |
|
1615 |
+ |
mon[i].by = -bh; |
| 1542 |
1616 |
|
if(pquery && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) |
| 1543 |
1617 |
|
selmon = &mon[i]; |
| 1544 |
1618 |
|
} |
| 1545 |
|
- |
/* bar adjustments of selmon */ |
| 1546 |
|
- |
selmon->wy = showbar && topbar ? selmon->wy + bh : selmon->wy; |
| 1547 |
|
- |
selmon->wh = showbar ? selmon->wh - bh : selmon->wh; |
| 1548 |
1619 |
|
XFree(info); |
| 1549 |
1620 |
|
} |
| 1550 |
1621 |
|
else |
| 1551 |
|
- |
#endif |
|
1622 |
+ |
#endif /* XINERAMA */ |
| 1552 |
1623 |
|
{ |
| 1553 |
1624 |
|
nmons = 1; |
| 1554 |
1625 |
|
if(!(mon = (Monitor *)realloc(mon, sizeof(Monitor)))) |
| 1555 |
1626 |
|
die("fatal: could not realloc() %u bytes\n", sizeof(Monitor)); |
| 1556 |
1627 |
|
selmon = &mon[0]; |
|
1628 |
+ |
mon[0].symbol[0] = '['; |
|
1629 |
+ |
mon[0].symbol[1] = '0'; |
|
1630 |
+ |
mon[0].symbol[2] = ']'; |
|
1631 |
+ |
mon[0].symbol[3] = 0; |
|
1632 |
+ |
mon[0].showbar = showbar; |
|
1633 |
+ |
mon[0].topbar = topbar; |
| 1557 |
1634 |
|
mon[0].wx = sx; |
| 1558 |
|
- |
mon[0].wy = showbar && topbar ? sy + bh : sy; |
|
1635 |
+ |
mon[0].wy = mon[0].showbar && mon[0].topbar ? sy + bh : sy; |
| 1559 |
1636 |
|
mon[0].ww = sw; |
| 1560 |
|
- |
mon[0].wh = showbar ? sh - bh : sh; |
|
1637 |
+ |
mon[0].wh = mon[0].showbar ? sh - bh : sh; |
| 1561 |
1638 |
|
mon[0].seltags = 0; |
| 1562 |
1639 |
|
mon[0].sellt = 0; |
|
1640 |
+ |
if(mon[0].showbar) |
|
1641 |
+ |
mon[0].by = mon[0].topbar ? sy : mon[0].wy + mon[0].wh; |
|
1642 |
+ |
else |
|
1643 |
+ |
mon[0].by = -bh; |
| 1563 |
1644 |
|
} |
| 1564 |
|
- |
|
| 1565 |
|
- |
/* bar position */ |
| 1566 |
|
- |
by = showbar ? (topbar ? selmon->wy - bh : selmon->wy + selmon->wh) : -bh; |
| 1567 |
1645 |
|
} |
| 1568 |
1646 |
|
|
| 1569 |
1647 |
|
void |
|
| 1588 |
1666 |
|
|
| 1589 |
1667 |
|
if(!XGetWMNormalHints(dpy, c->win, &size, &msize)) |
| 1590 |
1668 |
|
/* size is uninitialized, ensure that size.flags aren't used */ |
| 1591 |
|
- |
size.flags = PSize; |
|
1669 |
+ |
size.flags = PSize; |
| 1592 |
1670 |
|
if(size.flags & PBaseSize) { |
| 1593 |
1671 |
|
c->basew = size.base_width; |
| 1594 |
1672 |
|
c->baseh = size.base_height; |
|
| 1641 |
1719 |
|
updatestatus() { |
| 1642 |
1720 |
|
if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) |
| 1643 |
1721 |
|
strcpy(stext, "dwm-"VERSION); |
| 1644 |
|
- |
drawbar(); |
|
1722 |
+ |
drawbar(selmon); |
| 1645 |
1723 |
|
} |
| 1646 |
1724 |
|
|
| 1647 |
1725 |
|
void |
|
| 1709 |
1787 |
|
|
| 1710 |
1788 |
|
if(!lt[selmon->sellt]->arrange || lt[selmon->sellt]->arrange == monocle || (sel && sel->isfloating)) |
| 1711 |
1789 |
|
return; |
| 1712 |
|
- |
if(c == nexttiled(clients)) |
| 1713 |
|
- |
if(!c || !(c = nexttiled(c->next))) |
|
1790 |
+ |
if(c == nexttiled(selmon, clients)) |
|
1791 |
+ |
if(!c || !(c = nexttiled(selmon, c->next))) |
| 1714 |
1792 |
|
return; |
| 1715 |
1793 |
|
detach(c); |
| 1716 |
1794 |
|
attach(c); |