fixed several issues with focus handling via mouse, also added sending clients to the right monitor they belong to after mouse moves/resizals 176408af
Anselm R Garbe · 2009-06-27 18:39 1 file(s) · +79 −43
dwm.c +79 −43
166 166
static void detachstack(Client *c);
167 167
static void die(const char *errstr, ...);
168 168
static void drawbar(Monitor *m);
169 -
static void drawbars();
169 +
static void drawbars(void);
170 170
static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
171 171
static void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
172 172
static void enternotify(XEvent *e);
176 176
static void focusstack(const Arg *arg);
177 177
static Client *getclient(Window w);
178 178
static unsigned long getcolor(const char *colstr);
179 +
static Monitor *getmonitor(Window w);
180 +
static Monitor *getmonitorxy(int x, int y);
181 +
static Bool getrootpointer(int *x, int *y);
179 182
static long getstate(Window w);
180 183
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
181 184
static void grabbuttons(Client *c, Bool focused);
197 200
static void restack(Monitor *m);
198 201
static void run(void);
199 202
static void scan(void);
203 +
static void sendmon(Client *c, Monitor *m);
200 204
static void setclientstate(Client *c, long state);
201 205
static void setlayout(const Arg *arg);
202 206
static void setmfact(const Arg *arg);
397 401
398 402
	click = ClkRootWin;
399 403
	/* focus monitor if necessary */
400 -
	for(m = mons; m; m = m->next)
401 -
		if(ev->window == m->barwin) {
402 -
			if(m != selmon) {
403 -
				unfocus(selmon->stack);
404 -
				selmon = m;
405 -
				focus(NULL);
406 -
			}
407 -
			break;
408 -
		}
404 +
	if((m = getmonitor(ev->window)) && m != selmon) {
405 +
		unfocus(selmon->sel);
406 +
		selmon = m;
407 +
		focus(NULL);
408 +
	}
409 409
	if(ev->window == selmon->barwin && ev->x >= selmon->btx) {
410 410
		i = 0;
411 411
		x = selmon->btx;
683 683
}
684 684
685 685
void
686 -
drawbars() {
686 +
drawbars(void) {
687 687
	Monitor *m;
688 688
689 689
	for(m = mons; m; m = m->next)
742 742
void
743 743
enternotify(XEvent *e) {
744 744
	Client *c;
745 +
	Monitor *m;
745 746
	XCrossingEvent *ev = &e->xcrossing;
746 747
747 748
	if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
748 749
		return;
750 +
	if((m = getmonitor(ev->window)) && m != selmon) {
751 +
		unfocus(selmon->sel);
752 +
		selmon = m;
753 +
	}
749 754
	if((c = getclient(ev->window)))
750 755
		focus(c);
751 756
	else
757 762
	Monitor *m;
758 763
	XExposeEvent *ev = &e->xexpose;
759 764
760 -
	if(ev->count == 0)
761 -
		for(m = mons; m; m = m->next)
762 -
			if(ev->window == m->barwin) {
763 -
				drawbar(m);
764 -
				break;
765 -
			}
765 +
	if(ev->count == 0 && (m = getmonitor(ev->window)))
766 +
		drawbar(m);
766 767
}
767 768
768 769
void
809 810
			unfocus(selmon->sel);
810 811
			selmon = m;
811 812
			focus(NULL);
812 -
			drawbars();
813 813
			break;
814 814
		}
815 815
}
863 863
	return color.pixel;
864 864
}
865 865
866 +
Monitor *
867 +
getmonitor(Window w) {
868 +
	int x, y;
869 +
	Client *c;
870 +
	Monitor *m;
871 +
872 +
	if(w == root && getrootpointer(&x, &y))
873 +
		return getmonitorxy(x, y);
874 +
	for(m = mons; m; m = m->next)
875 +
		if(w == m->barwin)
876 +
			return m;
877 +
	if((c = getclient(w)))
878 +
		return c->mon;
879 +
	return NULL;
880 +
}
881 +
882 +
Monitor *
883 +
getmonitorxy(int x, int y) {
884 +
	Monitor *m;
885 +
886 +
	for(m = mons; m; m = m->next)
887 +
		if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh))
888 +
			return m;
889 +
	return NULL;
890 +
}
891 +
892 +
Bool
893 +
getrootpointer(int *x, int *y) {
894 +
	int di;
895 +
	unsigned int dui;
896 +
	Window dummy;
897 +
	return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
898 +
}
899 +
866 900
long
867 901
getstate(Window w) {
868 902
	int format, status;
1124 1158
1125 1159
void
1126 1160
movemouse(const Arg *arg) {
1127 -
	int x, y, ocx, ocy, di, nx, ny;
1128 -
	unsigned int dui;
1161 +
	int x, y, ocx, ocy, nx, ny;
1129 1162
	Client *c;
1130 -
	Window dummy;
1163 +
	Monitor *m;
1131 1164
	XEvent ev;
1132 1165
1133 1166
	if(!(c = selmon->sel))
1138 1171
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
1139 1172
	None, cursor[CurMove], CurrentTime) != GrabSuccess)
1140 1173
		return;
1141 -
	XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
1174 +
	if(!getrootpointer(&x, &y))
1175 +
		return;
1142 1176
	do {
1143 1177
		XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
1144 1178
		switch (ev.type) {
1171 1205
	}
1172 1206
	while(ev.type != ButtonRelease);
1173 1207
	XUngrabPointer(dpy, CurrentTime);
1208 +
	if((m = getmonitorxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon)
1209 +
		sendmon(c, m);
1174 1210
}
1175 1211
1176 1212
Client *
1239 1275
	int ocx, ocy;
1240 1276
	int nw, nh;
1241 1277
	Client *c;
1278 +
	Monitor *m;
1242 1279
	XEvent ev;
1243 1280
1244 1281
	if(!(c = selmon->sel))
1277 1314
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
1278 1315
	XUngrabPointer(dpy, CurrentTime);
1279 1316
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
1317 +
	if((m = getmonitorxy(c->x + c->w / 2, c->y + c->h / 2)) != selmon)
1318 +
		sendmon(c, m);
1280 1319
}
1281 1320
1282 1321
void
1342 1381
}
1343 1382
1344 1383
void
1384 +
sendmon(Client *c, Monitor *m) {
1385 +
	if(c->mon == m)
1386 +
		return;
1387 +
	detach(c);
1388 +
	detachstack(c);
1389 +
	c->mon = m;
1390 +
	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
1391 +
	attach(c);
1392 +
	attachstack(c);
1393 +
	focus(NULL);
1394 +
	arrange();
1395 +
}
1396 +
1397 +
void
1345 1398
setclientstate(Client *c, long state) {
1346 1399
	long data[] = {state, None};
1347 1400
1497 1550
		return;
1498 1551
	for(i = 0, m = mons; m; m = m->next, i++)
1499 1552
		if(i == arg->ui) {
1500 -
			detach(c);
1501 -
			detachstack(c);
1502 -
			c->mon = m;
1503 -
			c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
1504 -
			attach(c);
1505 -
			attachstack(c);
1506 -
			focus(NULL);
1507 -
			arrange();
1553 +
			sendmon(c, m);
1508 1554
			break;
1509 1555
		}
1510 1556
}
1676 1722
1677 1723
void
1678 1724
updategeom(void) {
1679 -
	int i, di, n = 1, x, y;
1680 -
	unsigned int dui;
1725 +
	int i, n = 1;
1681 1726
	Client *c;
1682 1727
	Monitor *newmons = NULL, *m, *tm;
1683 -
	Window dummy;
1684 1728
1685 1729
#ifdef XINULATOR
1686 1730
	n = 2;
1763 1807
		}
1764 1808
1765 1809
	/* select focused monitor */
1766 -
	selmon = newmons;
1767 -
	if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) 
1768 -
		for(m = newmons; m; m = m->next)
1769 -
			if(INRECT(x, y, m->wx, m->wy, m->ww, m->wh)) {
1770 -
				selmon = m;
1771 -
				break;
1772 -
			}
1773 -
1774 -
	/* final assignment of new monitors */
1775 1810
	cleanupmons();
1776 1811
	mons = newmons;
1812 +
	selmon = getmonitor(root);
1777 1813
}
1778 1814
1779 1815
void
1848 1884
}
1849 1885
1850 1886
void
1851 -
updatestatus() {
1887 +
updatestatus(void) {
1852 1888
	if(!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
1853 1889
		strcpy(stext, "dwm-"VERSION);
1854 1890
	drawbar(selmon);