| 117 |
117 |
|
} Regs; |
| 118 |
118 |
|
|
| 119 |
119 |
|
typedef struct { |
| 120 |
|
- |
int id; |
|
120 |
+ |
int screen; |
|
121 |
+ |
Window root; |
| 121 |
122 |
|
Window barwin; |
| 122 |
|
- |
//TODO: Window root; |
| 123 |
|
- |
//TODO: int screen; |
| 124 |
123 |
|
int sx, sy, sw, sh, wax, way, wah, waw; |
| 125 |
124 |
|
DC dc; |
| 126 |
125 |
|
Bool *seltags; |
|
| 158 |
157 |
|
void focusnext(const char *arg); |
| 159 |
158 |
|
void focusprev(const char *arg); |
| 160 |
159 |
|
Client *getclient(Window w); |
| 161 |
|
- |
unsigned long getcolor(const char *colstr); |
|
160 |
+ |
unsigned long getcolor(const char *colstr, int screen); |
| 162 |
161 |
|
long getstate(Window w); |
| 163 |
162 |
|
Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
| 164 |
163 |
|
void grabbuttons(Client *c, Bool focused); |
|
| 170 |
169 |
|
Bool isvisible(Client *c, Monitor *m); |
| 171 |
170 |
|
void keypress(XEvent *e); |
| 172 |
171 |
|
void killclient(const char *arg); |
| 173 |
|
- |
void leavenotify(XEvent *e); |
| 174 |
172 |
|
void manage(Window w, XWindowAttributes *wa); |
| 175 |
173 |
|
void mappingnotify(XEvent *e); |
| 176 |
174 |
|
void maprequest(XEvent *e); |
|
| 215 |
213 |
|
|
| 216 |
214 |
|
/* variables */ |
| 217 |
215 |
|
char stext[256]; |
| 218 |
|
- |
int mcount, screen; |
|
216 |
+ |
int mcount = 1; |
| 219 |
217 |
|
//double mwfact; |
| 220 |
|
- |
//int screen, sx, sy, sw, sh, wax, way, waw, wah; |
| 221 |
218 |
|
int (*xerrorxlib)(Display *, XErrorEvent *); |
| 222 |
219 |
|
unsigned int bh, bpos; |
| 223 |
220 |
|
unsigned int blw = 0; |
|
| 231 |
228 |
|
[Expose] = expose, |
| 232 |
229 |
|
[FocusIn] = focusin, |
| 233 |
230 |
|
[KeyPress] = keypress, |
| 234 |
|
- |
[LeaveNotify] = leavenotify, |
| 235 |
231 |
|
[MappingNotify] = mappingnotify, |
| 236 |
232 |
|
[MapRequest] = maprequest, |
| 237 |
233 |
|
[PropertyNotify] = propertynotify, |
|
| 242 |
238 |
|
Bool dozoom = True; |
| 243 |
239 |
|
Bool otherwm, readin; |
| 244 |
240 |
|
Bool running = True; |
| 245 |
|
- |
//Bool selscreen = True; |
| 246 |
241 |
|
Client *clients = NULL; |
| 247 |
242 |
|
Client *sel = NULL; |
| 248 |
243 |
|
Client *stack = NULL; |
| 249 |
244 |
|
Cursor cursor[CurLast]; |
| 250 |
245 |
|
Display *dpy; |
| 251 |
246 |
|
DC dc = {0}; |
| 252 |
|
- |
Window root; |
| 253 |
|
- |
//Layout *layout = NULL; |
| 254 |
|
- |
//Window barwin, root; |
| 255 |
247 |
|
Regs *regs = NULL; |
| 256 |
248 |
|
Monitor *monitors; |
| 257 |
249 |
|
int selmonitor = 0; |
|
| 402 |
394 |
|
XSetErrorHandler(xerrorstart); |
| 403 |
395 |
|
|
| 404 |
396 |
|
/* this causes an error if some other window manager is running */ |
| 405 |
|
- |
XSelectInput(dpy, root, SubstructureRedirectMask); |
|
397 |
+ |
XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); |
| 406 |
398 |
|
XSync(dpy, False); |
| 407 |
399 |
|
if(otherwm) |
| 408 |
400 |
|
eprint("dwm: another window manager is already running\n"); |
|
| 426 |
418 |
|
XFreeFontSet(dpy, m->dc.font.set); |
| 427 |
419 |
|
else |
| 428 |
420 |
|
XFreeFont(dpy, m->dc.font.xfont); |
| 429 |
|
- |
XUngrabKey(dpy, AnyKey, AnyModifier, root); |
|
421 |
+ |
XUngrabKey(dpy, AnyKey, AnyModifier, m->root); |
| 430 |
422 |
|
XFreePixmap(dpy, m->dc.drawable); |
| 431 |
423 |
|
XFreeGC(dpy, m->dc.gc); |
| 432 |
424 |
|
XDestroyWindow(dpy, m->barwin); |
|
| 487 |
479 |
|
XConfigureEvent *ev = &e->xconfigure; |
| 488 |
480 |
|
Monitor *m = &monitors[selmonitor]; |
| 489 |
481 |
|
|
| 490 |
|
- |
if(ev->window == root && (ev->width != m->sw || ev->height != m->sh)) { |
|
482 |
+ |
if(ev->window == m->root && (ev->width != m->sw || ev->height != m->sh)) { |
| 491 |
483 |
|
m->sw = ev->width; |
| 492 |
484 |
|
m->sh = ev->height; |
| 493 |
485 |
|
XFreePixmap(dpy, dc.drawable); |
| 494 |
|
- |
dc.drawable = XCreatePixmap(dpy, root, m->sw, bh, DefaultDepth(dpy, screen)); |
|
486 |
+ |
dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen)); |
| 495 |
487 |
|
XResizeWindow(dpy, m->barwin, m->sw, bh); |
| 496 |
488 |
|
updatebarpos(m); |
| 497 |
489 |
|
arrange(); |
|
| 582 |
574 |
|
m->dc.w = textw(m, tags[i]); |
| 583 |
575 |
|
if(m->seltags[i]) { |
| 584 |
576 |
|
drawtext(m, tags[i], m->dc.sel); |
| 585 |
|
- |
drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.sel); |
|
577 |
+ |
drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.sel); |
| 586 |
578 |
|
} |
| 587 |
579 |
|
else { |
| 588 |
580 |
|
drawtext(m, tags[i], m->dc.norm); |
| 589 |
|
- |
drawsquare(m, sel && sel->tags[i] && sel->monitor == m->id, isoccupied(m, i), m->dc.norm); |
|
581 |
+ |
drawsquare(m, sel && sel->tags[i] && sel->monitor == selmonitor, isoccupied(m, i), m->dc.norm); |
| 590 |
582 |
|
} |
| 591 |
583 |
|
m->dc.x += m->dc.w; |
| 592 |
584 |
|
} |
|
| 602 |
594 |
|
drawtext(m, stext, m->dc.norm); |
| 603 |
595 |
|
if((m->dc.w = m->dc.x - x) > bh) { |
| 604 |
596 |
|
m->dc.x = x; |
| 605 |
|
- |
if(sel && sel->monitor == m->id) { |
|
597 |
+ |
if(sel && sel->monitor == selmonitor) { |
| 606 |
598 |
|
drawtext(m, sel->name, m->dc.sel); |
| 607 |
599 |
|
drawsquare(m, False, sel->isfloating, m->dc.sel); |
| 608 |
600 |
|
} |
|
| 686 |
678 |
|
|
| 687 |
679 |
|
void |
| 688 |
680 |
|
enternotify(XEvent *e) { |
|
681 |
+ |
unsigned int i; |
| 689 |
682 |
|
Client *c; |
| 690 |
683 |
|
XCrossingEvent *ev = &e->xcrossing; |
| 691 |
684 |
|
|
|
| 693 |
686 |
|
return; |
| 694 |
687 |
|
if((c = getclient(ev->window))) |
| 695 |
688 |
|
focus(c); |
| 696 |
|
- |
else if(ev->window == root) { |
| 697 |
|
- |
selmonitor = True; |
| 698 |
|
- |
focus(NULL); |
|
689 |
+ |
else { |
|
690 |
+ |
for(i = 0; i < mcount; i++) |
|
691 |
+ |
if(ev->window == monitors[i].root) { |
|
692 |
+ |
selmonitor = i; |
|
693 |
+ |
focus(NULL); |
|
694 |
+ |
break; |
|
695 |
+ |
} |
| 699 |
696 |
|
} |
| 700 |
697 |
|
} |
| 701 |
698 |
|
|
|
| 731 |
728 |
|
|
| 732 |
729 |
|
void |
| 733 |
730 |
|
focus(Client *c) { |
| 734 |
|
- |
Monitor *m = &monitors[monitorat(-1, -1)]; |
|
731 |
+ |
Monitor *m = &monitors[c ? c->monitor : selmonitor]; |
| 735 |
732 |
|
if(!c || (c && !isvisible(c, m))) |
| 736 |
733 |
|
for(c = stack; c && !isvisible(c, m); c = c->snext); |
| 737 |
734 |
|
if(sel && sel != c) { |
|
| 746 |
743 |
|
sel = c; |
| 747 |
744 |
|
drawbar(); |
| 748 |
745 |
|
if(c) { |
| 749 |
|
- |
XSetWindowBorder(dpy, c->win, monitors[c->monitor].dc.sel[ColBorder]); |
|
746 |
+ |
XSetWindowBorder(dpy, c->win, m->dc.sel[ColBorder]); |
| 750 |
747 |
|
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
| 751 |
|
- |
selmonitor = monitorat(c->x, c->y); |
|
748 |
+ |
selmonitor = c->monitor; |
| 752 |
749 |
|
} |
| 753 |
750 |
|
else { |
| 754 |
|
- |
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
| 755 |
|
- |
selmonitor = monitorat(-1, -1); |
|
751 |
+ |
XSetInputFocus(dpy, m->root, RevertToPointerRoot, CurrentTime); |
| 756 |
752 |
|
} |
| 757 |
753 |
|
} |
| 758 |
754 |
|
|
|
| 807 |
803 |
|
} |
| 808 |
804 |
|
|
| 809 |
805 |
|
unsigned long |
| 810 |
|
- |
getcolor(const char *colstr) { |
|
806 |
+ |
getcolor(const char *colstr, int screen) { |
| 811 |
807 |
|
Colormap cmap = DefaultColormap(dpy, screen); |
| 812 |
808 |
|
XColor color; |
| 813 |
809 |
|
|
|
| 899 |
895 |
|
|
| 900 |
896 |
|
void |
| 901 |
897 |
|
grabkeys(void) { |
| 902 |
|
- |
unsigned int i; |
|
898 |
+ |
unsigned int i, j; |
| 903 |
899 |
|
KeyCode code; |
|
900 |
+ |
XModifierKeymap *modmap; |
| 904 |
901 |
|
|
| 905 |
|
- |
XUngrabKey(dpy, AnyKey, AnyModifier, root); |
| 906 |
|
- |
for(i = 0; i < LENGTH(keys); i++) { |
| 907 |
|
- |
code = XKeysymToKeycode(dpy, keys[i].keysym); |
| 908 |
|
- |
XGrabKey(dpy, code, keys[i].mod, root, True, |
| 909 |
|
- |
GrabModeAsync, GrabModeAsync); |
| 910 |
|
- |
XGrabKey(dpy, code, keys[i].mod | LockMask, root, True, |
| 911 |
|
- |
GrabModeAsync, GrabModeAsync); |
| 912 |
|
- |
XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True, |
| 913 |
|
- |
GrabModeAsync, GrabModeAsync); |
| 914 |
|
- |
XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True, |
| 915 |
|
- |
GrabModeAsync, GrabModeAsync); |
|
902 |
+ |
/* init modifier map */ |
|
903 |
+ |
modmap = XGetModifierMapping(dpy); |
|
904 |
+ |
for(i = 0; i < 8; i++) |
|
905 |
+ |
for(j = 0; j < modmap->max_keypermod; j++) { |
|
906 |
+ |
if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) |
|
907 |
+ |
numlockmask = (1 << i); |
|
908 |
+ |
} |
|
909 |
+ |
XFreeModifiermap(modmap); |
|
910 |
+ |
|
|
911 |
+ |
for(i = 0; i < mcount; i++) { |
|
912 |
+ |
Monitor *m = &monitors[i]; |
|
913 |
+ |
XUngrabKey(dpy, AnyKey, AnyModifier, m->root); |
|
914 |
+ |
for(j = 0; j < LENGTH(keys); j++) { |
|
915 |
+ |
code = XKeysymToKeycode(dpy, keys[j].keysym); |
|
916 |
+ |
XGrabKey(dpy, code, keys[j].mod, m->root, True, |
|
917 |
+ |
GrabModeAsync, GrabModeAsync); |
|
918 |
+ |
XGrabKey(dpy, code, keys[j].mod | LockMask, m->root, True, |
|
919 |
+ |
GrabModeAsync, GrabModeAsync); |
|
920 |
+ |
XGrabKey(dpy, code, keys[j].mod | numlockmask, m->root, True, |
|
921 |
+ |
GrabModeAsync, GrabModeAsync); |
|
922 |
+ |
XGrabKey(dpy, code, keys[j].mod | numlockmask | LockMask, m->root, True, |
|
923 |
+ |
GrabModeAsync, GrabModeAsync); |
|
924 |
+ |
} |
| 916 |
925 |
|
} |
| 917 |
926 |
|
} |
| 918 |
927 |
|
|
|
| 971 |
980 |
|
Client *c; |
| 972 |
981 |
|
|
| 973 |
982 |
|
for(c = clients; c; c = c->next) |
| 974 |
|
- |
if(c->tags[t] && c->monitor == m->id) |
|
983 |
+ |
if(c->tags[t] && c->monitor == selmonitor) |
| 975 |
984 |
|
return True; |
| 976 |
985 |
|
return False; |
| 977 |
986 |
|
} |
|
| 996 |
1005 |
|
unsigned int i; |
| 997 |
1006 |
|
|
| 998 |
1007 |
|
for(i = 0; i < LENGTH(tags); i++) |
| 999 |
|
- |
if(c->tags[i] && monitors[c->monitor].seltags[i] && m->id == c->monitor) |
|
1008 |
+ |
if(c->tags[i] && monitors[c->monitor].seltags[i] && c->monitor == selmonitor) |
| 1000 |
1009 |
|
return True; |
| 1001 |
1010 |
|
return False; |
| 1002 |
1011 |
|
} |
|
| 1038 |
1047 |
|
} |
| 1039 |
1048 |
|
|
| 1040 |
1049 |
|
void |
| 1041 |
|
- |
leavenotify(XEvent *e) { |
| 1042 |
|
- |
XCrossingEvent *ev = &e->xcrossing; |
| 1043 |
|
- |
|
| 1044 |
|
- |
if((ev->window == root) && !ev->same_screen) { |
| 1045 |
|
- |
selmonitor = False; |
| 1046 |
|
- |
focus(NULL); |
| 1047 |
|
- |
} |
| 1048 |
|
- |
} |
| 1049 |
|
- |
|
| 1050 |
|
- |
void |
| 1051 |
1050 |
|
manage(Window w, XWindowAttributes *wa) { |
| 1052 |
1051 |
|
Client *c, *t = NULL; |
|
1052 |
+ |
Monitor *m = &monitors[selmonitor]; |
|
1053 |
+ |
Status rettrans; |
| 1053 |
1054 |
|
Window trans; |
| 1054 |
|
- |
Status rettrans; |
| 1055 |
1055 |
|
XWindowChanges wc; |
| 1056 |
1056 |
|
|
| 1057 |
1057 |
|
c = emallocz(sizeof(Client)); |
|
| 1059 |
1059 |
|
c->win = w; |
| 1060 |
1060 |
|
|
| 1061 |
1061 |
|
applyrules(c); |
| 1062 |
|
- |
Monitor *m = &monitors[c->monitor]; |
| 1063 |
1062 |
|
|
| 1064 |
|
- |
c->x = wa->x+m->sx; |
| 1065 |
|
- |
c->y = wa->y+m->sy; |
|
1063 |
+ |
c->x = wa->x + m->sx; |
|
1064 |
+ |
c->y = wa->y + m->sy; |
| 1066 |
1065 |
|
c->w = wa->width; |
| 1067 |
1066 |
|
c->h = wa->height; |
| 1068 |
1067 |
|
c->oldborder = wa->border_width; |
|
| 1142 |
1141 |
|
|
| 1143 |
1142 |
|
ocx = nx = c->x; |
| 1144 |
1143 |
|
ocy = ny = c->y; |
| 1145 |
|
- |
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
1144 |
+ |
if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
| 1146 |
1145 |
|
None, cursor[CurMove], CurrentTime) != GrabSuccess) |
| 1147 |
1146 |
|
return; |
| 1148 |
|
- |
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); |
|
1147 |
+ |
XQueryPointer(dpy, monitors[selmonitor].root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); |
| 1149 |
1148 |
|
for(;;) { |
| 1150 |
1149 |
|
XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); |
| 1151 |
1150 |
|
switch (ev.type) { |
|
| 1232 |
1231 |
|
resize(Client *c, int x, int y, int w, int h, Bool sizehints) { |
| 1233 |
1232 |
|
XWindowChanges wc; |
| 1234 |
1233 |
|
Monitor scr = monitors[monitorat(x, y)]; |
| 1235 |
|
- |
c->monitor = scr.id; |
|
1234 |
+ |
c->monitor = monitorat(x, y); |
| 1236 |
1235 |
|
|
| 1237 |
1236 |
|
if(sizehints) { |
| 1238 |
1237 |
|
/* set minimum possible */ |
|
| 1305 |
1304 |
|
|
| 1306 |
1305 |
|
ocx = c->x; |
| 1307 |
1306 |
|
ocy = c->y; |
| 1308 |
|
- |
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
1307 |
+ |
if(XGrabPointer(dpy, monitors[selmonitor].root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
| 1309 |
1308 |
|
None, cursor[CurResize], CurrentTime) != GrabSuccess) |
| 1310 |
1309 |
|
return; |
| 1311 |
1310 |
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); |
|
| 1429 |
1428 |
|
|
| 1430 |
1429 |
|
void |
| 1431 |
1430 |
|
scan(void) { |
| 1432 |
|
- |
unsigned int i, num; |
|
1431 |
+ |
unsigned int i, j, num; |
| 1433 |
1432 |
|
Window *wins, d1, d2; |
| 1434 |
1433 |
|
XWindowAttributes wa; |
| 1435 |
1434 |
|
|
| 1436 |
|
- |
wins = NULL; |
| 1437 |
|
- |
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { |
| 1438 |
|
- |
for(i = 0; i < num; i++) { |
| 1439 |
|
- |
if(!XGetWindowAttributes(dpy, wins[i], &wa) |
| 1440 |
|
- |
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) |
| 1441 |
|
- |
continue; |
| 1442 |
|
- |
if(wa.map_state == IsViewable || getstate(wins[i]) == IconicState) |
| 1443 |
|
- |
manage(wins[i], &wa); |
|
1435 |
+ |
for(i = 0; i < mcount; i++) { |
|
1436 |
+ |
Monitor *m = &monitors[i]; |
|
1437 |
+ |
wins = NULL; |
|
1438 |
+ |
if(XQueryTree(dpy, m->root, &d1, &d2, &wins, &num)) { |
|
1439 |
+ |
for(j = 0; j < num; j++) { |
|
1440 |
+ |
if(!XGetWindowAttributes(dpy, wins[j], &wa) |
|
1441 |
+ |
|| wa.override_redirect || XGetTransientForHint(dpy, wins[j], &d1)) |
|
1442 |
+ |
continue; |
|
1443 |
+ |
if(wa.map_state == IsViewable || getstate(wins[j]) == IconicState) |
|
1444 |
+ |
manage(wins[j], &wa); |
|
1445 |
+ |
} |
|
1446 |
+ |
for(j = 0; j < num; j++) { /* now the transients */ |
|
1447 |
+ |
if(!XGetWindowAttributes(dpy, wins[j], &wa)) |
|
1448 |
+ |
continue; |
|
1449 |
+ |
if(XGetTransientForHint(dpy, wins[j], &d1) |
|
1450 |
+ |
&& (wa.map_state == IsViewable || getstate(wins[j]) == IconicState)) |
|
1451 |
+ |
manage(wins[j], &wa); |
|
1452 |
+ |
} |
| 1444 |
1453 |
|
} |
| 1445 |
|
- |
for(i = 0; i < num; i++) { /* now the transients */ |
| 1446 |
|
- |
if(!XGetWindowAttributes(dpy, wins[i], &wa)) |
| 1447 |
|
- |
continue; |
| 1448 |
|
- |
if(XGetTransientForHint(dpy, wins[i], &d1) |
| 1449 |
|
- |
&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) |
| 1450 |
|
- |
manage(wins[i], &wa); |
| 1451 |
|
- |
} |
|
1454 |
+ |
if(wins) |
|
1455 |
+ |
XFree(wins); |
| 1452 |
1456 |
|
} |
| 1453 |
|
- |
if(wins) |
| 1454 |
|
- |
XFree(wins); |
| 1455 |
1457 |
|
} |
| 1456 |
1458 |
|
|
| 1457 |
1459 |
|
void |
|
| 1513 |
1515 |
|
void |
| 1514 |
1516 |
|
setup(void) { |
| 1515 |
1517 |
|
unsigned int i, j, k; |
| 1516 |
|
- |
XModifierKeymap *modmap; |
|
1518 |
+ |
Monitor *m; |
| 1517 |
1519 |
|
XSetWindowAttributes wa; |
| 1518 |
|
- |
int s = 1; |
| 1519 |
|
- |
GC g; |
| 1520 |
1520 |
|
XineramaScreenInfo *info = NULL; |
| 1521 |
1521 |
|
|
| 1522 |
1522 |
|
/* init atoms */ |
|
| 1526 |
1526 |
|
wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); |
| 1527 |
1527 |
|
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); |
| 1528 |
1528 |
|
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); |
| 1529 |
|
- |
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, |
| 1530 |
|
- |
PropModeReplace, (unsigned char *) netatom, NetLast); |
| 1531 |
1529 |
|
|
| 1532 |
1530 |
|
/* init cursors */ |
| 1533 |
|
- |
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); |
|
1531 |
+ |
wa.cursor = cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); |
| 1534 |
1532 |
|
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); |
| 1535 |
1533 |
|
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); |
| 1536 |
1534 |
|
|
| 1537 |
|
- |
|
| 1538 |
|
- |
/* init modifier map */ |
| 1539 |
|
- |
modmap = XGetModifierMapping(dpy); |
| 1540 |
|
- |
for(i = 0; i < 8; i++) |
| 1541 |
|
- |
for(j = 0; j < modmap->max_keypermod; j++) { |
| 1542 |
|
- |
if(modmap->modifiermap[i * modmap->max_keypermod + j] |
| 1543 |
|
- |
== XKeysymToKeycode(dpy, XK_Num_Lock)) |
| 1544 |
|
- |
numlockmask = (1 << i); |
| 1545 |
|
- |
} |
| 1546 |
|
- |
XFreeModifiermap(modmap); |
| 1547 |
|
- |
|
| 1548 |
|
- |
/* select for events */ |
| 1549 |
|
- |
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
| 1550 |
|
- |
| EnterWindowMask | LeaveWindowMask | StructureNotifyMask; |
| 1551 |
|
- |
wa.cursor = cursor[CurNormal]; |
| 1552 |
|
- |
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); |
| 1553 |
|
- |
XSelectInput(dpy, root, wa.event_mask); |
| 1554 |
|
- |
|
| 1555 |
|
- |
/* grab keys */ |
| 1556 |
|
- |
grabkeys(); |
| 1557 |
|
- |
|
| 1558 |
|
- |
/* init tags */ |
| 1559 |
|
- |
compileregs(); |
| 1560 |
|
- |
|
|
1535 |
+ |
// init screens/monitors first |
| 1561 |
1536 |
|
if (XineramaIsActive(dpy)) { |
| 1562 |
|
- |
info = XineramaQueryScreens(dpy, &s); |
|
1537 |
+ |
info = XineramaQueryScreens(dpy, &mcount); |
| 1563 |
1538 |
|
} |
|
1539 |
+ |
mcount = 1; |
|
1540 |
+ |
monitors = emallocz(mcount * sizeof(Monitor)); |
| 1564 |
1541 |
|
|
| 1565 |
|
- |
monitors = emallocz(s*sizeof(Monitor)); |
| 1566 |
|
- |
mcount = s; |
|
1542 |
+ |
for(i = 0; i < mcount; i++) { |
|
1543 |
+ |
/* init geometry */ |
|
1544 |
+ |
m = &monitors[i]; |
| 1567 |
1545 |
|
|
| 1568 |
|
- |
for(i = 0; i < s; i++) { |
| 1569 |
|
- |
/* init geometry */ |
| 1570 |
|
- |
if (mcount != 1) { |
| 1571 |
|
- |
monitors[i].sx = info[i].x_org; |
| 1572 |
|
- |
monitors[i].sy = info[i].y_org; |
| 1573 |
|
- |
monitors[i].sw = info[i].width; |
| 1574 |
|
- |
monitors[i].sh = info[i].height; |
|
1546 |
+ |
m->screen = i; |
|
1547 |
+ |
m->root = RootWindow(dpy, i); |
|
1548 |
+ |
|
|
1549 |
+ |
if (mcount != 1) { // TODO: Xinerama |
|
1550 |
+ |
m->sx = info[i].x_org; |
|
1551 |
+ |
m->sy = info[i].y_org; |
|
1552 |
+ |
m->sw = info[i].width; |
|
1553 |
+ |
m->sh = info[i].height; |
| 1575 |
1554 |
|
} |
| 1576 |
1555 |
|
else { |
| 1577 |
|
- |
monitors[i].sx = 0; |
| 1578 |
|
- |
monitors[i].sy = 0; |
| 1579 |
|
- |
monitors[i].sw = DisplayWidth(dpy, screen); |
| 1580 |
|
- |
monitors[i].sh = DisplayHeight(dpy, screen); |
|
1556 |
+ |
m->sx = 0; |
|
1557 |
+ |
m->sy = 0; |
|
1558 |
+ |
m->sw = DisplayWidth(dpy, m->screen); |
|
1559 |
+ |
m->sh = DisplayHeight(dpy, m->screen); |
| 1581 |
1560 |
|
} |
| 1582 |
1561 |
|
|
| 1583 |
|
- |
monitors[i].id = i; |
| 1584 |
|
- |
monitors[i].seltags = emallocz(sizeof initags); |
| 1585 |
|
- |
monitors[i].prevtags = emallocz(sizeof initags); |
|
1562 |
+ |
m->seltags = emallocz(sizeof initags); |
|
1563 |
+ |
m->prevtags = emallocz(sizeof initags); |
| 1586 |
1564 |
|
|
| 1587 |
|
- |
memcpy(monitors[i].seltags, initags, sizeof initags); |
| 1588 |
|
- |
memcpy(monitors[i].prevtags, initags, sizeof initags); |
|
1565 |
+ |
memcpy(m->seltags, initags, sizeof initags); |
|
1566 |
+ |
memcpy(m->prevtags, initags, sizeof initags); |
| 1589 |
1567 |
|
|
| 1590 |
1568 |
|
/* init appearance */ |
| 1591 |
|
- |
monitors[i].dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); |
| 1592 |
|
- |
monitors[i].dc.norm[ColBG] = getcolor(NORMBGCOLOR); |
| 1593 |
|
- |
monitors[i].dc.norm[ColFG] = getcolor(NORMFGCOLOR); |
| 1594 |
|
- |
monitors[i].dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); |
| 1595 |
|
- |
monitors[i].dc.sel[ColBG] = getcolor(SELBGCOLOR); |
| 1596 |
|
- |
monitors[i].dc.sel[ColFG] = getcolor(SELFGCOLOR); |
| 1597 |
|
- |
initfont(&(monitors[i]), FONT); |
| 1598 |
|
- |
monitors[i].dc.h = bh = monitors[i].dc.font.height + 2; |
|
1569 |
+ |
m->dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR, i); |
|
1570 |
+ |
m->dc.norm[ColBG] = getcolor(NORMBGCOLOR, i); |
|
1571 |
+ |
m->dc.norm[ColFG] = getcolor(NORMFGCOLOR, i); |
|
1572 |
+ |
m->dc.sel[ColBorder] = getcolor(SELBORDERCOLOR, i); |
|
1573 |
+ |
m->dc.sel[ColBG] = getcolor(SELBGCOLOR, i); |
|
1574 |
+ |
m->dc.sel[ColFG] = getcolor(SELFGCOLOR, i); |
|
1575 |
+ |
initfont(m, FONT); |
|
1576 |
+ |
m->dc.h = bh = m->dc.font.height + 2; |
| 1599 |
1577 |
|
|
| 1600 |
1578 |
|
/* init layouts */ |
| 1601 |
|
- |
monitors[i].mwfact = MWFACT; |
| 1602 |
|
- |
monitors[i].layout = &layouts[0]; |
|
1579 |
+ |
m->mwfact = MWFACT; |
|
1580 |
+ |
m->layout = &layouts[0]; |
| 1603 |
1581 |
|
for(blw = k = 0; k < LENGTH(layouts); k++) { |
| 1604 |
|
- |
j = textw(&monitors[i], layouts[k].symbol); |
|
1582 |
+ |
j = textw(m, layouts[k].symbol); |
| 1605 |
1583 |
|
if(j > blw) |
| 1606 |
1584 |
|
blw = j; |
| 1607 |
1585 |
|
} |
| 1608 |
1586 |
|
|
|
1587 |
+ |
// TODO: bpos per screen? |
| 1609 |
1588 |
|
bpos = BARPOS; |
| 1610 |
1589 |
|
wa.override_redirect = 1; |
| 1611 |
1590 |
|
wa.background_pixmap = ParentRelative; |
| 1612 |
1591 |
|
wa.event_mask = ButtonPressMask | ExposureMask; |
| 1613 |
1592 |
|
|
| 1614 |
1593 |
|
/* init bars */ |
| 1615 |
|
- |
monitors[i].barwin = XCreateWindow(dpy, root, monitors[i].sx, monitors[i].sy, monitors[i].sw, bh, 0, |
| 1616 |
|
- |
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), |
|
1594 |
+ |
m->barwin = XCreateWindow(dpy, m->root, m->sx, m->sy, m->sw, bh, 0, |
|
1595 |
+ |
DefaultDepth(dpy, m->screen), CopyFromParent, DefaultVisual(dpy, m->screen), |
| 1617 |
1596 |
|
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
| 1618 |
|
- |
XDefineCursor(dpy, monitors[i].barwin, cursor[CurNormal]); |
| 1619 |
|
- |
updatebarpos(&monitors[i]); |
| 1620 |
|
- |
XMapRaised(dpy, monitors[i].barwin); |
|
1597 |
+ |
XDefineCursor(dpy, m->barwin, cursor[CurNormal]); |
|
1598 |
+ |
updatebarpos(m); |
|
1599 |
+ |
XMapRaised(dpy, m->barwin); |
| 1621 |
1600 |
|
strcpy(stext, "dwm-"VERSION); |
| 1622 |
|
- |
monitors[i].dc.drawable = XCreatePixmap(dpy, root, monitors[i].sw, bh, DefaultDepth(dpy, screen)); |
| 1623 |
|
- |
g = XCreateGC(dpy, root, 0, 0); |
| 1624 |
|
- |
monitors[i].dc.gc = XCreateGC(dpy, root, 0, 0); |
| 1625 |
|
- |
XSetLineAttributes(dpy, monitors[i].dc.gc, 1, LineSolid, CapButt, JoinMiter); |
| 1626 |
|
- |
if(!monitors[i].dc.font.set) |
| 1627 |
|
- |
XSetFont(dpy, monitors[i].dc.gc, monitors[i].dc.font.xfont->fid); |
|
1601 |
+ |
m->dc.drawable = XCreatePixmap(dpy, m->root, m->sw, bh, DefaultDepth(dpy, m->screen)); |
|
1602 |
+ |
m->dc.gc = XCreateGC(dpy, m->root, 0, 0); |
|
1603 |
+ |
XSetLineAttributes(dpy, m->dc.gc, 1, LineSolid, CapButt, JoinMiter); |
|
1604 |
+ |
if(!m->dc.font.set) |
|
1605 |
+ |
XSetFont(dpy, m->dc.gc, m->dc.font.xfont->fid); |
|
1606 |
+ |
|
|
1607 |
+ |
/* EWMH support per monitor */ |
|
1608 |
+ |
XChangeProperty(dpy, m->root, netatom[NetSupported], XA_ATOM, 32, |
|
1609 |
+ |
PropModeReplace, (unsigned char *) netatom, NetLast); |
|
1610 |
+ |
|
|
1611 |
+ |
/* select for events */ |
|
1612 |
+ |
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
|
1613 |
+ |
| EnterWindowMask | LeaveWindowMask | StructureNotifyMask; |
|
1614 |
+ |
XChangeWindowAttributes(dpy, m->root, CWEventMask | CWCursor, &wa); |
|
1615 |
+ |
XSelectInput(dpy, m->root, wa.event_mask); |
| 1628 |
1616 |
|
} |
|
1617 |
+ |
|
|
1618 |
+ |
/* grab keys */ |
|
1619 |
+ |
grabkeys(); |
|
1620 |
+ |
|
|
1621 |
+ |
/* init tags */ |
|
1622 |
+ |
compileregs(); |
| 1629 |
1623 |
|
} |
| 1630 |
1624 |
|
|
| 1631 |
1625 |
|
void |
|
| 1978 |
1972 |
|
monitorat(int x, int y) { |
| 1979 |
1973 |
|
int i; |
| 1980 |
1974 |
|
|
|
1975 |
+ |
return 0; |
| 1981 |
1976 |
|
if(!XineramaIsActive(dpy)) |
| 1982 |
1977 |
|
return 0; |
| 1983 |
1978 |
|
|
| 1984 |
1979 |
|
if (x < 0 || y < 0) { |
| 1985 |
1980 |
|
Window win; |
| 1986 |
1981 |
|
unsigned int mask; |
| 1987 |
|
- |
XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask); |
|
1982 |
+ |
XQueryPointer(dpy, DefaultRootWindow(dpy), &win, &win, &x, &y, &i, &i, &mask); |
| 1988 |
1983 |
|
} |
| 1989 |
1984 |
|
|
| 1990 |
|
- |
for(i = 0; i < mcount; i++) |
| 1991 |
|
- |
if((x < 0 || (x >= monitors[i].sx && x < monitors[i].sx + monitors[i].sw)) |
| 1992 |
|
- |
&& (y < 0 || (y >= monitors[i].sy && y < monitors[i].sy + monitors[i].sh))) |
|
1985 |
+ |
for(i = 0; i < mcount; i++) { |
|
1986 |
+ |
Monitor *m = &monitors[i]; |
|
1987 |
+ |
if((x < 0 || (x >= m->sx && x < m->sx + m->sw)) |
|
1988 |
+ |
&& (y < 0 || (y >= m->sy && y < m->sy + m->sh))) |
| 1993 |
1989 |
|
{ |
| 1994 |
1990 |
|
return i; |
| 1995 |
1991 |
|
} |
|
1992 |
+ |
} |
| 1996 |
1993 |
|
return 0; |
| 1997 |
1994 |
|
} |
| 1998 |
1995 |
|
|
|
| 2011 |
2008 |
|
selectmonitor(const char *arg) { |
| 2012 |
2009 |
|
Monitor *m = &monitors[arg ? atoi(arg) : (monitorat(-1, -1)+1) % mcount]; |
| 2013 |
2010 |
|
|
| 2014 |
|
- |
XWarpPointer(dpy, None, root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2); |
|
2011 |
+ |
XWarpPointer(dpy, None, m->root, 0, 0, 0, 0, m->wax+m->waw/2, m->way+m->wah/2); |
| 2015 |
2012 |
|
focus(NULL); |
| 2016 |
2013 |
|
} |
| 2017 |
2014 |
|
|
|
| 2020 |
2017 |
|
main(int argc, char *argv[]) { |
| 2021 |
2018 |
|
if(argc == 2 && !strcmp("-v", argv[1])) |
| 2022 |
2019 |
|
eprint("dwm-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, " |
| 2023 |
|
- |
"Jukka Salmi, Premysl Hruby, Szabolcs Nagy\n"); |
|
2020 |
+ |
"Jukka Salmi, Premysl Hruby, Szabolcs Nagy, Christof Musik\n"); |
| 2024 |
2021 |
|
else if(argc != 1) |
| 2025 |
2022 |
|
eprint("usage: dwm [-v]\n"); |
| 2026 |
2023 |
|
|
| 2027 |
2024 |
|
setlocale(LC_CTYPE, ""); |
| 2028 |
2025 |
|
if(!(dpy = XOpenDisplay(0))) |
| 2029 |
2026 |
|
eprint("dwm: cannot open display\n"); |
| 2030 |
|
- |
screen = DefaultScreen(dpy); |
| 2031 |
|
- |
root = RootWindow(dpy, screen); |
| 2032 |
2027 |
|
|
| 2033 |
2028 |
|
checkotherwm(); |
| 2034 |
2029 |
|
setup(); |