client.c
changeset 971 b2a0dfa22b1d
parent 970 d5c3537ee3be
child 974 408014d21261
equal deleted inserted replaced
970:d5c3537ee3be 971:b2a0dfa22b1d
     1 /* See LICENSE file for copyright and license details. */
     1 /* See LICENSE file for copyright and license details. */
     2 #include "dwm.h"
     2 #include "dwm.h"
     3 #include <stdlib.h>
     3 #include <stdlib.h>
     4 #include <string.h>
       
     5 #include <X11/Xatom.h>
     4 #include <X11/Xatom.h>
     6 #include <X11/Xutil.h>
     5 #include <X11/Xutil.h>
     7 
     6 
     8 /* static */
     7 /* static */
     9 
       
    10 static char buf[128];
       
    11 
     8 
    12 static void
     9 static void
    13 attachstack(Client *c) {
    10 attachstack(Client *c) {
    14 	c->snext = stack;
    11 	c->snext = stack;
    15 	stack = c;
    12 	stack = c;
   100 
    97 
   101 void
    98 void
   102 ban(Client *c) {
    99 ban(Client *c) {
   103 	if(c->isbanned)
   100 	if(c->isbanned)
   104 		return;
   101 		return;
   105 	XUnmapWindow(dpy, c->win);
   102 	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
   106 	setclientstate(c, IconicState);
       
   107 	c->isbanned = True;
   103 	c->isbanned = True;
   108 	c->unmapped++;
       
   109 }
   104 }
   110 
   105 
   111 void
   106 void
   112 configure(Client *c) {
   107 configure(Client *c) {
   113 	XConfigureEvent ce;
   108 	XConfigureEvent ce;
   177 		ev.xclient.data.l[1] = CurrentTime;
   172 		ev.xclient.data.l[1] = CurrentTime;
   178 		XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
   173 		XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
   179 	}
   174 	}
   180 	else
   175 	else
   181 		XKillClient(dpy, sel->win);
   176 		XKillClient(dpy, sel->win);
   182 }
       
   183 
       
   184 Bool
       
   185 getprops(Client *c) {
       
   186 	unsigned int i;
       
   187 	Bool result = False;
       
   188 
       
   189 	if(gettextprop(c->win, dwmprops, buf, sizeof buf)) {
       
   190 		for(i = 0; i < ntags && i < sizeof buf - 1 && buf[i] != '\0'; i++)
       
   191 			if((c->tags[i] = buf[i] == '1'))
       
   192 				result = True;
       
   193 		if(i < sizeof buf - 1 && buf[i] != '\0')
       
   194 			c->isfloating = buf[i] == '1';
       
   195 	}
       
   196 	return result;
       
   197 }
   177 }
   198 
   178 
   199 void
   179 void
   200 manage(Window w, XWindowAttributes *wa) {
   180 manage(Window w, XWindowAttributes *wa) {
   201 	unsigned int i;
   181 	unsigned int i;
   240 	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
   220 	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
   241 		for(t = clients; t && t->win != trans; t = t->next);
   221 		for(t = clients; t && t->win != trans; t = t->next);
   242 	if(t)
   222 	if(t)
   243 		for(i = 0; i < ntags; i++)
   223 		for(i = 0; i < ntags; i++)
   244 			c->tags[i] = t->tags[i];
   224 			c->tags[i] = t->tags[i];
   245 	if(!getprops(c))
   225 	applyrules(c);
   246 		applyrules(c);
       
   247 	if(!c->isfloating)
   226 	if(!c->isfloating)
   248 		c->isfloating = (rettrans == Success) || c->isfixed;
   227 		c->isfloating = (rettrans == Success) || c->isfixed;
   249 	setprops(c);
       
   250 	attach(c);
   228 	attach(c);
   251 	attachstack(c);
   229 	attachstack(c);
   252 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
   230 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
   253 	ban(c);
   231 	ban(c);
       
   232 	XMapWindow(dpy, c->win);
   254 	arrange();
   233 	arrange();
   255 }
   234 }
   256 
   235 
   257 void
   236 void
   258 resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
   237 resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
   316 		XSync(dpy, False);
   295 		XSync(dpy, False);
   317 	}
   296 	}
   318 }
   297 }
   319 
   298 
   320 void
   299 void
   321 setprops(Client *c) {
       
   322 	unsigned int i;
       
   323 
       
   324 	for(i = 0; i < ntags && i < sizeof buf - 1; i++)
       
   325 		buf[i] = c->tags[i] ? '1' : '0';
       
   326 	if(i < sizeof buf - 1)
       
   327 		buf[i++] = c->isfloating ? '1' : '0';
       
   328 	buf[i] = '\0';
       
   329 	XChangeProperty(dpy, c->win, dwmprops, XA_STRING, 8,
       
   330 			PropModeReplace, (unsigned char *)buf, i);
       
   331 }
       
   332 
       
   333 void
       
   334 unban(Client *c) {
   300 unban(Client *c) {
   335 	if(!c->isbanned)
   301 	if(!c->isbanned)
   336 		return;
   302 		return;
   337 	XMapWindow(dpy, c->win);
   303 	XMoveWindow(dpy, c->win, c->x, c->y);
   338 	setclientstate(c, NormalState);
       
   339 	c->isbanned = False;
   304 	c->isbanned = False;
   340 }
   305 }
   341 
   306 
   342 void
   307 void
   343 unmanage(Client *c, long state) {
   308 unmanage(Client *c) {
   344 	XWindowChanges wc;
   309 	XWindowChanges wc;
   345 
   310 
   346 	wc.border_width = c->oldborder;
   311 	wc.border_width = c->oldborder;
   347 	/* The server grab construct avoids race conditions. */
   312 	/* The server grab construct avoids race conditions. */
   348 	XGrabServer(dpy);
   313 	XGrabServer(dpy);
   351 	detach(c);
   316 	detach(c);
   352 	detachstack(c);
   317 	detachstack(c);
   353 	if(sel == c)
   318 	if(sel == c)
   354 		focus(NULL);
   319 		focus(NULL);
   355 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
   320 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
   356 	setclientstate(c, state);
   321 	setclientstate(c, WithdrawnState);
   357 	free(c->tags);
   322 	free(c->tags);
   358 	free(c);
   323 	free(c);
   359 	XSync(dpy, False);
   324 	XSync(dpy, False);
   360 	XSetErrorHandler(xerror);
   325 	XSetErrorHandler(xerror);
   361 	XUngrabServer(dpy);
   326 	XUngrabServer(dpy);
   362 	if(state != NormalState)
   327 	arrange();
   363 		arrange();
       
   364 }
   328 }
   365 
   329 
   366 void
   330 void
   367 updatesizehints(Client *c) {
   331 updatesizehints(Client *c) {
   368 	long msize;
   332 	long msize;