proceeded with cleaning up, sorting functions, etc
This commit is contained in:
		
							
								
								
									
										423
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										423
									
								
								client.c
									
									
									
									
									
								
							@@ -2,21 +2,14 @@
 | 
			
		||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
			
		||||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
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 functions */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
resizetitle(Client *c)
 | 
			
		||||
@@ -35,84 +28,19 @@ resizetitle(Client *c)
 | 
			
		||||
	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
settitle(Client *c)
 | 
			
		||||
static int
 | 
			
		||||
xerrordummy(Display *dsply, XErrorEvent *ee)
 | 
			
		||||
{
 | 
			
		||||
	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);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
/* extern functions */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
higher(Client *c)
 | 
			
		||||
ban(Client *c)
 | 
			
		||||
{
 | 
			
		||||
	XRaiseWindow(dpy, c->win);
 | 
			
		||||
	XRaiseWindow(dpy, c->title);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lower(Client *c)
 | 
			
		||||
{
 | 
			
		||||
	XLowerWindow(dpy, c->title);
 | 
			
		||||
	XLowerWindow(dpy, c->win);
 | 
			
		||||
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
 | 
			
		||||
	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -131,6 +59,137 @@ focus(Client *c)
 | 
			
		||||
	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
 | 
			
		||||
manage(Window w, XWindowAttributes *wa)
 | 
			
		||||
{
 | 
			
		||||
@@ -195,61 +254,18 @@ manage(Window w, XWindowAttributes *wa)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gravitate(Client *c, Bool invert)
 | 
			
		||||
maximize(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
	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
 | 
			
		||||
resize(Client *c, Bool inc)
 | 
			
		||||
{
 | 
			
		||||
@@ -290,10 +306,70 @@ resize(Client *c, Bool inc)
 | 
			
		||||
	XFlush(dpy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
xerrordummy(Display *dsply, XErrorEvent *ee)
 | 
			
		||||
void
 | 
			
		||||
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
 | 
			
		||||
@@ -325,26 +401,6 @@ unmanage(Client *c)
 | 
			
		||||
		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
 | 
			
		||||
zoom(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
@@ -366,58 +422,3 @@ zoom(Arg *arg)
 | 
			
		||||
	arrange(NULL);
 | 
			
		||||
	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>
 | 
			
		||||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.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
 | 
			
		||||
drawall()
 | 
			
		||||
@@ -52,59 +73,6 @@ drawstatus()
 | 
			
		||||
	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
 | 
			
		||||
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
 | 
			
		||||
getcolor(const char *colstr)
 | 
			
		||||
{
 | 
			
		||||
@@ -165,23 +167,6 @@ getcolor(const char *colstr)
 | 
			
		||||
	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
 | 
			
		||||
setfont(const char *fontstr)
 | 
			
		||||
{
 | 
			
		||||
@@ -232,3 +217,20 @@ setfont(const char *fontstr)
 | 
			
		||||
	}
 | 
			
		||||
	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 */
 | 
			
		||||
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 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 setsize(Client *c);
 | 
			
		||||
extern Client *getctitle(Window w);
 | 
			
		||||
extern void higher(Client *c);
 | 
			
		||||
extern void lower(Client *c);
 | 
			
		||||
extern void gravitate(Client *c, Bool invert);
 | 
			
		||||
extern void settitle(Client *c);
 | 
			
		||||
extern void unmanage(Client *c);
 | 
			
		||||
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 */
 | 
			
		||||
extern void drawall();
 | 
			
		||||
extern void drawstatus();
 | 
			
		||||
extern void drawtitle(Client *c);
 | 
			
		||||
extern void drawtext(const char *text, Bool invert, Bool border);
 | 
			
		||||
extern void drawtitle(Client *c);
 | 
			
		||||
extern unsigned long getcolor(const char *colstr);
 | 
			
		||||
extern void setfont(const char *fontstr);
 | 
			
		||||
extern unsigned int textnw(char *text, unsigned int len);
 | 
			
		||||
extern unsigned int textw(char *text);
 | 
			
		||||
extern unsigned int texth(void);
 | 
			
		||||
 | 
			
		||||
/* event.c */
 | 
			
		||||
extern void grabkeys();
 | 
			
		||||
 | 
			
		||||
/* 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 void quit(Arg *arg);
 | 
			
		||||
extern void sendevent(Window w, Atom a, long value);
 | 
			
		||||
extern int xerror(Display *dsply, XErrorEvent *ee);
 | 
			
		||||
 | 
			
		||||
/* tag.c */
 | 
			
		||||
extern Client *getnext(Client *c);
 | 
			
		||||
extern void settags(Client *c);
 | 
			
		||||
extern void appendtag(Arg *arg);
 | 
			
		||||
extern void dofloat(Arg *arg);
 | 
			
		||||
extern void dotile(Arg *arg);
 | 
			
		||||
extern void view(Arg *arg);
 | 
			
		||||
extern void appendtag(Arg *arg);
 | 
			
		||||
extern Client *getnext(Client *c);
 | 
			
		||||
extern void replacetag(Arg *arg);
 | 
			
		||||
extern void settags(Client *c);
 | 
			
		||||
extern void view(Arg *arg);
 | 
			
		||||
 | 
			
		||||
/* util.c */
 | 
			
		||||
extern void eprint(const char *errstr, ...);
 | 
			
		||||
extern void *emallocz(unsigned int size);
 | 
			
		||||
extern void eprint(const char *errstr, ...);
 | 
			
		||||
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>
 | 
			
		||||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <X11/keysym.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
 | 
			
		||||
#define MouseMask       (ButtonMask | PointerMotionMask)
 | 
			
		||||
 | 
			
		||||
@@ -54,130 +49,10 @@ Key key[] = {
 | 
			
		||||
 | 
			
		||||
/********** CUSTOMIZE **********/
 | 
			
		||||
 | 
			
		||||
/* local 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);
 | 
			
		||||
/* static 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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 movemouse(Client *c);
 | 
			
		||||
static void resizemouse(Client *c);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
buttonpress(XEvent *e)
 | 
			
		||||
@@ -279,15 +154,6 @@ enternotify(XEvent *e)
 | 
			
		||||
		issel = True;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
leavenotify(XEvent *e)
 | 
			
		||||
{
 | 
			
		||||
	XCrossingEvent *ev = &e->xcrossing;
 | 
			
		||||
 | 
			
		||||
	if((ev->window == root) && !ev->same_screen)
 | 
			
		||||
		issel = True;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
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
 | 
			
		||||
maprequest(XEvent *e)
 | 
			
		||||
{
 | 
			
		||||
@@ -321,6 +213,40 @@ maprequest(XEvent *e)
 | 
			
		||||
		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
 | 
			
		||||
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
 | 
			
		||||
unmapnotify(XEvent *e)
 | 
			
		||||
{
 | 
			
		||||
@@ -363,3 +323,33 @@ unmapnotify(XEvent *e)
 | 
			
		||||
	if((c = getclient(ev->window)))
 | 
			
		||||
		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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/cursorfont.h>
 | 
			
		||||
#include <X11/Xatom.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;
 | 
			
		||||
Window root, barwin;
 | 
			
		||||
Atom wm_atom[WMLast], net_atom[NetLast];
 | 
			
		||||
@@ -48,8 +34,17 @@ static const char version[] =
 | 
			
		||||
	"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
 | 
			
		||||
static int (*xerrorxlib)(Display *, XErrorEvent *);
 | 
			
		||||
 | 
			
		||||
/* static functions */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
usage() {	eprint("usage: dwm [-v]\n"); }
 | 
			
		||||
cleanup()
 | 
			
		||||
{
 | 
			
		||||
	while(sel) {
 | 
			
		||||
		resize(sel, True);
 | 
			
		||||
		unmanage(sel);
 | 
			
		||||
	}
 | 
			
		||||
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scan()
 | 
			
		||||
@@ -73,22 +68,6 @@ scan()
 | 
			
		||||
		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
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
getproto(Window w)
 | 
			
		||||
{
 | 
			
		||||
@@ -144,15 +136,10 @@ sendevent(Window w, Atom a, long value)
 | 
			
		||||
	XFlush(dpy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Startup Error handler to check if another window manager
 | 
			
		||||
 * is already running.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
xerrorstart(Display *dsply, XErrorEvent *ee)
 | 
			
		||||
void
 | 
			
		||||
quit(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
	otherwm = True;
 | 
			
		||||
	return -1;
 | 
			
		||||
	running = False;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -201,7 +188,7 @@ main(int argc, char *argv[])
 | 
			
		||||
			exit(0);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			usage();
 | 
			
		||||
			eprint("usage: dwm [-v]\n");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										118
									
								
								tag.c
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								tag.c
									
									
									
									
									
								
							@@ -2,71 +2,39 @@
 | 
			
		||||
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 | 
			
		||||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
/********** CUSTOMIZE **********/
 | 
			
		||||
 | 
			
		||||
char *tags[TLast] = {
 | 
			
		||||
	[Tscratch] = "scratch",
 | 
			
		||||
	[Tdev] = "dev",
 | 
			
		||||
	[Twww] = "www",
 | 
			
		||||
	[Twork] = "work",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static Rule rule[] = {
 | 
			
		||||
	/* class			instance	tags						dofloat */
 | 
			
		||||
	{ "Firefox-bin",	"Gecko",	{ [Twww] = "www" },			False },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/********** CUSTOMIZE **********/
 | 
			
		||||
 | 
			
		||||
/* extern functions */
 | 
			
		||||
 | 
			
		||||
void (*arrange)(Arg *) = dotile;
 | 
			
		||||
 | 
			
		||||
Client *
 | 
			
		||||
getnext(Client *c)
 | 
			
		||||
{
 | 
			
		||||
	for(; c && !c->tags[tsel]; c = c->next);
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
settags(Client *c)
 | 
			
		||||
appendtag(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
	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];
 | 
			
		||||
	if(!sel)
 | 
			
		||||
		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;
 | 
			
		||||
	sel->tags[arg->i] = tags[arg->i];
 | 
			
		||||
	arrange(NULL);
 | 
			
		||||
	drawall();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -147,14 +115,11 @@ dotile(Arg *arg)
 | 
			
		||||
	drawall();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
appendtag(Arg *arg)
 | 
			
		||||
Client *
 | 
			
		||||
getnext(Client *c)
 | 
			
		||||
{
 | 
			
		||||
	if(!sel)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	sel->tags[arg->i] = tags[arg->i];
 | 
			
		||||
	arrange(NULL);
 | 
			
		||||
	for(; c && !c->tags[tsel]; c = c->next);
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -169,3 +134,46 @@ replacetag(Arg *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>
 | 
			
		||||
 * See LICENSE file for license details.
 | 
			
		||||
 */
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "dwm.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eprint(const char *errstr, ...) {
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	va_start(ap, errstr);
 | 
			
		||||
	vfprintf(stderr, errstr, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
/* static functions */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
bad_malloc(unsigned int size)
 | 
			
		||||
@@ -29,6 +20,8 @@ bad_malloc(unsigned int size)
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* extern functions */
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
emallocz(unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
@@ -38,6 +31,15 @@ emallocz(unsigned int size)
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eprint(const char *errstr, ...) {
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	va_start(ap, errstr);
 | 
			
		||||
	vfprintf(stderr, errstr, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
spawn(Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user