implemented better fullscreen handling, please test 62d3caa9
Anselm R Garbe · 2010-05-30 10:02 1 file(s) · +75 −30
dwm.c +75 −30
57 57
/* enums */
58 58
enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
59 59
enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
60 -
enum { NetSupported, NetWMName, NetWMState, NetLast };  /* EWMH atoms */
60 +
enum { NetSupported, NetWMName, NetWMState,
61 +
       NetWMFullscreen, NetLast };                      /* EWMH atoms */
61 62
enum { WMProtocols, WMDelete, WMState, WMLast };        /* default atoms */
62 63
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
63 64
       ClkClientWin, ClkRootWin, ClkLast };             /* clicks */
83 84
	char name[256];
84 85
	float mina, maxa;
85 86
	int x, y, w, h;
87 +
	int oldx, oldy, oldw, oldh;
86 88
	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
87 89
	int bw, oldbw;
88 90
	unsigned int tags;
89 -
	Bool isfixed, isfloating, isurgent;
91 +
	Bool isfixed, isfloating, isurgent, oldstate;
90 92
	Client *next;
91 93
	Client *snext;
92 94
	Monitor *mon;
161 163
static void cleanup(void);
162 164
static void cleanupmon(Monitor *mon);
163 165
static void clearurgent(Client *c);
166 +
static void clientmessage(XEvent *e);
164 167
static void configure(Client *c);
165 168
static void configurenotify(XEvent *e);
166 169
static void configurerequest(XEvent *e);
200 203
static void propertynotify(XEvent *e);
201 204
static void quit(const Arg *arg);
202 205
static void resize(Client *c, int x, int y, int w, int h, Bool interact);
206 +
static void resizeclient(Client *c, int x, int y, int w, int h);
203 207
static void resizemouse(const Arg *arg);
204 208
static void restack(Monitor *m);
205 209
static void run(void);
220 224
static void togglefloating(const Arg *arg);
221 225
static void toggletag(const Arg *arg);
222 226
static void toggleview(const Arg *arg);
223 -
static void unfocus(Client *c);
227 +
static void unfocus(Client *c, Bool setfocus);
224 228
static void unmanage(Client *c, Bool destroyed);
225 229
static void unmapnotify(XEvent *e);
226 230
static Bool updategeom(void);
249 253
static unsigned int numlockmask = 0;
250 254
static void (*handler[LASTEvent]) (XEvent *) = {
251 255
	[ButtonPress] = buttonpress,
256 +
	[ClientMessage] = clientmessage,
252 257
	[ConfigureRequest] = configurerequest,
253 258
	[ConfigureNotify] = configurenotify,
254 259
	[DestroyNotify] = destroynotify,
423 428
	click = ClkRootWin;
424 429
	/* focus monitor if necessary */
425 430
	if((m = wintomon(ev->window)) && m != selmon) {
426 -
		unfocus(selmon->sel);
431 +
		unfocus(selmon->sel, True);
427 432
		selmon = m;
428 433
		focus(NULL);
429 434
	}
792 797
	if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
793 798
		return;
794 799
	if((m = wintomon(ev->window)) && m != selmon) {
795 -
		unfocus(selmon->sel);
800 +
		unfocus(selmon->sel, True);
796 801
		selmon = m;
797 802
	}
798 803
	if((c = wintoclient(ev->window)))
814 819
focus(Client *c) {
815 820
	if(!c || !ISVISIBLE(c))
816 821
		for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
817 -
	if(selmon->sel)
818 -
		unfocus(selmon->sel);
822 +
	/* was if(selmon->sel) */
823 +
	if(selmon->sel && selmon->sel != c)
824 +
		unfocus(selmon->sel, False);
819 825
	if(c) {
820 826
		if(c->mon != selmon)
821 827
			selmon = c->mon;
849 855
		return;
850 856
	if((m = dirtomon(arg->i)) == selmon)
851 857
		return;
852 -
	unfocus(selmon->sel);
858 +
	unfocus(selmon->sel, True);
853 859
	selmon = m;
854 860
	focus(NULL);
855 861
}
901 907
902 908
long
903 909
getstate(Window w) {
904 -
	int format, status;
910 +
	int format;
905 911
	long result = -1;
906 912
	unsigned char *p = NULL;
907 913
	unsigned long n, extra;
908 914
	Atom real;
909 915
910 -
	status = XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
911 -
	                            &real, &format, &n, &extra, (unsigned char **)&p);
912 -
	if(status != Success)
916 +
	if(XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
917 +
	                      &real, &format, &n, &extra, (unsigned char **)&p) != Success)
913 918
		return -1;
914 919
	if(n != 0)
915 920
		result = *p;
1110 1115
		applyrules(c);
1111 1116
	}
1112 1117
	/* geometry */
1113 -
	c->x = wa->x + c->mon->wx;
1114 -
	c->y = wa->y + c->mon->wy;
1115 -
	c->w = wa->width;
1116 -
	c->h = wa->height;
1118 +
	c->x = c->oldx = wa->x + c->mon->wx;
1119 +
	c->y = c->oldy = wa->y + c->mon->wy;
1120 +
	c->w = c->oldw = wa->width;
1121 +
	c->h = c->oldh = wa->height;
1117 1122
	c->oldbw = wa->border_width;
1118 1123
	if(c->w == c->mon->mw && c->h == c->mon->mh) {
1124 +
		c->isfloating = 1;
1119 1125
		c->x = c->mon->mx;
1120 1126
		c->y = c->mon->my;
1121 1127
		c->bw = 0;
1139 1145
	XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
1140 1146
	grabbuttons(c, False);
1141 1147
	if(!c->isfloating)
1142 -
		c->isfloating = trans != None || c->isfixed;
1148 +
		c->isfloating = c->oldstate = trans != None || c->isfixed;
1143 1149
	if(c->isfloating)
1144 1150
		XRaiseWindow(dpy, c->win);
1145 1151
	attach(c);
1292 1298
}
1293 1299
1294 1300
void
1301 +
clientmessage(XEvent *e) {
1302 +
	XClientMessageEvent *cme = &e->xclient;
1303 +
	Client *c;
1304 +
1305 +
	if((c = wintoclient(cme->window))
1306 +
	&& (cme->message_type == netatom[NetWMState] && cme->data.l[1] == netatom[NetWMFullscreen]))
1307 +
	{
1308 +
		if(cme->data.l[0]) {
1309 +
			XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
1310 +
			                PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
1311 +
			c->oldstate = c->isfloating;
1312 +
			c->oldbw = c->bw;
1313 +
			c->bw = 0;
1314 +
			c->isfloating = 1;
1315 +
			resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
1316 +
			XRaiseWindow(dpy, c->win);
1317 +
		}
1318 +
		else {
1319 +
			XChangeProperty(dpy, cme->window, netatom[NetWMState], XA_ATOM, 32,
1320 +
			                PropModeReplace, (unsigned char*)0, 0);
1321 +
			c->isfloating = c->oldstate;
1322 +
			c->bw = c->oldbw;
1323 +
			c->x = c->oldx;
1324 +
			c->y = c->oldy;
1325 +
			c->w = c->oldw;
1326 +
			c->h = c->oldh;
1327 +
			resizeclient(c, c->x, c->y, c->w, c->h);
1328 +
			arrange(c->mon);
1329 +
		}
1330 +
	}
1331 +
}
1332 +
1333 +
void
1295 1334
quit(const Arg *arg) {
1296 1335
	running = False;
1297 1336
}
1298 1337
1299 1338
void
1300 1339
resize(Client *c, int x, int y, int w, int h, Bool interact) {
1340 +
	if(applysizehints(c, &x, &y, &w, &h, interact))
1341 +
		resizeclient(c, x, y, w, h);
1342 +
}
1343 +
1344 +
void
1345 +
resizeclient(Client *c, int x, int y, int w, int h) {
1301 1346
	XWindowChanges wc;
1302 1347
1303 -
	if(applysizehints(c, &x, &y, &w, &h, interact)) {
1304 -
		c->x = wc.x = x;
1305 -
		c->y = wc.y = y;
1306 -
		c->w = wc.width = w;
1307 -
		c->h = wc.height = h;
1308 -
		wc.border_width = c->bw;
1309 -
		XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
1310 -
		configure(c);
1311 -
		XSync(dpy, False);
1312 -
	}
1348 +
	c->oldx = c->x; c->x = wc.x = x;
1349 +
	c->oldy = c->y; c->y = wc.y = y;
1350 +
	c->oldw = c->w; c->w = wc.width = w;
1351 +
	c->oldh = c->h; c->h = wc.height = h;
1352 +
	wc.border_width = c->bw;
1353 +
	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
1354 +
	configure(c);
1355 +
	XSync(dpy, False);
1313 1356
}
1314 1357
1315 1358
void
1427 1470
sendmon(Client *c, Monitor *m) {
1428 1471
	if(c->mon == m)
1429 1472
		return;
1430 -
	unfocus(c);
1473 +
	unfocus(c, True);
1431 1474
	detach(c);
1432 1475
	detachstack(c);
1433 1476
	c->mon = m;
1495 1538
	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
1496 1539
	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
1497 1540
	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
1541 +
	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
1498 1542
	/* init cursors */
1499 1543
	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
1500 1544
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
1663 1707
}
1664 1708
1665 1709
void
1666 -
unfocus(Client *c) {
1710 +
unfocus(Client *c, Bool setfocus) {
1667 1711
	if(!c)
1668 1712
		return;
1669 1713
	grabbuttons(c, False);
1670 1714
	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
1671 -
	XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
1715 +
	if(setfocus)
1716 +
		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
1672 1717
}
1673 1718
1674 1719
void