removed View cruft, now back to the roots f7c097e8
anselm@anselm1 · 2008-03-03 21:40 2 file(s) · +200 −348
config.def.h +0 −1
13 13
14 14
/* old */
15 15
const char tags[][MAXTAGLEN]     = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
16 -
unsigned int vtags[LENGTH(tags)] = {  0 ,  0 ,  0 ,  0 ,   0  ,  1 ,  1 ,  1 ,   1   };
17 16
18 17
Rule rules[] = {
19 18
	/* class:instance:title substr	tags ref	isfloating */
dwm.c +200 −347
40 40
#include <X11/Xlib.h>
41 41
#include <X11/Xproto.h>
42 42
#include <X11/Xutil.h>
43 -
//#ifdef XINERAMA
43 +
#ifdef XINERAMA
44 44
#include <X11/extensions/Xinerama.h>
45 -
//#endif
45 +
#endif
46 46
47 47
/* macros */
48 48
#define BUTTONMASK		(ButtonPressMask|ButtonReleaseMask)
60 60
enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
61 61
62 62
/* typedefs */
63 -
typedef struct View View;
64 63
typedef struct Client Client;
65 64
struct Client {
66 65
	char name[256];
101 100
102 101
typedef struct {
103 102
	const char *symbol;
104 -
	void (*arrange)(View *);
103 +
	void (*arrange)(void);
105 104
} Layout;
106 105
107 106
typedef struct {
110 109
	Bool isfloating;
111 110
} Rule;
112 111
113 -
struct View {
114 -
	unsigned int id;
115 -
	int x, y, w, h, wax, way, wah, waw;
116 -
	double mwfact;
117 -
	Layout *layout;
118 -
	Window barwin;
119 -
};
120 -
121 112
/* function declarations */
122 113
void applyrules(Client *c);
123 114
void arrange(void);
130 121
void configure(Client *c);
131 122
void configurenotify(XEvent *e);
132 123
void configurerequest(XEvent *e);
133 -
Bool conflicts(Client *c, unsigned int tidx);
134 124
void destroynotify(XEvent *e);
135 125
void detach(Client *c);
136 126
void detachstack(Client *c);
137 -
void drawbar(View *v);
127 +
void drawbar(void);
138 128
void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
139 129
void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
140 130
void *emallocz(unsigned int size);
141 131
void enternotify(XEvent *e);
142 132
void eprint(const char *errstr, ...);
143 133
void expose(XEvent *e);
144 -
unsigned int firstag(View *v);
145 -
void floating(View *v); /* default floating layout */
134 +
void floating(void); /* default floating layout */
146 135
void focus(Client *c);
147 136
void focusin(XEvent *e);
148 137
void focusnext(const char *arg);
149 138
void focusprev(const char *arg);
150 139
Client *getclient(Window w);
151 140
unsigned long getcolor(const char *colstr);
152 -
View *getview(Client *c);
153 -
View *getviewbar(Window barwin);
154 141
long getstate(Window w);
155 142
Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
156 143
void grabbuttons(Client *c, Bool focused);
166 153
void manage(Window w, XWindowAttributes *wa);
167 154
void mappingnotify(XEvent *e);
168 155
void maprequest(XEvent *e);
169 -
View *viewat(void);
170 156
void movemouse(Client *c);
171 -
Client *nexttiled(Client *c, View *v);
157 +
Client *nexttiled(Client *c);
172 158
void propertynotify(XEvent *e);
173 159
void quit(const char *arg);
174 160
void reapply(const char *arg);
175 161
void resize(Client *c, int x, int y, int w, int h, Bool sizehints);
176 162
void resizemouse(Client *c);
177 -
void restack(View *v);
163 +
void restack(void);
178 164
void run(void);
179 165
void scan(void);
180 166
void setclientstate(Client *c, long state);
185 171
void tag(const char *arg);
186 172
unsigned int textnw(const char *text, unsigned int len);
187 173
unsigned int textw(const char *text);
188 -
void tile(View *v);
174 +
void tile(void);
189 175
void togglebar(const char *arg);
190 176
void togglefloating(const char *arg);
191 177
void toggletag(const char *arg);
193 179
void unban(Client *c);
194 180
void unmanage(Client *c);
195 181
void unmapnotify(XEvent *e);
196 -
void updatebarpos(View *v);
182 +
void updatebarpos(void);
197 183
void updatesizehints(Client *c);
198 184
void updatetitle(Client *c);
199 185
void updatewmhints(Client *c);
207 193
208 194
/* variables */
209 195
char stext[256], buf[256];
210 -
int nviews = 1;
211 -
int screen;
196 +
double mwfact;
197 +
int screen, sx, sy, sw, sh, wax, way, waw, wah, xscreens;
212 198
int (*xerrorxlib)(Display *, XErrorEvent *);
213 199
unsigned int bh, bpos;
214 200
unsigned int blw = 0;
240 226
Cursor cursor[CurLast];
241 227
Display *dpy;
242 228
DC dc = {0};
243 -
View *views;
244 -
View *selview;
245 -
Window root;
229 +
Layout *lt;
230 +
Window root, barwin;
231 +
#ifdef XINERAMA
232 +
XineramaScreenInfo *info = NULL;
233 +
#endif
246 234
247 235
/* configuration, allows nested code to access above variables */
248 236
#include "config.h"
249 237
#define TAGSZ (LENGTH(tags) * sizeof(Bool))
238 +
static Bool tmp[LENGTH(tags)];
250 239
251 240
/* function implementations */
252 241
253 242
void
254 243
applyrules(Client *c) {
255 -
	unsigned int i, idx;
244 +
	unsigned int i;
256 245
	Bool matched = False;
257 246
	Rule *r;
258 247
	XClassHint ch = { 0 };
266 255
		|| (ch.res_name && strstr(ch.res_name, r->prop)))
267 256
		{
268 257
			c->isfloating = r->isfloating;
269 -
			if(r->tag && !conflicts(c, (idx = idxoftag(r->tag)))) {
270 -
				c->tags[idx] = True;
258 +
			if(r->tag) {
259 +
				c->tags[idxoftag(r->tag)] = True;
271 260
				matched = True;
272 261
			}
273 262
		}
276 265
		XFree(ch.res_class);
277 266
	if(ch.res_name)
278 267
		XFree(ch.res_name);
279 -
	if(!matched) {
280 -
		for(i = 0; i < LENGTH(tags); i++)
281 -
			if(seltags[i] && vtags[i] == selview->id)
282 -
				c->tags[i] = True;
283 -
	}
268 +
	if(!matched)
269 +
		memcpy(c->tags, seltags, TAGSZ);
284 270
}
285 271
286 272
void
287 273
arrange(void) {
288 -
	unsigned int i;
289 274
	Client *c;
290 275
291 276
	for(c = clients; c; c = c->next)
295 280
			ban(c);
296 281
297 282
	focus(NULL);
298 -
	for(i = 0; i < nviews; i++) {
299 -
		views[i].layout->arrange(&views[i]);
300 -
		restack(&views[i]);
301 -
	}
283 +
	lt->arrange();
284 +
	restack();
302 285
}
303 286
304 287
void
319 302
ban(Client *c) {
320 303
	if(c->isbanned)
321 304
		return;
322 -
	XMoveWindow(dpy, c->win, c->x + 3 * getview(c)->w, c->y);
305 +
	XMoveWindow(dpy, c->win, c->x + 3 * sw, c->y);
323 306
	c->isbanned = True;
324 307
}
325 308
329 312
	Client *c;
330 313
	XButtonPressedEvent *ev = &e->xbutton;
331 314
332 -
	if(ev->window == selview->barwin) {
315 +
	if(ev->window == barwin) {
333 316
		x = 0;
334 317
		for(i = 0; i < LENGTH(tags); i++) {
335 -
			if(&views[vtags[i]] != selview)
336 -
				continue;
337 318
			x += textw(tags[i]);
338 319
			if(ev->x < x) {
339 320
				if(ev->button == Button1) {
359 340
		if(CLEANMASK(ev->state) != MODKEY)
360 341
			return;
361 342
		if(ev->button == Button1) {
362 -
			restack(getview(c));
343 +
			restack();
363 344
			movemouse(c);
364 345
		}
365 346
		else if(ev->button == Button2) {
366 -
			if((floating != getview(c)->layout->arrange) && c->isfloating)
347 +
			if((floating != lt->arrange) && c->isfloating)
367 348
				togglefloating(NULL);
368 349
			else
369 350
				zoom(NULL);
370 351
		}
371 352
		else if(ev->button == Button3 && !c->isfixed) {
372 -
			restack(getview(c));
353 +
			restack();
373 354
			resizemouse(c);
374 355
		}
375 356
	}
393 374
394 375
void
395 376
cleanup(void) {
396 -
	unsigned int i;
397 377
398 378
	close(STDIN_FILENO);
399 379
	while(stack) {
411 391
	XFreeCursor(dpy, cursor[CurNormal]);
412 392
	XFreeCursor(dpy, cursor[CurResize]);
413 393
	XFreeCursor(dpy, cursor[CurMove]);
414 -
	for(i = 0; i < nviews; i++)
415 -
		XDestroyWindow(dpy, views[i].barwin);
394 +
	XDestroyWindow(dpy, barwin);
395 +
#if XINERAMA
396 +
	if(info)
397 +
		XFree(info);
398 +
#endif
416 399
	XSync(dpy, False);
417 400
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
418 401
}
438 421
void
439 422
configurenotify(XEvent *e) {
440 423
	XConfigureEvent *ev = &e->xconfigure;
441 -
	View *v = selview;
442 424
443 -
	if(ev->window == root && (ev->width != v->w || ev->height != v->h)) {
444 -
		/* TODO -- update Xinerama dimensions here */
445 -
		v->w = ev->width;
446 -
		v->h = ev->height;
425 +
	if(ev->window == root && (ev->width != sw || ev->height != sh)) {
426 +
		/* TODO -- use Xinerama dimensions here ? */
427 +
		sw = ev->width;
428 +
		sh = ev->height;
447 429
		XFreePixmap(dpy, dc.drawable);
448 430
		dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(root, screen), bh, DefaultDepth(dpy, screen));
449 -
		XResizeWindow(dpy, v->barwin, v->w, bh);
450 -
		updatebarpos(selview);
431 +
		XResizeWindow(dpy, barwin, sw, bh);
432 +
		updatebarpos();
451 433
		arrange();
452 434
	}
453 435
}
458 440
	XConfigureRequestEvent *ev = &e->xconfigurerequest;
459 441
	XWindowChanges wc;
460 442
443 +
	/* TODO -- consider Xinerama if necessary when centering */
461 444
	if((c = getclient(ev->window))) {
462 -
		View *v = getview(c);
463 445
		if(ev->value_mask & CWBorderWidth)
464 446
			c->border = ev->border_width;
465 -
		if(c->isfixed || c->isfloating || (floating == v->layout->arrange)) {
447 +
		if(c->isfixed || c->isfloating || (floating == lt->arrange)) {
466 448
			if(ev->value_mask & CWX)
467 -
				c->x = v->x + ev->x;
449 +
				c->x = sx + ev->x;
468 450
			if(ev->value_mask & CWY)
469 -
				c->y = v->y + ev->y;
451 +
				c->y = sy + ev->y;
470 452
			if(ev->value_mask & CWWidth)
471 453
				c->w = ev->width;
472 454
			if(ev->value_mask & CWHeight)
473 455
				c->h = ev->height;
474 -
			if((c->x - v->x + c->w) > v->w && c->isfloating)
475 -
				c->x = v->x + (v->w / 2 - c->w / 2); /* center in x direction */
476 -
			if((c->y - v->y + c->h) > v->h && c->isfloating)
477 -
				c->y = v->y + (v->h / 2 - c->h / 2); /* center in y direction */
456 +
			if((c->x - sx + c->w) > sw && c->isfloating)
457 +
				c->x = sx + (sw / 2 - c->w / 2); /* center in x direction */
458 +
			if((c->y - sy + c->h) > sh && c->isfloating)
459 +
				c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
478 460
			if((ev->value_mask & (CWX|CWY))
479 461
			&& !(ev->value_mask & (CWWidth|CWHeight)))
480 462
				configure(c);
502 484
	unsigned int i;
503 485
504 486
	for(i = 0; i < LENGTH(tags); i++)
505 -
		if(c->tags[i] && vtags[i] != vtags[tidx])
487 +
		if(c->tags[i])
506 488
			return True; /* conflict */
507 489
	return False;
508 490
}
536 518
}
537 519
538 520
void
539 -
drawbar(View *v) {
521 +
drawbar(void) {
540 522
	int i, x;
541 523
	Client *c;
542 524
543 525
	dc.x = 0;
544 -
	for(c = stack; c && (!isvisible(c) || getview(c) != v); c = c->snext);
526 +
	for(c = stack; c && !isvisible(c); c = c->snext);
545 527
	for(i = 0; i < LENGTH(tags); i++) {
546 -
		if(&views[vtags[i]] != v)
547 -
			continue;
548 528
		dc.w = textw(tags[i]);
549 529
		if(seltags[i]) {
550 530
			drawtext(tags[i], dc.sel, isurgent(i));
557 537
		dc.x += dc.w;
558 538
	}
559 539
	dc.w = blw;
560 -
	drawtext(v->layout->symbol, dc.norm, False);
540 +
	drawtext(lt->symbol, dc.norm, False);
561 541
	x = dc.x + dc.w;
562 -
	if(v == selview) {
563 -
		dc.w = textw(stext);
564 -
		dc.x = v->w - dc.w;
565 -
		if(dc.x < x) {
566 -
			dc.x = x;
567 -
			dc.w = v->w - x;
568 -
		}
569 -
		drawtext(stext, dc.norm, False);
542 +
	dc.w = textw(stext);
543 +
	dc.x = sw - dc.w;
544 +
	if(dc.x < x) {
545 +
		dc.x = x;
546 +
		dc.w = sw - x;
570 547
	}
571 -
	else
572 -
		dc.x = v->w;
548 +
	drawtext(stext, dc.norm, False);
573 549
	if((dc.w = dc.x - x) > bh) {
574 550
		dc.x = x;
575 551
		if(c) {
579 555
		else
580 556
			drawtext(NULL, dc.norm, False);
581 557
	}
582 -
	XCopyArea(dpy, dc.drawable, v->barwin, dc.gc, 0, 0, v->w, bh, 0, 0);
558 +
	XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
583 559
	XSync(dpy, False);
584 560
}
585 561
677 653
678 654
void
679 655
expose(XEvent *e) {
680 -
	View *v;
681 656
	XExposeEvent *ev = &e->xexpose;
682 657
683 -
	if(ev->count == 0 && ((v = getviewbar(ev->window))))
684 -
		drawbar(v);
685 -
}
686 -
687 -
unsigned int
688 -
firstag(View *v) {
689 -
	unsigned int i;
690 -
691 -
	for(i = 0; i < LENGTH(tags); i++)
692 -
		if(vtags[i] == v->id)
693 -
			return i;
694 -
	return 0; /* safe fallback */
658 +
	if(ev->count == 0 && (ev->window == barwin))
659 +
		drawbar();
695 660
}
696 661
697 662
void
698 -
floating(View *v) { /* default floating layout */
663 +
floating(void) { /* default floating layout */
699 664
	Client *c;
700 665
701 666
	domwfact = dozoom = False;
706 671
707 672
void
708 673
focus(Client *c) {
709 -
	View *v = selview;
710 -
711 -
	if(c)
712 -
		selview = getview(c);
713 -
	if(selview != v)
714 -
		drawbar(v);
715 674
	if(!c || (c && !isvisible(c)))
716 -
		/* TODO: isvisible might take getview(c) as constraint? */
717 -
		for(c = stack; c && (!isvisible(c) || getview(c) != selview); c = c->snext);
675 +
		for(c = stack; c && !isvisible(c); c = c->snext);
718 676
	if(sel && sel != c) {
719 677
		grabbuttons(sel, False);
720 678
		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
728 686
	if(c) {
729 687
		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
730 688
		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
731 -
		selview = getview(c);
732 689
	}
733 690
	else
734 691
		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
735 -
	drawbar(selview);
692 +
	drawbar();
736 693
}
737 694
738 695
void
754 711
		for(c = clients; c && !isvisible(c); c = c->next);
755 712
	if(c) {
756 713
		focus(c);
757 -
		restack(getview(c));
714 +
		restack();
758 715
	}
759 716
}
760 717
771 728
	}
772 729
	if(c) {
773 730
		focus(c);
774 -
		restack(getview(c));
731 +
		restack();
775 732
	}
776 733
}
777 734
793 750
	return color.pixel;
794 751
}
795 752
796 -
View *
797 -
getview(Client *c) {
798 -
	unsigned int i;
799 -
800 -
	for(i = 0; i < LENGTH(tags); i++)
801 -
		if(c->tags[i])
802 -
			return &views[vtags[i]];
803 -
	return NULL;
804 -
}
805 -
806 -
View *
807 -
getviewbar(Window barwin) {
808 -
	unsigned int i;
809 -
810 -
	for(i = 0; i < nviews; i++)
811 -
		if(views[i].barwin == barwin)
812 -
			return &views[i];
813 -
	return NULL;
814 -
}
815 -
816 753
long
817 754
getstate(Window w) {
818 755
	int format, status;
928 865
	unsigned int i;
929 866
930 867
	for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++);
931 -
	return (i < LENGTH(tags)) ? i : firstag(selview);
868 +
	return (i < LENGTH(tags)) ? i : 0;
932 869
}
933 870
934 871
void
1057 994
void
1058 995
manage(Window w, XWindowAttributes *wa) {
1059 996
	Client *c, *t = NULL;
1060 -
	View *v;
1061 997
	Status rettrans;
1062 998
	Window trans;
1063 999
	XWindowChanges wc;
1068 1004
1069 1005
	applyrules(c);
1070 1006
1071 -
	v = getview(c);
1072 -
1073 -
	c->x = wa->x + v->x;
1074 -
	c->y = wa->y + v->y;
1007 +
	c->x = wa->x + sx;
1008 +
	c->y = wa->y + sy;
1075 1009
	c->w = wa->width;
1076 1010
	c->h = wa->height;
1077 1011
	c->oldborder = wa->border_width;
1078 1012
1079 -
	if(c->w == v->w && c->h == v->h) {
1080 -
		c->x = v->x;
1081 -
		c->y = v->y;
1013 +
	if(c->w == sw && c->h == sh) {
1014 +
		c->x = sx;
1015 +
		c->y = sy;
1082 1016
		c->border = wa->border_width;
1083 1017
	}
1084 1018
	else {
1085 -
		if(c->x + c->w + 2 * c->border > v->wax + v->waw)
1086 -
			c->x = v->wax + v->waw - c->w - 2 * c->border;
1087 -
		if(c->y + c->h + 2 * c->border > v->way + v->wah)
1088 -
			c->y = v->way + v->wah - c->h - 2 * c->border;
1089 -
		if(c->x < v->wax)
1090 -
			c->x = v->wax;
1091 -
		if(c->y < v->way)
1092 -
			c->y = v->way;
1019 +
		if(c->x + c->w + 2 * c->border > wax + waw)
1020 +
			c->x = wax + waw - c->w - 2 * c->border;
1021 +
		if(c->y + c->h + 2 * c->border > way + wah)
1022 +
			c->y = way + wah - c->h - 2 * c->border;
1023 +
		if(c->x < wax)
1024 +
			c->x = wax;
1025 +
		if(c->y < way)
1026 +
			c->y = way;
1093 1027
		c->border = BORDERPX;
1094 1028
	}
1095 1029
	wc.border_width = c->border;
1141 1075
movemouse(Client *c) {
1142 1076
	int x1, y1, ocx, ocy, di, nx, ny;
1143 1077
	unsigned int dui;
1144 -
	View *v;
1145 1078
	Window dummy;
1146 1079
	XEvent ev;
1147 1080
1148 1081
	ocx = nx = c->x;
1149 1082
	ocy = ny = c->y;
1150 -
	v = getview(c);
1151 1083
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1152 1084
			None, cursor[CurMove], CurrentTime) != GrabSuccess)
1153 1085
		return;
1167 1099
			XSync(dpy, False);
1168 1100
			nx = ocx + (ev.xmotion.x - x1);
1169 1101
			ny = ocy + (ev.xmotion.y - y1);
1170 -
			if(abs(v->wax - nx) < SNAP)
1171 -
				nx = v->wax;
1172 -
			else if(abs((v->wax + v->waw) - (nx + c->w + 2 * c->border)) < SNAP)
1173 -
				nx = v->wax + v->waw - c->w - 2 * c->border;
1174 -
			if(abs(v->way - ny) < SNAP)
1175 -
				ny = v->way;
1176 -
			else if(abs((v->way + v->wah) - (ny + c->h + 2 * c->border)) < SNAP)
1177 -
				ny = v->way + v->wah - c->h - 2 * c->border;
1178 -
			if(!c->isfloating && (v->layout->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
1102 +
			if(abs(wax - nx) < SNAP)
1103 +
				nx = wax;
1104 +
			else if(abs((wax + waw) - (nx + c->w + 2 * c->border)) < SNAP)
1105 +
				nx = wax + waw - c->w - 2 * c->border;
1106 +
			if(abs(way - ny) < SNAP)
1107 +
				ny = way;
1108 +
			else if(abs((way + wah) - (ny + c->h + 2 * c->border)) < SNAP)
1109 +
				ny = way + wah - c->h - 2 * c->border;
1110 +
			if(!c->isfloating && (lt->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
1179 1111
				togglefloating(NULL);
1180 -
			if((v->layout->arrange == floating) || c->isfloating)
1112 +
			if((lt->arrange == floating) || c->isfloating)
1181 1113
				resize(c, nx, ny, c->w, c->h, False);
1182 1114
			break;
1183 1115
		}
1185 1117
}
1186 1118
1187 1119
Client *
1188 -
nexttiled(Client *c, View *v) {
1189 -
	for(; c && (c->isfloating || getview(c) != v || !isvisible(c)); c = c->next);
1120 +
nexttiled(Client *c) {
1121 +
	for(; c && (c->isfloating || !isvisible(c)); c = c->next);
1190 1122
	return c;
1191 1123
}
1192 1124
1211 1143
			break;
1212 1144
		case XA_WM_HINTS:
1213 1145
			updatewmhints(c);
1214 -
			drawbar(getview(c));
1146 +
			drawbar();
1215 1147
			break;
1216 1148
		}
1217 1149
		if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
1218 1150
			updatetitle(c);
1219 1151
			if(c == sel)
1220 -
				drawbar(selview);
1152 +
				drawbar();
1221 1153
		}
1222 1154
	}
1223 1155
}
1241 1173
1242 1174
void
1243 1175
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
1244 -
	View *v;
1245 1176
	XWindowChanges wc;
1246 1177
1247 -
	v = getview(c);
1248 1178
	if(sizehints) {
1249 1179
		/* set minimum possible */
1250 1180
		if (w < 1)
1285 1215
	}
1286 1216
	if(w <= 0 || h <= 0)
1287 1217
		return;
1288 -
	if(x > v->x + v->w)
1289 -
		x = v->w - w - 2 * c->border;
1290 -
	if(y > v->y + v->h)
1291 -
		y = v->h - h - 2 * c->border;
1292 -
	if(x + w + 2 * c->border < v->x)
1293 -
		x = v->x;
1294 -
	if(y + h + 2 * c->border < v->y)
1295 -
		y = v->y;
1218 +
	if(x > sx + sw)
1219 +
		x = sw - w - 2 * c->border;
1220 +
	if(y > sy + sh)
1221 +
		y = sh - h - 2 * c->border;
1222 +
	if(x + w + 2 * c->border < sx)
1223 +
		x = sx;
1224 +
	if(y + h + 2 * c->border < sy)
1225 +
		y = sy;
1296 1226
	if(c->x != x || c->y != y || c->w != w || c->h != h) {
1297 1227
		c->x = wc.x = x;
1298 1228
		c->y = wc.y = y;
1310 1240
resizemouse(Client *c) {
1311 1241
	int ocx, ocy;
1312 1242
	int nw, nh;
1313 -
	View *v;
1314 1243
	XEvent ev;
1315 1244
1316 1245
	ocx = c->x;
1317 1246
	ocy = c->y;
1318 -
	v = getview(c);
1319 1247
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1320 1248
			None, cursor[CurResize], CurrentTime) != GrabSuccess)
1321 1249
		return;
1340 1268
				nw = 1;
1341 1269
			if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0)
1342 1270
				nh = 1;
1343 -
			if(!c->isfloating && (v->layout->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
1271 +
			if(!c->isfloating && (lt->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
1344 1272
				togglefloating(NULL);
1345 -
			if((v->layout->arrange == floating) || c->isfloating)
1273 +
			if((lt->arrange == floating) || c->isfloating)
1346 1274
				resize(c, c->x, c->y, nw, nh, True);
1347 1275
			break;
1348 1276
		}
1350 1278
}
1351 1279
1352 1280
void
1353 -
restack(View *v) {
1281 +
restack(void) {
1354 1282
	Client *c;
1355 1283
	XEvent ev;
1356 1284
	XWindowChanges wc;
1357 1285
1358 -
	drawbar(v);
1286 +
	drawbar();
1359 1287
	if(!sel)
1360 1288
		return;
1361 -
	if(sel->isfloating || (v->layout->arrange == floating))
1289 +
	if(sel->isfloating || (lt->arrange == floating))
1362 1290
		XRaiseWindow(dpy, sel->win);
1363 -
	if(v->layout->arrange != floating) {
1291 +
	if(lt->arrange != floating) {
1364 1292
		wc.stack_mode = Below;
1365 -
		wc.sibling = v->barwin;
1293 +
		wc.sibling = barwin;
1366 1294
		if(!sel->isfloating) {
1367 1295
			XConfigureWindow(dpy, sel->win, CWSibling|CWStackMode, &wc);
1368 1296
			wc.sibling = sel->win;
1369 1297
		}
1370 -
		for(c = nexttiled(clients, v); c; c = nexttiled(c->next, v)) {
1298 +
		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
1371 1299
			if(c == sel)
1372 1300
				continue;
1373 1301
			XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
1428 1356
					}
1429 1357
				break;
1430 1358
			}
1431 -
			drawbar(selview);
1359 +
			drawbar();
1432 1360
		}
1433 1361
		while(XPending(dpy)) {
1434 1362
			XNextEvent(dpy, &ev);
1476 1404
void
1477 1405
setlayout(const char *arg) {
1478 1406
	unsigned int i;
1479 -
	View *v = selview;
1480 1407
1481 1408
	if(!arg) {
1482 -
		v->layout++;
1483 -
		if(v->layout == &layouts[LENGTH(layouts)])
1484 -
			v->layout = &layouts[0];
1409 +
		lt++;
1410 +
		if(lt == &layouts[LENGTH(layouts)])
1411 +
			lt = &layouts[0];
1485 1412
	}
1486 1413
	else {
1487 1414
		for(i = 0; i < LENGTH(layouts); i++)
1488 -
			if(!strcmp(arg, layouts[i].symbol))
1415 +
			if(arg == layouts[i].symbol)
1489 1416
				break;
1490 1417
		if(i == LENGTH(layouts))
1491 1418
			return;
1492 -
		v->layout = &layouts[i];
1419 +
		lt = &layouts[i];
1493 1420
	}
1494 1421
	if(sel)
1495 1422
		arrange();
1496 1423
	else
1497 -
		drawbar(selview);
1424 +
		drawbar();
1498 1425
}
1499 1426
1500 1427
void
1501 1428
setmwfact(const char *arg) {
1502 1429
	double delta;
1503 -
	View *v = selview;
1504 1430
1505 1431
	if(!domwfact)
1506 1432
		return;
1507 1433
	/* arg handling, manipulate mwfact */
1508 1434
	if(arg == NULL)
1509 -
		v->mwfact = MWFACT;
1435 +
		mwfact = MWFACT;
1510 1436
	else if(sscanf(arg, "%lf", &delta) == 1) {
1511 1437
		if(arg[0] == '+' || arg[0] == '-')
1512 -
			v->mwfact += delta;
1438 +
			mwfact += delta;
1513 1439
		else
1514 -
			v->mwfact = delta;
1515 -
		if(v->mwfact < 0.1)
1516 -
			v->mwfact = 0.1;
1517 -
		else if(v->mwfact > 0.9)
1518 -
			v->mwfact = 0.9;
1440 +
			mwfact = delta;
1441 +
		if(mwfact < 0.1)
1442 +
			mwfact = 0.1;
1443 +
		else if(mwfact > 0.9)
1444 +
			mwfact = 0.9;
1519 1445
	}
1520 1446
	arrange();
1521 1447
}
1522 1448
1523 1449
void
1524 1450
setup(void) {
1525 -
	unsigned int i, j;
1526 -
	View *v;
1451 +
	unsigned int i;
1527 1452
	XSetWindowAttributes wa;
1528 -
	XineramaScreenInfo *info = NULL;
1453 +
1454 +
	/* init screen */
1455 +
	screen = DefaultScreen(dpy);
1456 +
	root = RootWindow(dpy, screen);
1457 +
	sx = 0;
1458 +
	sy = 0;
1459 +
	sw = DisplayWidth(dpy, screen);
1460 +
	sh = DisplayHeight(dpy, screen);
1529 1461
1530 1462
	/* init atoms */
1531 1463
	wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
1540 1472
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
1541 1473
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
1542 1474
1475 +
#ifdef XINERAMA
1543 1476
	if(XineramaIsActive(dpy))
1544 -
		info = XineramaQueryScreens(dpy, &nviews);
1545 -
1546 -
#if defined(AIM_XINERAMA)
1547 -
nviews = 2; /* aim Xinerama */
1477 +
		info = XineramaQueryScreens(dpy, &xscreens);
1548 1478
#endif
1549 -
	views = emallocz(nviews * sizeof(View));
1550 -
1551 -
	screen = DefaultScreen(dpy);
1552 -
	root = RootWindow(dpy, screen);
1553 1479
1554 1480
	/* init appearance */
1555 1481
	dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
1566 1492
	if(!dc.font.set)
1567 1493
		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
1568 1494
1495 +
	/* init tags */
1496 +
	seltags = emallocz(TAGSZ);
1497 +
	prevtags = emallocz(TAGSZ);
1498 +
	seltags[0] = prevtags[0] = True;
1499 +
1500 +
	/* init layouts */
1501 +
	mwfact = MWFACT;
1502 +
	lt = &layouts[0];
1503 +
1504 +
	/* TODO: Xinerama hints ? */
1505 +
	/* init bar */
1569 1506
	for(blw = i = 0; i < LENGTH(layouts); i++) {
1570 1507
		i = textw(layouts[i].symbol);
1571 1508
		if(i > blw)
1572 1509
			blw = i;
1573 1510
	}
1574 1511
1575 -
	seltags = emallocz(TAGSZ);
1576 -
	prevtags = emallocz(TAGSZ);
1577 -
1578 -
	/* check, if vtags need assistance, because there is only 1 view */
1579 -
	if(nviews == 1)
1580 -
		for(i = 0; i < LENGTH(tags); i++)
1581 -
			vtags[i] = 0;
1582 -
1583 -
	for(i = 0; i < nviews; i++) {
1584 -
		/* init geometry */
1585 -
		v = &views[i];
1586 -
		v->id = i;
1587 -
1588 -
		/* select first tag of view */
1589 -
		j = firstag(v);
1590 -
		seltags[j] = prevtags[j] = True; 
1591 -
1592 -
		if(info) {
1593 -
1594 -
#if defined(AIM_XINERAMA)
1595 -
v->w = DisplayWidth(dpy, screen) / 2;
1596 -
v->x = (i == 0) ? 0 : v->w;
1597 -
v->y = 0;
1598 -
v->h = DisplayHeight(dpy, screen);
1599 -
#else
1600 -
			v->x = info[i].x_org;
1601 -
			v->y = info[i].y_org;
1602 -
			v->w = info[i].width;
1603 -
			v->h = info[i].height;
1604 -
#endif
1605 -
		}
1606 -
		else {
1607 -
			v->x = 0;
1608 -
			v->y = 0;
1609 -
			v->w = DisplayWidth(dpy, screen);
1610 -
			v->h = DisplayHeight(dpy, screen);
1611 -
		}
1612 -
1613 -
		/* init layouts */
1614 -
		v->mwfact = MWFACT;
1615 -
		v->layout = &layouts[0];
1512 +
	bpos = BARPOS;
1513 +
	wa.override_redirect = 1;
1514 +
	wa.background_pixmap = ParentRelative;
1515 +
	wa.event_mask = ButtonPressMask|ExposureMask;
1616 1516
1617 -
		// TODO: bpos per screen?
1618 -
		bpos = BARPOS;
1619 -
		wa.override_redirect = 1;
1620 -
		wa.background_pixmap = ParentRelative;
1621 -
		wa.event_mask = ButtonPressMask|ExposureMask;
1622 -
1623 -
		/* init bars */
1624 -
		v->barwin = XCreateWindow(dpy, root, v->x, v->y, v->w, bh, 0,
1625 -
				DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
1517 +
	barwin = XCreateWindow(dpy, root, sx, sy, sw, bh, 0, DefaultDepth(dpy, screen),
1518 +
				CopyFromParent, DefaultVisual(dpy, screen),
1626 1519
				CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
1627 -
		XDefineCursor(dpy, v->barwin, cursor[CurNormal]);
1628 -
		updatebarpos(v);
1629 -
		XMapRaised(dpy, v->barwin);
1630 -
		strcpy(stext, "dwm-"VERSION);
1520 +
	XDefineCursor(dpy, barwin, cursor[CurNormal]);
1521 +
	updatebarpos();
1522 +
	XMapRaised(dpy, barwin);
1523 +
	strcpy(stext, "dwm-"VERSION);
1524 +
	drawbar();
1631 1525
1632 -
		/* EWMH support per view */
1633 -
		XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
1634 -
				PropModeReplace, (unsigned char *) netatom, NetLast);
1526 +
	/* EWMH support per view */
1527 +
	XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
1528 +
			PropModeReplace, (unsigned char *) netatom, NetLast);
1635 1529
1636 -
		/* select for events */
1637 -
		wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
1638 -
				|EnterWindowMask|LeaveWindowMask|StructureNotifyMask;
1639 -
		XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
1640 -
		XSelectInput(dpy, root, wa.event_mask);
1530 +
	/* select for events */
1531 +
	wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
1532 +
			|EnterWindowMask|LeaveWindowMask|StructureNotifyMask;
1533 +
	XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
1534 +
	XSelectInput(dpy, root, wa.event_mask);
1641 1535
1642 -
		drawbar(v);
1643 -
	}
1644 -
	if(info)
1645 -
		XFree(info);
1646 -
1647 -
	selview = viewat();
1648 1536
1649 1537
	/* grab keys */
1650 1538
	grabkeys();
1681 1569
	if(!sel)
1682 1570
		return;
1683 1571
	for(i = 0; i < LENGTH(tags); i++)
1684 -
		sel->tags[i] = (NULL == arg) && (vtags[i] == getview(sel)->id);
1685 -
	i = idxoftag(arg);
1686 -
	if(!conflicts(sel, i))
1687 -
		sel->tags[idxoftag(arg)] = True;
1572 +
		sel->tags[i] = (NULL == arg);
1573 +
	sel->tags[idxoftag(arg)] = True;
1688 1574
	arrange();
1689 1575
}
1690 1576
1705 1591
}
1706 1592
1707 1593
void
1708 -
tile(View *v) {
1594 +
tile(void) {
1709 1595
	unsigned int i, n, nx, ny, nw, nh, mw, th;
1710 1596
	Client *c, *mc;
1711 1597
1712 1598
	domwfact = dozoom = True;
1713 -
	nx = v->wax;
1714 -
	ny = v->way;
1599 +
	nx = wax;
1600 +
	ny = way;
1715 1601
	nw = 0;
1716 -
	for(n = 0, c = nexttiled(clients, v); c; c = nexttiled(c->next, v))
1602 +
	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
1717 1603
		n++;
1718 1604
1719 1605
	/* window geoms */
1720 -
	mw = (n == 1) ? v->waw : v->mwfact * v->waw;
1721 -
	th = (n > 1) ? v->wah / (n - 1) : 0;
1606 +
	mw = (n == 1) ? waw : mwfact * waw;
1607 +
	th = (n > 1) ? wah / (n - 1) : 0;
1722 1608
	if(n > 1 && th < bh)
1723 -
		th = v->wah;
1609 +
		th = wah;
1724 1610
1725 -
	for(i = 0, c = mc = nexttiled(clients, v); c; c = nexttiled(c->next, v)) {
1611 +
	for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next)) {
1726 1612
		if(i == 0) { /* master */
1727 1613
			nw = mw - 2 * c->border;
1728 -
			nh = v->wah - 2 * c->border;
1614 +
			nh = wah - 2 * c->border;
1729 1615
		}
1730 1616
		else {  /* tile window */
1731 1617
			if(i == 1) {
1732 -
				ny = v->way;
1618 +
				ny = way;
1733 1619
				nx += mc->w + 2 * mc->border;
1734 -
				nw = v->waw - mw - 2 * c->border;
1620 +
				nw = waw - mw - 2 * c->border;
1735 1621
			}
1736 1622
			if(i + 1 == n) /* remainder */
1737 -
				nh = (v->way + v->wah) - ny - 2 * c->border;
1623 +
				nh = (way + wah) - ny - 2 * c->border;
1738 1624
			else
1739 1625
				nh = th - 2 * c->border;
1740 1626
		}
1742 1628
		if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw)))
1743 1629
			/* client doesn't accept size constraints */
1744 1630
			resize(c, nx, ny, nw, nh, False);
1745 -
		if(n > 1 && th != v->wah)
1631 +
		if(n > 1 && th != wah)
1746 1632
			ny = c->y + c->h + 2 * c->border;
1747 1633
		i++;
1748 1634
	}
1754 1640
		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
1755 1641
	else
1756 1642
		bpos = BarOff;
1757 -
	updatebarpos(selview);
1643 +
	updatebarpos();
1758 1644
	arrange();
1759 1645
}
1760 1646
1837 1723
}
1838 1724
1839 1725
void
1840 -
updatebarpos(View *v) {
1726 +
updatebarpos(void) {
1841 1727
	XEvent ev;
1842 1728
1843 -
	v->wax = v->x;
1844 -
	v->way = v->y;
1845 -
	v->wah = v->h;
1846 -
	v->waw = v->w;
1729 +
	wax = sx;
1730 +
	way = sy;
1731 +
	wah = sh;
1732 +
	waw = sw;
1847 1733
	switch(bpos) {
1848 1734
	default:
1849 -
		v->wah -= bh;
1850 -
		v->way += bh;
1851 -
		XMoveWindow(dpy, v->barwin, v->x, v->y);
1735 +
		wah -= bh;
1736 +
		way += bh;
1737 +
		XMoveWindow(dpy, barwin, sx, sy);
1852 1738
		break;
1853 1739
	case BarBot:
1854 -
		v->wah -= bh;
1855 -
		XMoveWindow(dpy, v->barwin, v->x, v->y + v->wah);
1740 +
		wah -= bh;
1741 +
		XMoveWindow(dpy, barwin, sx, sy + wah);
1856 1742
		break;
1857 1743
	case BarOff:
1858 -
		XMoveWindow(dpy, v->barwin, v->x, v->y - bh);
1744 +
		XMoveWindow(dpy, barwin, sx, sy - bh);
1859 1745
		break;
1860 1746
	}
1861 1747
	XSync(dpy, False);
1930 1816
	}
1931 1817
}
1932 1818
1819 +
1933 1820
void
1934 1821
view(const char *arg) {
1935 -
	unsigned int i, j;
1936 -
	Bool tmp[LENGTH(tags)];
1822 +
	unsigned int i;
1937 1823
1938 -
	memcpy(tmp, seltags, TAGSZ);
1939 -
	if(arg == NULL) {
1940 -
		for(i = 0; i < LENGTH(tags); i++)
1941 -
			tmp[i] = (vtags[i] == selview->id);
1942 -
	}
1943 -
	else {
1944 -
		i = idxoftag(arg);
1945 -
		for(j = 0; j < LENGTH(tags); j++)
1946 -
			if(selview->id == vtags[i]) {
1947 -
				/* view tag of selview */
1948 -
				if(selview->id == vtags[j])
1949 -
					tmp[j] = False;
1950 -
			}
1951 -
			else {
1952 -
				/* only touch the view the focus should go */
1953 -
				if(vtags[j] == vtags[i])
1954 -
					tmp[j] = False;
1955 -
			}
1956 -
		selview = &views[vtags[i]];
1957 -
		tmp[i] = True;
1958 -
	}
1824 +
	for(i = 0; i < LENGTH(tags); i++)
1825 +
		tmp[i] = (NULL == arg);
1826 +
	tmp[idxoftag(arg)] = True;
1827 +
1959 1828
	if(memcmp(seltags, tmp, TAGSZ) != 0) {
1960 1829
		memcpy(prevtags, seltags, TAGSZ);
1961 1830
		memcpy(seltags, tmp, TAGSZ);
1963 1832
	}
1964 1833
}
1965 1834
1966 -
View *
1967 -
viewat() {
1968 -
	int i, x, y;
1969 -
	Window win;
1970 -
	unsigned int mask;
1971 -
1972 -
	XQueryPointer(dpy, root, &win, &win, &x, &y, &i, &i, &mask);
1973 -
	for(i = 0; i < nviews; i++) {
1974 -
		if((x >= views[i].x && x < views[i].x + views[i].w)
1975 -
		&& (y >= views[i].y && y < views[i].y + views[i].h))
1976 -
			return &views[i];
1977 -
	}
1978 -
	return NULL;
1979 -
}
1980 -
1981 1835
void
1982 1836
viewprevtag(const char *arg) {
1983 -
	static Bool tmp[LENGTH(tags)];
1984 1837
1985 1838
	memcpy(tmp, seltags, TAGSZ);
1986 1839
	memcpy(seltags, prevtags, TAGSZ);
2026 1879
2027 1880
	if(!sel || !dozoom || sel->isfloating)
2028 1881
		return;
2029 -
	if(c == nexttiled(clients, getview(c)))
2030 -
		if(!(c = nexttiled(c->next, getview(c))))
1882 +
	if(c == nexttiled(clients))
1883 +
		if(!(c = nexttiled(c->next)))
2031 1884
			return;
2032 1885
	detach(c);
2033 1886
	attach(c);