proceeded with cleaning up, sorting functions, etc
This commit is contained in:
		
							parent
							
								
									dba23062ba
								
							
						
					
					
						commit
						adaa28a6e6
					
				
							
								
								
									
										423
									
								
								client.c
								
								
								
								
							
							
						
						
									
										423
									
								
								client.c
								
								
								
								
							| 
						 | 
					@ -2,21 +2,14 @@
 | 
				
			||||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
					 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <X11/Xatom.h>
 | 
					#include <X11/Xatom.h>
 | 
				
			||||||
#include <X11/Xutil.h>
 | 
					#include <X11/Xutil.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					/* static functions */
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
ban(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
 | 
					 | 
				
			||||||
	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
resizetitle(Client *c)
 | 
					resizetitle(Client *c)
 | 
				
			||||||
| 
						 | 
					@ -35,84 +28,19 @@ resizetitle(Client *c)
 | 
				
			||||||
	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
 | 
						XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					static int
 | 
				
			||||||
settitle(Client *c)
 | 
					xerrordummy(Display *dsply, XErrorEvent *ee)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	XTextProperty name;
 | 
						return 0;
 | 
				
			||||||
	int n;
 | 
					 | 
				
			||||||
	char **list = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name.nitems = 0;
 | 
					 | 
				
			||||||
	c->name[0] = 0;
 | 
					 | 
				
			||||||
	XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
 | 
					 | 
				
			||||||
	if(!name.nitems)
 | 
					 | 
				
			||||||
		XGetWMName(dpy, c->win, &name);
 | 
					 | 
				
			||||||
	if(!name.nitems)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	if(name.encoding == XA_STRING)
 | 
					 | 
				
			||||||
		strncpy(c->name, (char *)name.value, sizeof(c->name));
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
 | 
					 | 
				
			||||||
				&& n > 0 && *list)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			strncpy(c->name, *list, sizeof(c->name));
 | 
					 | 
				
			||||||
			XFreeStringList(list);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	XFree(name.value);
 | 
					 | 
				
			||||||
	resizetitle(c);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					/* extern functions */
 | 
				
			||||||
setsize(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XSizeHints size;
 | 
					 | 
				
			||||||
	long msize;
 | 
					 | 
				
			||||||
	if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
 | 
					 | 
				
			||||||
		size.flags = PSize;
 | 
					 | 
				
			||||||
	c->flags = size.flags;
 | 
					 | 
				
			||||||
	if(c->flags & PBaseSize) {
 | 
					 | 
				
			||||||
		c->basew = size.base_width;
 | 
					 | 
				
			||||||
		c->baseh = size.base_height;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		c->basew = c->baseh = 0;
 | 
					 | 
				
			||||||
	if(c->flags & PResizeInc) {
 | 
					 | 
				
			||||||
		c->incw = size.width_inc;
 | 
					 | 
				
			||||||
		c->inch = size.height_inc;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		c->incw = c->inch = 0;
 | 
					 | 
				
			||||||
	if(c->flags & PMaxSize) {
 | 
					 | 
				
			||||||
		c->maxw = size.max_width;
 | 
					 | 
				
			||||||
		c->maxh = size.max_height;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		c->maxw = c->maxh = 0;
 | 
					 | 
				
			||||||
	if(c->flags & PMinSize) {
 | 
					 | 
				
			||||||
		c->minw = size.min_width;
 | 
					 | 
				
			||||||
		c->minh = size.min_height;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		c->minw = c->minh = 0;
 | 
					 | 
				
			||||||
	if(c->flags & PWinGravity)
 | 
					 | 
				
			||||||
		c->grav = size.win_gravity;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		c->grav = NorthWestGravity;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
higher(Client *c)
 | 
					ban(Client *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	XRaiseWindow(dpy, c->win);
 | 
						XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
 | 
				
			||||||
	XRaiseWindow(dpy, c->title);
 | 
						XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
lower(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XLowerWindow(dpy, c->title);
 | 
					 | 
				
			||||||
	XLowerWindow(dpy, c->win);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -131,6 +59,137 @@ focus(Client *c)
 | 
				
			||||||
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 | 
						while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					focusnext(Arg *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
						if(!sel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!(c = getnext(sel->next)))
 | 
				
			||||||
 | 
							c = getnext(clients);
 | 
				
			||||||
 | 
						if(c) {
 | 
				
			||||||
 | 
							higher(c);
 | 
				
			||||||
 | 
							c->revert = sel;
 | 
				
			||||||
 | 
							focus(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					focusprev(Arg *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!sel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
 | 
				
			||||||
 | 
							higher(c);
 | 
				
			||||||
 | 
							focus(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client *
 | 
				
			||||||
 | 
					getclient(Window w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
						for(c = clients; c; c = c->next)
 | 
				
			||||||
 | 
							if(c->win == w)
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client *
 | 
				
			||||||
 | 
					getctitle(Window w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Client *c;
 | 
				
			||||||
 | 
						for(c = clients; c; c = c->next)
 | 
				
			||||||
 | 
							if(c->title == w)
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					gravitate(Client *c, Bool invert)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int dx = 0, dy = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(c->grav) {
 | 
				
			||||||
 | 
						case StaticGravity:
 | 
				
			||||||
 | 
						case NorthWestGravity:
 | 
				
			||||||
 | 
						case NorthGravity:
 | 
				
			||||||
 | 
						case NorthEastGravity:
 | 
				
			||||||
 | 
							dy = c->border;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case EastGravity:
 | 
				
			||||||
 | 
						case CenterGravity:
 | 
				
			||||||
 | 
						case WestGravity:
 | 
				
			||||||
 | 
							dy = -(c->h / 2) + c->border;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SouthEastGravity:
 | 
				
			||||||
 | 
						case SouthGravity:
 | 
				
			||||||
 | 
						case SouthWestGravity:
 | 
				
			||||||
 | 
							dy = -c->h;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (c->grav) {
 | 
				
			||||||
 | 
						case StaticGravity:
 | 
				
			||||||
 | 
						case NorthWestGravity:
 | 
				
			||||||
 | 
						case WestGravity:
 | 
				
			||||||
 | 
						case SouthWestGravity:
 | 
				
			||||||
 | 
							dx = c->border;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NorthGravity:
 | 
				
			||||||
 | 
						case CenterGravity:
 | 
				
			||||||
 | 
						case SouthGravity:
 | 
				
			||||||
 | 
							dx = -(c->w / 2) + c->border;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case NorthEastGravity:
 | 
				
			||||||
 | 
						case EastGravity:
 | 
				
			||||||
 | 
						case SouthEastGravity:
 | 
				
			||||||
 | 
							dx = -(c->w + c->border);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(invert) {
 | 
				
			||||||
 | 
							dx = -dx;
 | 
				
			||||||
 | 
							dy = -dy;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c->x += dx;
 | 
				
			||||||
 | 
						c->y += dy;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					higher(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XRaiseWindow(dpy, c->win);
 | 
				
			||||||
 | 
						XRaiseWindow(dpy, c->title);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					killclient(Arg *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(!sel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if(sel->proto & WM_PROTOCOL_DELWIN)
 | 
				
			||||||
 | 
							sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							XKillClient(dpy, sel->win);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					lower(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XLowerWindow(dpy, c->title);
 | 
				
			||||||
 | 
						XLowerWindow(dpy, c->win);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
manage(Window w, XWindowAttributes *wa)
 | 
					manage(Window w, XWindowAttributes *wa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -195,61 +254,18 @@ manage(Window w, XWindowAttributes *wa)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
gravitate(Client *c, Bool invert)
 | 
					maximize(Arg *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int dx = 0, dy = 0;
 | 
						if(!sel)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
	switch(c->grav) {
 | 
						sel->x = sx;
 | 
				
			||||||
	case StaticGravity:
 | 
						sel->y = sy + bh;
 | 
				
			||||||
	case NorthWestGravity:
 | 
						sel->w = sw - 2 * sel->border;
 | 
				
			||||||
	case NorthGravity:
 | 
						sel->h = sh - 2 * sel->border - bh;
 | 
				
			||||||
	case NorthEastGravity:
 | 
						higher(sel);
 | 
				
			||||||
		dy = c->border;
 | 
						resize(sel, False);
 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case EastGravity:
 | 
					 | 
				
			||||||
	case CenterGravity:
 | 
					 | 
				
			||||||
	case WestGravity:
 | 
					 | 
				
			||||||
		dy = -(c->h / 2) + c->border;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SouthEastGravity:
 | 
					 | 
				
			||||||
	case SouthGravity:
 | 
					 | 
				
			||||||
	case SouthWestGravity:
 | 
					 | 
				
			||||||
		dy = -c->h;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (c->grav) {
 | 
					 | 
				
			||||||
	case StaticGravity:
 | 
					 | 
				
			||||||
	case NorthWestGravity:
 | 
					 | 
				
			||||||
	case WestGravity:
 | 
					 | 
				
			||||||
	case SouthWestGravity:
 | 
					 | 
				
			||||||
		dx = c->border;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case NorthGravity:
 | 
					 | 
				
			||||||
	case CenterGravity:
 | 
					 | 
				
			||||||
	case SouthGravity:
 | 
					 | 
				
			||||||
		dx = -(c->w / 2) + c->border;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case NorthEastGravity:
 | 
					 | 
				
			||||||
	case EastGravity:
 | 
					 | 
				
			||||||
	case SouthEastGravity:
 | 
					 | 
				
			||||||
		dx = -(c->w + c->border);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(invert) {
 | 
					 | 
				
			||||||
		dx = -dx;
 | 
					 | 
				
			||||||
		dy = -dy;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c->x += dx;
 | 
					 | 
				
			||||||
	c->y += dy;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
resize(Client *c, Bool inc)
 | 
					resize(Client *c, Bool inc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -290,10 +306,70 @@ resize(Client *c, Bool inc)
 | 
				
			||||||
	XFlush(dpy);
 | 
						XFlush(dpy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					void
 | 
				
			||||||
xerrordummy(Display *dsply, XErrorEvent *ee)
 | 
					setsize(Client *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 0;
 | 
						XSizeHints size;
 | 
				
			||||||
 | 
						long msize;
 | 
				
			||||||
 | 
						if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
 | 
				
			||||||
 | 
							size.flags = PSize;
 | 
				
			||||||
 | 
						c->flags = size.flags;
 | 
				
			||||||
 | 
						if(c->flags & PBaseSize) {
 | 
				
			||||||
 | 
							c->basew = size.base_width;
 | 
				
			||||||
 | 
							c->baseh = size.base_height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							c->basew = c->baseh = 0;
 | 
				
			||||||
 | 
						if(c->flags & PResizeInc) {
 | 
				
			||||||
 | 
							c->incw = size.width_inc;
 | 
				
			||||||
 | 
							c->inch = size.height_inc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							c->incw = c->inch = 0;
 | 
				
			||||||
 | 
						if(c->flags & PMaxSize) {
 | 
				
			||||||
 | 
							c->maxw = size.max_width;
 | 
				
			||||||
 | 
							c->maxh = size.max_height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							c->maxw = c->maxh = 0;
 | 
				
			||||||
 | 
						if(c->flags & PMinSize) {
 | 
				
			||||||
 | 
							c->minw = size.min_width;
 | 
				
			||||||
 | 
							c->minh = size.min_height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							c->minw = c->minh = 0;
 | 
				
			||||||
 | 
						if(c->flags & PWinGravity)
 | 
				
			||||||
 | 
							c->grav = size.win_gravity;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							c->grav = NorthWestGravity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					settitle(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XTextProperty name;
 | 
				
			||||||
 | 
						int n;
 | 
				
			||||||
 | 
						char **list = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name.nitems = 0;
 | 
				
			||||||
 | 
						c->name[0] = 0;
 | 
				
			||||||
 | 
						XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
 | 
				
			||||||
 | 
						if(!name.nitems)
 | 
				
			||||||
 | 
							XGetWMName(dpy, c->win, &name);
 | 
				
			||||||
 | 
						if(!name.nitems)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if(name.encoding == XA_STRING)
 | 
				
			||||||
 | 
							strncpy(c->name, (char *)name.value, sizeof(c->name));
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
 | 
				
			||||||
 | 
									&& n > 0 && *list)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								strncpy(c->name, *list, sizeof(c->name));
 | 
				
			||||||
 | 
								XFreeStringList(list);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						XFree(name.value);
 | 
				
			||||||
 | 
						resizetitle(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -325,26 +401,6 @@ unmanage(Client *c)
 | 
				
			||||||
		focus(sel);
 | 
							focus(sel);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Client *
 | 
					 | 
				
			||||||
getctitle(Window w)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
	for(c = clients; c; c = c->next)
 | 
					 | 
				
			||||||
		if(c->title == w)
 | 
					 | 
				
			||||||
			return c;
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Client *
 | 
					 | 
				
			||||||
getclient(Window w)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
	for(c = clients; c; c = c->next)
 | 
					 | 
				
			||||||
		if(c->win == w)
 | 
					 | 
				
			||||||
			return c;
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
zoom(Arg *arg)
 | 
					zoom(Arg *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -366,58 +422,3 @@ zoom(Arg *arg)
 | 
				
			||||||
	arrange(NULL);
 | 
						arrange(NULL);
 | 
				
			||||||
	focus(sel);
 | 
						focus(sel);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
maximize(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if(!sel)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	sel->x = sx;
 | 
					 | 
				
			||||||
	sel->y = sy + bh;
 | 
					 | 
				
			||||||
	sel->w = sw - 2 * sel->border;
 | 
					 | 
				
			||||||
	sel->h = sh - 2 * sel->border - bh;
 | 
					 | 
				
			||||||
	higher(sel);
 | 
					 | 
				
			||||||
	resize(sel, False);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
focusprev(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!sel)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
 | 
					 | 
				
			||||||
		higher(c);
 | 
					 | 
				
			||||||
		focus(c);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
focusnext(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Client *c;
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
	if(!sel)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!(c = getnext(sel->next)))
 | 
					 | 
				
			||||||
		c = getnext(clients);
 | 
					 | 
				
			||||||
	if(c) {
 | 
					 | 
				
			||||||
		higher(c);
 | 
					 | 
				
			||||||
		c->revert = sel;
 | 
					 | 
				
			||||||
		focus(c);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
killclient(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if(!sel)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	if(sel->proto & WM_PROTOCOL_DELWIN)
 | 
					 | 
				
			||||||
		sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		XKillClient(dpy, sel->win);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										146
									
								
								draw.c
								
								
								
								
							
							
						
						
									
										146
									
								
								draw.c
								
								
								
								
							| 
						 | 
					@ -2,13 +2,34 @@
 | 
				
			||||||
 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
					 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <X11/Xlocale.h>
 | 
					#include <X11/Xlocale.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					/* static functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					drawborder(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XPoint points[5];
 | 
				
			||||||
 | 
						XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
 | 
				
			||||||
 | 
						XSetForeground(dpy, dc.gc, dc.border);
 | 
				
			||||||
 | 
						points[0].x = dc.x;
 | 
				
			||||||
 | 
						points[0].y = dc.y;
 | 
				
			||||||
 | 
						points[1].x = dc.w - 1;
 | 
				
			||||||
 | 
						points[1].y = 0;
 | 
				
			||||||
 | 
						points[2].x = 0;
 | 
				
			||||||
 | 
						points[2].y = dc.h - 1;
 | 
				
			||||||
 | 
						points[3].x = -(dc.w - 1);
 | 
				
			||||||
 | 
						points[3].y = 0;
 | 
				
			||||||
 | 
						points[4].x = 0;
 | 
				
			||||||
 | 
						points[4].y = -(dc.h - 1);
 | 
				
			||||||
 | 
						XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* extern functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
drawall()
 | 
					drawall()
 | 
				
			||||||
| 
						 | 
					@ -52,59 +73,6 @@ drawstatus()
 | 
				
			||||||
	XFlush(dpy);
 | 
						XFlush(dpy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
drawtitle(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	Bool istile = arrange == dotile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(c == sel) {
 | 
					 | 
				
			||||||
		drawstatus();
 | 
					 | 
				
			||||||
		XUnmapWindow(dpy, c->title);
 | 
					 | 
				
			||||||
		XSetWindowBorder(dpy, c->win, dc.fg);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	XSetWindowBorder(dpy, c->win, dc.bg);
 | 
					 | 
				
			||||||
	XMapWindow(dpy, c->title);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dc.x = dc.y = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dc.w = 0;
 | 
					 | 
				
			||||||
	for(i = 0; i < TLast; i++) {
 | 
					 | 
				
			||||||
		if(c->tags[i]) {
 | 
					 | 
				
			||||||
			dc.x += dc.w;
 | 
					 | 
				
			||||||
			dc.w = textw(c->tags[i]);
 | 
					 | 
				
			||||||
			drawtext(c->tags[i], !istile, True);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dc.x += dc.w;
 | 
					 | 
				
			||||||
	dc.w = textw(c->name);
 | 
					 | 
				
			||||||
	drawtext(c->name, !istile, True);
 | 
					 | 
				
			||||||
	XCopyArea(dpy, dc.drawable, c->title, dc.gc,
 | 
					 | 
				
			||||||
			0, 0, c->tw, c->th, 0, 0);
 | 
					 | 
				
			||||||
	XFlush(dpy);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
drawborder(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XPoint points[5];
 | 
					 | 
				
			||||||
	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
 | 
					 | 
				
			||||||
	XSetForeground(dpy, dc.gc, dc.border);
 | 
					 | 
				
			||||||
	points[0].x = dc.x;
 | 
					 | 
				
			||||||
	points[0].y = dc.y;
 | 
					 | 
				
			||||||
	points[1].x = dc.w - 1;
 | 
					 | 
				
			||||||
	points[1].y = 0;
 | 
					 | 
				
			||||||
	points[2].x = 0;
 | 
					 | 
				
			||||||
	points[2].y = dc.h - 1;
 | 
					 | 
				
			||||||
	points[3].x = -(dc.w - 1);
 | 
					 | 
				
			||||||
	points[3].y = 0;
 | 
					 | 
				
			||||||
	points[4].x = 0;
 | 
					 | 
				
			||||||
	points[4].y = -(dc.h - 1);
 | 
					 | 
				
			||||||
	XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
drawtext(const char *text, Bool invert, Bool border)
 | 
					drawtext(const char *text, Bool invert, Bool border)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -155,6 +123,40 @@ drawtext(const char *text, Bool invert, Bool border)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					drawtitle(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						Bool istile = arrange == dotile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(c == sel) {
 | 
				
			||||||
 | 
							drawstatus();
 | 
				
			||||||
 | 
							XUnmapWindow(dpy, c->title);
 | 
				
			||||||
 | 
							XSetWindowBorder(dpy, c->win, dc.fg);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						XSetWindowBorder(dpy, c->win, dc.bg);
 | 
				
			||||||
 | 
						XMapWindow(dpy, c->title);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc.x = dc.y = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc.w = 0;
 | 
				
			||||||
 | 
						for(i = 0; i < TLast; i++) {
 | 
				
			||||||
 | 
							if(c->tags[i]) {
 | 
				
			||||||
 | 
								dc.x += dc.w;
 | 
				
			||||||
 | 
								dc.w = textw(c->tags[i]);
 | 
				
			||||||
 | 
								drawtext(c->tags[i], !istile, True);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dc.x += dc.w;
 | 
				
			||||||
 | 
						dc.w = textw(c->name);
 | 
				
			||||||
 | 
						drawtext(c->name, !istile, True);
 | 
				
			||||||
 | 
						XCopyArea(dpy, dc.drawable, c->title, dc.gc,
 | 
				
			||||||
 | 
								0, 0, c->tw, c->th, 0, 0);
 | 
				
			||||||
 | 
						XFlush(dpy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long
 | 
					unsigned long
 | 
				
			||||||
getcolor(const char *colstr)
 | 
					getcolor(const char *colstr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -165,23 +167,6 @@ getcolor(const char *colstr)
 | 
				
			||||||
	return color.pixel;
 | 
						return color.pixel;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int
 | 
					 | 
				
			||||||
textnw(char *text, unsigned int len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XRectangle r;
 | 
					 | 
				
			||||||
	if(dc.font.set) {
 | 
					 | 
				
			||||||
		XmbTextExtents(dc.font.set, text, len, NULL, &r);
 | 
					 | 
				
			||||||
		return r.width;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return XTextWidth(dc.font.xfont, text, len);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned int
 | 
					 | 
				
			||||||
textw(char *text)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return textnw(text, strlen(text)) + dc.font.height;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
setfont(const char *fontstr)
 | 
					setfont(const char *fontstr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -232,3 +217,20 @@ setfont(const char *fontstr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dc.font.height = dc.font.ascent + dc.font.descent;
 | 
						dc.font.height = dc.font.ascent + dc.font.descent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int
 | 
				
			||||||
 | 
					textnw(char *text, unsigned int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XRectangle r;
 | 
				
			||||||
 | 
						if(dc.font.set) {
 | 
				
			||||||
 | 
							XmbTextExtents(dc.font.set, text, len, NULL, &r);
 | 
				
			||||||
 | 
							return r.width;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return XTextWidth(dc.font.xfont, text, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int
 | 
				
			||||||
 | 
					textw(char *text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return textnw(text, strlen(text)) + dc.font.height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										43
									
								
								dwm.h
								
								
								
								
							
							
						
						
									
										43
									
								
								dwm.h
								
								
								
								
							| 
						 | 
					@ -104,53 +104,52 @@ extern Client *clients, *sel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* client.c */
 | 
					/* client.c */
 | 
				
			||||||
extern void ban(Client *c);
 | 
					extern void ban(Client *c);
 | 
				
			||||||
extern void manage(Window w, XWindowAttributes *wa);
 | 
					 | 
				
			||||||
extern void unmanage(Client *c);
 | 
					 | 
				
			||||||
extern Client *getclient(Window w);
 | 
					 | 
				
			||||||
extern void focus(Client *c);
 | 
					extern void focus(Client *c);
 | 
				
			||||||
extern void settitle(Client *c);
 | 
					extern void focusnext(Arg *arg);
 | 
				
			||||||
 | 
					extern void focusprev(Arg *arg);
 | 
				
			||||||
 | 
					extern Client *getclient(Window w);
 | 
				
			||||||
 | 
					extern Client *getctitle(Window w);
 | 
				
			||||||
 | 
					extern void gravitate(Client *c, Bool invert);
 | 
				
			||||||
 | 
					extern void higher(Client *c);
 | 
				
			||||||
 | 
					extern void killclient(Arg *arg);
 | 
				
			||||||
 | 
					extern void lower(Client *c);
 | 
				
			||||||
 | 
					extern void manage(Window w, XWindowAttributes *wa);
 | 
				
			||||||
 | 
					extern void maximize(Arg *arg);
 | 
				
			||||||
extern void resize(Client *c, Bool inc);
 | 
					extern void resize(Client *c, Bool inc);
 | 
				
			||||||
extern void setsize(Client *c);
 | 
					extern void setsize(Client *c);
 | 
				
			||||||
extern Client *getctitle(Window w);
 | 
					extern void settitle(Client *c);
 | 
				
			||||||
extern void higher(Client *c);
 | 
					extern void unmanage(Client *c);
 | 
				
			||||||
extern void lower(Client *c);
 | 
					 | 
				
			||||||
extern void gravitate(Client *c, Bool invert);
 | 
					 | 
				
			||||||
extern void zoom(Arg *arg);
 | 
					extern void zoom(Arg *arg);
 | 
				
			||||||
extern void maximize(Arg *arg);
 | 
					 | 
				
			||||||
extern void focusprev(Arg *arg);
 | 
					 | 
				
			||||||
extern void focusnext(Arg *arg);
 | 
					 | 
				
			||||||
extern void killclient(Arg *arg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* draw.c */
 | 
					/* draw.c */
 | 
				
			||||||
extern void drawall();
 | 
					extern void drawall();
 | 
				
			||||||
extern void drawstatus();
 | 
					extern void drawstatus();
 | 
				
			||||||
extern void drawtitle(Client *c);
 | 
					 | 
				
			||||||
extern void drawtext(const char *text, Bool invert, Bool border);
 | 
					extern void drawtext(const char *text, Bool invert, Bool border);
 | 
				
			||||||
 | 
					extern void drawtitle(Client *c);
 | 
				
			||||||
extern unsigned long getcolor(const char *colstr);
 | 
					extern unsigned long getcolor(const char *colstr);
 | 
				
			||||||
extern void setfont(const char *fontstr);
 | 
					extern void setfont(const char *fontstr);
 | 
				
			||||||
extern unsigned int textnw(char *text, unsigned int len);
 | 
					extern unsigned int textnw(char *text, unsigned int len);
 | 
				
			||||||
extern unsigned int textw(char *text);
 | 
					extern unsigned int textw(char *text);
 | 
				
			||||||
extern unsigned int texth(void);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* event.c */
 | 
					/* event.c */
 | 
				
			||||||
extern void grabkeys();
 | 
					extern void grabkeys();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* main.c */
 | 
					/* main.c */
 | 
				
			||||||
extern void quit(Arg *arg);
 | 
					 | 
				
			||||||
extern int xerror(Display *dsply, XErrorEvent *ee);
 | 
					 | 
				
			||||||
extern void sendevent(Window w, Atom a, long value);
 | 
					 | 
				
			||||||
extern int getproto(Window w);
 | 
					extern int getproto(Window w);
 | 
				
			||||||
 | 
					extern void quit(Arg *arg);
 | 
				
			||||||
 | 
					extern void sendevent(Window w, Atom a, long value);
 | 
				
			||||||
 | 
					extern int xerror(Display *dsply, XErrorEvent *ee);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tag.c */
 | 
					/* tag.c */
 | 
				
			||||||
extern Client *getnext(Client *c);
 | 
					extern void appendtag(Arg *arg);
 | 
				
			||||||
extern void settags(Client *c);
 | 
					 | 
				
			||||||
extern void dofloat(Arg *arg);
 | 
					extern void dofloat(Arg *arg);
 | 
				
			||||||
extern void dotile(Arg *arg);
 | 
					extern void dotile(Arg *arg);
 | 
				
			||||||
extern void view(Arg *arg);
 | 
					extern Client *getnext(Client *c);
 | 
				
			||||||
extern void appendtag(Arg *arg);
 | 
					 | 
				
			||||||
extern void replacetag(Arg *arg);
 | 
					extern void replacetag(Arg *arg);
 | 
				
			||||||
 | 
					extern void settags(Client *c);
 | 
				
			||||||
 | 
					extern void view(Arg *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* util.c */
 | 
					/* util.c */
 | 
				
			||||||
extern void eprint(const char *errstr, ...);
 | 
					 | 
				
			||||||
extern void *emallocz(unsigned int size);
 | 
					extern void *emallocz(unsigned int size);
 | 
				
			||||||
 | 
					extern void eprint(const char *errstr, ...);
 | 
				
			||||||
extern void spawn(Arg *arg);
 | 
					extern void spawn(Arg *arg);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										266
									
								
								event.c
								
								
								
								
							
							
						
						
									
										266
									
								
								event.c
								
								
								
								
							| 
						 | 
					@ -2,17 +2,12 @@
 | 
				
			||||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
					 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <X11/keysym.h>
 | 
					#include <X11/keysym.h>
 | 
				
			||||||
#include <X11/Xatom.h>
 | 
					#include <X11/Xatom.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
 | 
					#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
 | 
				
			||||||
#define MouseMask       (ButtonMask | PointerMotionMask)
 | 
					#define MouseMask       (ButtonMask | PointerMotionMask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,130 +49,10 @@ Key key[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********** CUSTOMIZE **********/
 | 
					/********** CUSTOMIZE **********/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* local functions */
 | 
					/* static functions */
 | 
				
			||||||
static void buttonpress(XEvent *e);
 | 
					 | 
				
			||||||
static void configurerequest(XEvent *e);
 | 
					 | 
				
			||||||
static void destroynotify(XEvent *e);
 | 
					 | 
				
			||||||
static void enternotify(XEvent *e);
 | 
					 | 
				
			||||||
static void leavenotify(XEvent *e);
 | 
					 | 
				
			||||||
static void expose(XEvent *e);
 | 
					 | 
				
			||||||
static void keypress(XEvent *e);
 | 
					 | 
				
			||||||
static void maprequest(XEvent *e);
 | 
					 | 
				
			||||||
static void propertynotify(XEvent *e);
 | 
					 | 
				
			||||||
static void unmapnotify(XEvent *e);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void (*handler[LASTEvent]) (XEvent *) = {
 | 
					static void movemouse(Client *c);
 | 
				
			||||||
	[ButtonPress] = buttonpress,
 | 
					static void resizemouse(Client *c);
 | 
				
			||||||
	[ConfigureRequest] = configurerequest,
 | 
					 | 
				
			||||||
	[DestroyNotify] = destroynotify,
 | 
					 | 
				
			||||||
	[EnterNotify] = enternotify,
 | 
					 | 
				
			||||||
	[LeaveNotify] = leavenotify,
 | 
					 | 
				
			||||||
	[Expose] = expose,
 | 
					 | 
				
			||||||
	[KeyPress] = keypress,
 | 
					 | 
				
			||||||
	[MapRequest] = maprequest,
 | 
					 | 
				
			||||||
	[PropertyNotify] = propertynotify,
 | 
					 | 
				
			||||||
	[UnmapNotify] = unmapnotify
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
grabkeys()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
 | 
					 | 
				
			||||||
	unsigned int i;
 | 
					 | 
				
			||||||
	KeyCode code;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for(i = 0; i < len; i++) {
 | 
					 | 
				
			||||||
		code = XKeysymToKeycode(dpy, key[i].keysym);
 | 
					 | 
				
			||||||
		XUngrabKey(dpy, code, key[i].mod, root);
 | 
					 | 
				
			||||||
		XGrabKey(dpy, code, key[i].mod, root, True,
 | 
					 | 
				
			||||||
				GrabModeAsync, GrabModeAsync);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
keypress(XEvent *e)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XKeyEvent *ev = &e->xkey;
 | 
					 | 
				
			||||||
	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
 | 
					 | 
				
			||||||
	unsigned int i;
 | 
					 | 
				
			||||||
	KeySym keysym;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
					 | 
				
			||||||
	for(i = 0; i < len; i++)
 | 
					 | 
				
			||||||
		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
 | 
					 | 
				
			||||||
			if(key[i].func)
 | 
					 | 
				
			||||||
				key[i].func(&key[i].arg);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
resizemouse(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XEvent ev;
 | 
					 | 
				
			||||||
	int ocx, ocy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ocx = c->x;
 | 
					 | 
				
			||||||
	ocy = c->y;
 | 
					 | 
				
			||||||
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
 | 
					 | 
				
			||||||
				None, cursor[CurResize], CurrentTime) != GrabSuccess)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
 | 
					 | 
				
			||||||
	for(;;) {
 | 
					 | 
				
			||||||
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
 | 
					 | 
				
			||||||
		switch(ev.type) {
 | 
					 | 
				
			||||||
		default: break;
 | 
					 | 
				
			||||||
		case Expose:
 | 
					 | 
				
			||||||
			handler[Expose](&ev);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case MotionNotify:
 | 
					 | 
				
			||||||
			XFlush(dpy);
 | 
					 | 
				
			||||||
			c->w = abs(ocx - ev.xmotion.x);
 | 
					 | 
				
			||||||
			c->h = abs(ocy - ev.xmotion.y);
 | 
					 | 
				
			||||||
			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
 | 
					 | 
				
			||||||
			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
 | 
					 | 
				
			||||||
			resize(c, True);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case ButtonRelease:
 | 
					 | 
				
			||||||
			XUngrabPointer(dpy, CurrentTime);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
movemouse(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XEvent ev;
 | 
					 | 
				
			||||||
	int x1, y1, ocx, ocy, di;
 | 
					 | 
				
			||||||
	unsigned int dui;
 | 
					 | 
				
			||||||
	Window dummy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ocx = c->x;
 | 
					 | 
				
			||||||
	ocy = c->y;
 | 
					 | 
				
			||||||
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
 | 
					 | 
				
			||||||
				None, cursor[CurMove], CurrentTime) != GrabSuccess)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
 | 
					 | 
				
			||||||
	for(;;) {
 | 
					 | 
				
			||||||
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
 | 
					 | 
				
			||||||
		switch (ev.type) {
 | 
					 | 
				
			||||||
		default: break;
 | 
					 | 
				
			||||||
		case Expose:
 | 
					 | 
				
			||||||
			handler[Expose](&ev);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case MotionNotify:
 | 
					 | 
				
			||||||
			XFlush(dpy);
 | 
					 | 
				
			||||||
			c->x = ocx + (ev.xmotion.x - x1);
 | 
					 | 
				
			||||||
			c->y = ocy + (ev.xmotion.y - y1);
 | 
					 | 
				
			||||||
			resize(c, False);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case ButtonRelease:
 | 
					 | 
				
			||||||
			XUngrabPointer(dpy, CurrentTime);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
buttonpress(XEvent *e)
 | 
					buttonpress(XEvent *e)
 | 
				
			||||||
| 
						 | 
					@ -279,15 +154,6 @@ enternotify(XEvent *e)
 | 
				
			||||||
		issel = True;
 | 
							issel = True;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
leavenotify(XEvent *e)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	XCrossingEvent *ev = &e->xcrossing;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if((ev->window == root) && !ev->same_screen)
 | 
					 | 
				
			||||||
		issel = True;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
expose(XEvent *e)
 | 
					expose(XEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -302,6 +168,32 @@ expose(XEvent *e)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					keypress(XEvent *e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XKeyEvent *ev = &e->xkey;
 | 
				
			||||||
 | 
						static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						KeySym keysym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
				
			||||||
 | 
						for(i = 0; i < len; i++)
 | 
				
			||||||
 | 
							if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
 | 
				
			||||||
 | 
								if(key[i].func)
 | 
				
			||||||
 | 
									key[i].func(&key[i].arg);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					leavenotify(XEvent *e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XCrossingEvent *ev = &e->xcrossing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if((ev->window == root) && !ev->same_screen)
 | 
				
			||||||
 | 
							issel = True;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
maprequest(XEvent *e)
 | 
					maprequest(XEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -321,6 +213,40 @@ maprequest(XEvent *e)
 | 
				
			||||||
		manage(ev->window, &wa);
 | 
							manage(ev->window, &wa);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					movemouse(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XEvent ev;
 | 
				
			||||||
 | 
						int x1, y1, ocx, ocy, di;
 | 
				
			||||||
 | 
						unsigned int dui;
 | 
				
			||||||
 | 
						Window dummy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ocx = c->x;
 | 
				
			||||||
 | 
						ocy = c->y;
 | 
				
			||||||
 | 
						if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
 | 
				
			||||||
 | 
									None, cursor[CurMove], CurrentTime) != GrabSuccess)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
 | 
				
			||||||
 | 
						for(;;) {
 | 
				
			||||||
 | 
							XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
 | 
				
			||||||
 | 
							switch (ev.type) {
 | 
				
			||||||
 | 
							default: break;
 | 
				
			||||||
 | 
							case Expose:
 | 
				
			||||||
 | 
								handler[Expose](&ev);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case MotionNotify:
 | 
				
			||||||
 | 
								XFlush(dpy);
 | 
				
			||||||
 | 
								c->x = ocx + (ev.xmotion.x - x1);
 | 
				
			||||||
 | 
								c->y = ocy + (ev.xmotion.y - y1);
 | 
				
			||||||
 | 
								resize(c, False);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ButtonRelease:
 | 
				
			||||||
 | 
								XUngrabPointer(dpy, CurrentTime);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
propertynotify(XEvent *e)
 | 
					propertynotify(XEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -354,6 +280,40 @@ propertynotify(XEvent *e)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					resizemouse(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XEvent ev;
 | 
				
			||||||
 | 
						int ocx, ocy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ocx = c->x;
 | 
				
			||||||
 | 
						ocy = c->y;
 | 
				
			||||||
 | 
						if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
 | 
				
			||||||
 | 
									None, cursor[CurResize], CurrentTime) != GrabSuccess)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
 | 
				
			||||||
 | 
						for(;;) {
 | 
				
			||||||
 | 
							XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
 | 
				
			||||||
 | 
							switch(ev.type) {
 | 
				
			||||||
 | 
							default: break;
 | 
				
			||||||
 | 
							case Expose:
 | 
				
			||||||
 | 
								handler[Expose](&ev);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case MotionNotify:
 | 
				
			||||||
 | 
								XFlush(dpy);
 | 
				
			||||||
 | 
								c->w = abs(ocx - ev.xmotion.x);
 | 
				
			||||||
 | 
								c->h = abs(ocy - ev.xmotion.y);
 | 
				
			||||||
 | 
								c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
 | 
				
			||||||
 | 
								c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
 | 
				
			||||||
 | 
								resize(c, True);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ButtonRelease:
 | 
				
			||||||
 | 
								XUngrabPointer(dpy, CurrentTime);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
unmapnotify(XEvent *e)
 | 
					unmapnotify(XEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -363,3 +323,33 @@ unmapnotify(XEvent *e)
 | 
				
			||||||
	if((c = getclient(ev->window)))
 | 
						if((c = getclient(ev->window)))
 | 
				
			||||||
		unmanage(c);
 | 
							unmanage(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* extern functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void (*handler[LASTEvent]) (XEvent *) = {
 | 
				
			||||||
 | 
						[ButtonPress] = buttonpress,
 | 
				
			||||||
 | 
						[ConfigureRequest] = configurerequest,
 | 
				
			||||||
 | 
						[DestroyNotify] = destroynotify,
 | 
				
			||||||
 | 
						[EnterNotify] = enternotify,
 | 
				
			||||||
 | 
						[LeaveNotify] = leavenotify,
 | 
				
			||||||
 | 
						[Expose] = expose,
 | 
				
			||||||
 | 
						[KeyPress] = keypress,
 | 
				
			||||||
 | 
						[MapRequest] = maprequest,
 | 
				
			||||||
 | 
						[PropertyNotify] = propertynotify,
 | 
				
			||||||
 | 
						[UnmapNotify] = unmapnotify
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grabkeys()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						KeyCode code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(i = 0; i < len; i++) {
 | 
				
			||||||
 | 
							code = XKeysymToKeycode(dpy, key[i].keysym);
 | 
				
			||||||
 | 
							XUngrabKey(dpy, code, key[i].mod, root);
 | 
				
			||||||
 | 
							XGrabKey(dpy, code, key[i].mod, root, True,
 | 
				
			||||||
 | 
									GrabModeAsync, GrabModeAsync);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										71
									
								
								main.c
								
								
								
								
							
							
						
						
									
										71
									
								
								main.c
								
								
								
								
							| 
						 | 
					@ -3,31 +3,17 @@
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <X11/cursorfont.h>
 | 
					#include <X11/cursorfont.h>
 | 
				
			||||||
#include <X11/Xatom.h>
 | 
					#include <X11/Xatom.h>
 | 
				
			||||||
#include <X11/Xproto.h>
 | 
					#include <X11/Xproto.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/********** CUSTOMIZE **********/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
char *tags[TLast] = {
 | 
					 | 
				
			||||||
	[Tscratch] = "scratch",
 | 
					 | 
				
			||||||
	[Tdev] = "dev",
 | 
					 | 
				
			||||||
	[Twww] = "www",
 | 
					 | 
				
			||||||
	[Twork] = "work",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/********** CUSTOMIZE **********/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* X structs */
 | 
					 | 
				
			||||||
Display *dpy;
 | 
					Display *dpy;
 | 
				
			||||||
Window root, barwin;
 | 
					Window root, barwin;
 | 
				
			||||||
Atom wm_atom[WMLast], net_atom[NetLast];
 | 
					Atom wm_atom[WMLast], net_atom[NetLast];
 | 
				
			||||||
| 
						 | 
					@ -48,8 +34,17 @@ static const char version[] =
 | 
				
			||||||
	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
 | 
						"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
 | 
				
			||||||
static int (*xerrorxlib)(Display *, XErrorEvent *);
 | 
					static int (*xerrorxlib)(Display *, XErrorEvent *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* static functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
usage() {	eprint("usage: dwm [-v]\n"); }
 | 
					cleanup()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while(sel) {
 | 
				
			||||||
 | 
							resize(sel, True);
 | 
				
			||||||
 | 
							unmanage(sel);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
scan()
 | 
					scan()
 | 
				
			||||||
| 
						 | 
					@ -73,22 +68,6 @@ scan()
 | 
				
			||||||
		XFree(wins);
 | 
							XFree(wins);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
cleanup()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while(sel) {
 | 
					 | 
				
			||||||
		resize(sel, True);
 | 
					 | 
				
			||||||
		unmanage(sel);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
quit(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	running = False;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
 | 
					win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -109,6 +88,19 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Startup Error handler to check if another window manager
 | 
				
			||||||
 | 
					 * is already running.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					xerrorstart(Display *dsply, XErrorEvent *ee)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						otherwm = True;
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* extern functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
getproto(Window w)
 | 
					getproto(Window w)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -144,15 +136,10 @@ sendevent(Window w, Atom a, long value)
 | 
				
			||||||
	XFlush(dpy);
 | 
						XFlush(dpy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					void
 | 
				
			||||||
 * Startup Error handler to check if another window manager
 | 
					quit(Arg *arg)
 | 
				
			||||||
 * is already running.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
xerrorstart(Display *dsply, XErrorEvent *ee)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	otherwm = True;
 | 
						running = False;
 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -201,7 +188,7 @@ main(int argc, char *argv[])
 | 
				
			||||||
			exit(0);
 | 
								exit(0);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			usage();
 | 
								eprint("usage: dwm [-v]\n");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										118
									
								
								tag.c
								
								
								
								
							
							
						
						
									
										118
									
								
								tag.c
								
								
								
								
							| 
						 | 
					@ -2,71 +2,39 @@
 | 
				
			||||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
					 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <X11/Xatom.h>
 | 
					 | 
				
			||||||
#include <X11/Xutil.h>
 | 
					#include <X11/Xutil.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					/********** CUSTOMIZE **********/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *tags[TLast] = {
 | 
				
			||||||
 | 
						[Tscratch] = "scratch",
 | 
				
			||||||
 | 
						[Tdev] = "dev",
 | 
				
			||||||
 | 
						[Twww] = "www",
 | 
				
			||||||
 | 
						[Twork] = "work",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Rule rule[] = {
 | 
					static Rule rule[] = {
 | 
				
			||||||
	/* class			instance	tags						dofloat */
 | 
						/* class			instance	tags						dofloat */
 | 
				
			||||||
	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
 | 
						{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/********** CUSTOMIZE **********/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* extern functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void (*arrange)(Arg *) = dotile;
 | 
					void (*arrange)(Arg *) = dotile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Client *
 | 
					 | 
				
			||||||
getnext(Client *c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	for(; c && !c->tags[tsel]; c = c->next);
 | 
					 | 
				
			||||||
	return c;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
settags(Client *c)
 | 
					appendtag(Arg *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	XClassHint ch;
 | 
						if(!sel)
 | 
				
			||||||
	static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
 | 
					 | 
				
			||||||
	unsigned int i, j;
 | 
					 | 
				
			||||||
	Bool matched = False;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!len) {
 | 
					 | 
				
			||||||
		c->tags[tsel] = tags[tsel];
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(XGetClassHint(dpy, c->win, &ch)) {
 | 
						sel->tags[arg->i] = tags[arg->i];
 | 
				
			||||||
		if(ch.res_class && ch.res_name) {
 | 
					 | 
				
			||||||
			for(i = 0; i < len; i++)
 | 
					 | 
				
			||||||
				if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
 | 
					 | 
				
			||||||
					&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					for(j = 0; j < TLast; j++)
 | 
					 | 
				
			||||||
						c->tags[j] = rule[i].tags[j];
 | 
					 | 
				
			||||||
					c->dofloat = rule[i].dofloat;
 | 
					 | 
				
			||||||
					matched = True;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if(ch.res_class)
 | 
					 | 
				
			||||||
			XFree(ch.res_class);
 | 
					 | 
				
			||||||
		if(ch.res_name)
 | 
					 | 
				
			||||||
			XFree(ch.res_name);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!matched)
 | 
					 | 
				
			||||||
		c->tags[tsel] = tags[tsel];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
view(Arg *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	tsel = arg->i;
 | 
					 | 
				
			||||||
	arrange(NULL);
 | 
						arrange(NULL);
 | 
				
			||||||
	drawall();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -147,14 +115,11 @@ dotile(Arg *arg)
 | 
				
			||||||
	drawall();
 | 
						drawall();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					Client *
 | 
				
			||||||
appendtag(Arg *arg)
 | 
					getnext(Client *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if(!sel)
 | 
						for(; c && !c->tags[tsel]; c = c->next);
 | 
				
			||||||
		return;
 | 
						return c;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	sel->tags[arg->i] = tags[arg->i];
 | 
					 | 
				
			||||||
	arrange(NULL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -169,3 +134,46 @@ replacetag(Arg *arg)
 | 
				
			||||||
	appendtag(arg);
 | 
						appendtag(arg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					settags(Client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						XClassHint ch;
 | 
				
			||||||
 | 
						static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
 | 
				
			||||||
 | 
						unsigned int i, j;
 | 
				
			||||||
 | 
						Bool matched = False;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!len) {
 | 
				
			||||||
 | 
							c->tags[tsel] = tags[tsel];
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(XGetClassHint(dpy, c->win, &ch)) {
 | 
				
			||||||
 | 
							if(ch.res_class && ch.res_name) {
 | 
				
			||||||
 | 
								for(i = 0; i < len; i++)
 | 
				
			||||||
 | 
									if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
 | 
				
			||||||
 | 
										&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										for(j = 0; j < TLast; j++)
 | 
				
			||||||
 | 
											c->tags[j] = rule[i].tags[j];
 | 
				
			||||||
 | 
										c->dofloat = rule[i].dofloat;
 | 
				
			||||||
 | 
										matched = True;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if(ch.res_class)
 | 
				
			||||||
 | 
								XFree(ch.res_class);
 | 
				
			||||||
 | 
							if(ch.res_name)
 | 
				
			||||||
 | 
								XFree(ch.res_name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!matched)
 | 
				
			||||||
 | 
							c->tags[tsel] = tags[tsel];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					view(Arg *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						tsel = arg->i;
 | 
				
			||||||
 | 
						arrange(NULL);
 | 
				
			||||||
 | 
						drawall();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								util.c
								
								
								
								
							
							
						
						
									
										24
									
								
								util.c
								
								
								
								
							| 
						 | 
					@ -2,24 +2,15 @@
 | 
				
			||||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
					 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
				
			||||||
 * See LICENSE file for license details.
 | 
					 * See LICENSE file for license details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "dwm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <sys/wait.h>
 | 
					#include <sys/wait.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dwm.h"
 | 
					/* static functions */
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
eprint(const char *errstr, ...) {
 | 
					 | 
				
			||||||
	va_list ap;
 | 
					 | 
				
			||||||
	va_start(ap, errstr);
 | 
					 | 
				
			||||||
	vfprintf(stderr, errstr, ap);
 | 
					 | 
				
			||||||
	va_end(ap);
 | 
					 | 
				
			||||||
	exit(1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
bad_malloc(unsigned int size)
 | 
					bad_malloc(unsigned int size)
 | 
				
			||||||
| 
						 | 
					@ -29,6 +20,8 @@ bad_malloc(unsigned int size)
 | 
				
			||||||
	exit(1);
 | 
						exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* extern functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *
 | 
					void *
 | 
				
			||||||
emallocz(unsigned int size)
 | 
					emallocz(unsigned int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -38,6 +31,15 @@ emallocz(unsigned int size)
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eprint(const char *errstr, ...) {
 | 
				
			||||||
 | 
						va_list ap;
 | 
				
			||||||
 | 
						va_start(ap, errstr);
 | 
				
			||||||
 | 
						vfprintf(stderr, errstr, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
						exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
spawn(Arg *arg)
 | 
					spawn(Arg *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue