client.c
changeset 31 386649deb651
parent 30 2e0fb4130bfb
child 32 082c75b937b5
equal deleted inserted replaced
30:2e0fb4130bfb 31:386649deb651
     8 #include <string.h>
     8 #include <string.h>
     9 #include <X11/Xatom.h>
     9 #include <X11/Xatom.h>
    10 
    10 
    11 #include "util.h"
    11 #include "util.h"
    12 #include "wm.h"
    12 #include "wm.h"
       
    13 
       
    14 void (*arrange)(void *aux);
    13 
    15 
    14 void
    16 void
    15 max(void *aux)
    17 max(void *aux)
    16 {
    18 {
    17 	if(!stack)
    19 	if(!stack)
    23 	resize(stack);
    25 	resize(stack);
    24 	discard_events(EnterWindowMask);
    26 	discard_events(EnterWindowMask);
    25 }
    27 }
    26 
    28 
    27 void
    29 void
    28 arrange(void *aux)
    30 floating(void *aux)
       
    31 {
       
    32 	Client *c;
       
    33 
       
    34 	arrange = floating;
       
    35 	for(c = stack; c; c = c->snext)
       
    36 		resize(c);
       
    37 	discard_events(EnterWindowMask);
       
    38 }
       
    39 
       
    40 void
       
    41 grid(void *aux)
    29 {
    42 {
    30 	Client *c;
    43 	Client *c;
    31 	int n, cols, rows, gw, gh, i, j;
    44 	int n, cols, rows, gw, gh, i, j;
    32     float rt, fd;
    45     float rt, fd;
    33 
    46 
       
    47 	arrange = grid;
    34 	if(!clients)
    48 	if(!clients)
    35 		return;
    49 		return;
    36 	for(n = 0, c = clients; c; c = c->next, n++);
    50 	for(n = 0, c = clients; c; c = c->next, n++);
    37 	rt = sqrt(n);
    51 	rt = sqrt(n);
    38 	if(modff(rt, &fd) < 0.5)
    52 	if(modff(rt, &fd) < 0.5)
    93 }
   107 }
    94 
   108 
    95 static void
   109 static void
    96 resize_title(Client *c)
   110 resize_title(Client *c)
    97 {
   111 {
    98 	c->tw = textw(&brush.font, c->name) + bh;
   112 	int i;
       
   113 
       
   114 	c->tw = 0;
       
   115 	for(i = 0; i < TLast; i++)
       
   116 		if(c->tags[i])
       
   117 			c->tw += textw(&brush.font, c->tags[i]) + bh;
       
   118 	c->tw += textw(&brush.font, c->name) + bh;
    99 	if(c->tw > c->w)
   119 	if(c->tw > c->w)
   100 		c->tw = c->w + 2;
   120 		c->tw = c->w + 2;
   101 	c->tx = c->x + c->w - c->tw + 2;
   121 	c->tx = c->x + c->w - c->tw + 2;
   102 	c->ty = c->y;
   122 	c->ty = c->y;
   103 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
   123 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
   188 {
   208 {
   189 	Client **l, *old;
   209 	Client **l, *old;
   190 
   210 
   191 	old = stack;
   211 	old = stack;
   192 	for(l = &stack; *l && *l != c; l = &(*l)->snext);
   212 	for(l = &stack; *l && *l != c; l = &(*l)->snext);
   193 	eassert(*l == c);
   213 	if(*l)
   194 	*l = c->snext;
   214 		*l = c->snext;
   195 	c->snext = stack;
   215 	c->snext = stack;
   196 	stack = c;
   216 	stack = c;
   197 	if(old && old != c) {
   217 	if(old && old != c) {
   198 		XMapWindow(dpy, old->title);
   218 		XMapWindow(dpy, old->title);
   199 		draw_client(old);
   219 		draw_client(old);
   228 	XGetTransientForHint(dpy, c->win, &c->trans);
   248 	XGetTransientForHint(dpy, c->win, &c->trans);
   229 	twa.override_redirect = 1;
   249 	twa.override_redirect = 1;
   230 	twa.background_pixmap = ParentRelative;
   250 	twa.background_pixmap = ParentRelative;
   231 	twa.event_mask = ExposureMask;
   251 	twa.event_mask = ExposureMask;
   232 
   252 
       
   253 	c->tags[tsel] = tags[tsel];
   233 	c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
   254 	c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
   234 			0, DefaultDepth(dpy, screen), CopyFromParent,
   255 			0, DefaultDepth(dpy, screen), CopyFromParent,
   235 			DefaultVisual(dpy, screen),
   256 			DefaultVisual(dpy, screen),
   236 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
   257 			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
       
   258 
   237 	update_name(c);
   259 	update_name(c);
   238 
       
   239 	for(l=&clients; *l; l=&(*l)->next);
   260 	for(l=&clients; *l; l=&(*l)->next);
   240 	c->next = *l; /* *l == nil */
   261 	c->next = *l; /* *l == nil */
   241 	*l = c;
   262 	*l = c;
   242 	c->snext = stack;
       
   243 	stack = c;
       
   244 	XMapRaised(dpy, c->win);
   263 	XMapRaised(dpy, c->win);
   245 	XMapRaised(dpy, c->title);
   264 	XMapRaised(dpy, c->title);
   246 	XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
   265 	XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
   247 			GrabModeAsync, GrabModeSync, None, None);
   266 			GrabModeAsync, GrabModeSync, None, None);
   248 	XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
   267 	XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
   249 			GrabModeAsync, GrabModeSync, None, None);
   268 			GrabModeAsync, GrabModeSync, None, None);
   250 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   269 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   251 			GrabModeAsync, GrabModeSync, None, None);
   270 			GrabModeAsync, GrabModeSync, None, None);
   252 	resize(c);
   271 	arrange(NULL);
   253 	focus(c);
   272 	focus(c);
   254 }
   273 }
   255 
   274 
   256 void
   275 void
   257 gravitate(Client *c, Bool invert)
   276 gravitate(Client *c, Bool invert)
   306 	}
   325 	}
   307 	c->x += dx;
   326 	c->x += dx;
   308 	c->y += dy;
   327 	c->y += dy;
   309 }
   328 }
   310 
   329 
       
   330 
   311 void
   331 void
   312 resize(Client *c)
   332 resize(Client *c)
   313 {
   333 {
   314 	XConfigureEvent e;
   334 	XConfigureEvent e;
   315 
   335 
       
   336 	if(c->incw)
       
   337 		c->w -= (c->w - c->basew) % c->incw;
       
   338 	if(c->inch)
       
   339 		c->h -= (c->h - c->baseh) % c->inch;
       
   340 	if(c->minw && c->w < c->minw)
       
   341 		c->w = c->minw;
       
   342 	if(c->minh && c->h < c->minh)
       
   343 		c->h = c->minh;
       
   344 	if(c->maxw && c->w > c->maxw)
       
   345 		c->w = c->maxw;
       
   346 	if(c->maxh && c->h > c->maxh)
       
   347 		c->h = c->maxh;
   316 	resize_title(c);
   348 	resize_title(c);
   317 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   349 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   318 	e.type = ConfigureNotify;
   350 	e.type = ConfigureNotify;
   319 	e.event = c->win;
   351 	e.event = c->win;
   320 	e.window = c->win;
   352 	e.window = c->win;
   355 	free(c);
   387 	free(c);
   356 
   388 
   357 	XFlush(dpy);
   389 	XFlush(dpy);
   358 	XSetErrorHandler(error_handler);
   390 	XSetErrorHandler(error_handler);
   359 	XUngrabServer(dpy);
   391 	XUngrabServer(dpy);
       
   392 	arrange(NULL);
   360 	if(stack)
   393 	if(stack)
   361 		focus(stack);
   394 		focus(stack);
   362 }
   395 }
   363 
   396 
   364 Client *
   397 Client *
   382 }
   415 }
   383 
   416 
   384 void
   417 void
   385 draw_client(Client *c)
   418 draw_client(Client *c)
   386 {
   419 {
       
   420 	int i;
   387 	if(c == stack) {
   421 	if(c == stack) {
   388 		draw_bar();
   422 		draw_bar();
   389 		return;
   423 		return;
   390 	}
   424 	}
   391 
   425 
   392 	brush.x = brush.y = 0;
   426 	brush.x = brush.y = 0;
   393 	brush.w = c->tw;
       
   394 	brush.h = c->th;
   427 	brush.h = c->th;
   395 
   428 
       
   429 	brush.w = 0;
       
   430 	for(i = 0; i < TLast; i++) {
       
   431 		if(c->tags[i]) {
       
   432 			brush.x += brush.w;
       
   433 			brush.w = textw(&brush.font, c->tags[i]) + bh;
       
   434 			draw(dpy, &brush, True, c->tags[i]);
       
   435 		}
       
   436 	}
       
   437 	brush.x += brush.w;
       
   438 	brush.w = textw(&brush.font, c->name) + bh;
   396 	draw(dpy, &brush, True, c->name);
   439 	draw(dpy, &brush, True, c->name);
   397 	XCopyArea(dpy, brush.drawable, c->title, brush.gc,
   440 	XCopyArea(dpy, brush.drawable, c->title, brush.gc,
   398 			0, 0, c->tw, c->th, 0, 0);
   441 			0, 0, c->tw, c->th, 0, 0);
   399 	XFlush(dpy);
   442 	XFlush(dpy);
   400 }
   443 }