dwm.c
changeset 1209 c2dc0bd92158
parent 1207 055bf865d22f
child 1212 4ed5ed4292fe
equal deleted inserted replaced
1208:fab49062da0a 1209:c2dc0bd92158
    39 #include <X11/Xlib.h>
    39 #include <X11/Xlib.h>
    40 #include <X11/Xproto.h>
    40 #include <X11/Xproto.h>
    41 #include <X11/Xutil.h>
    41 #include <X11/Xutil.h>
    42 
    42 
    43 /* macros */
    43 /* macros */
    44 #define MAX(a, b)	((a) > (b) ? (a) : (b))
    44 #define MAX(a, b)       ((a) > (b) ? (a) : (b))
    45 #define MIN(a, b)	((a) < (b) ? (a) : (b))
    45 #define MIN(a, b)       ((a) < (b) ? (a) : (b))
    46 #define BUTTONMASK	(ButtonPressMask|ButtonReleaseMask)
    46 #define BUTTONMASK      (ButtonPressMask|ButtonReleaseMask)
    47 #define CLEANMASK(mask)	(mask & ~(numlockmask|LockMask))
    47 #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
    48 #define LENGTH(x)	(sizeof x / sizeof x[0])
    48 #define LENGTH(x)       (sizeof x / sizeof x[0])
    49 #define MAXTAGLEN	16
    49 #define MAXTAGLEN       16
    50 #define MOUSEMASK	(BUTTONMASK|PointerMotionMask)
    50 #define MOUSEMASK       (BUTTONMASK|PointerMotionMask)
    51 
    51 
    52 /* enums */
    52 /* enums */
    53 enum { CurNormal, CurResize, CurMove, CurLast };	/* cursor */
    53 enum { BarTop, BarBot, BarOff, BarLast };               /* bar appearance */
    54 enum { ColBorder, ColFG, ColBG, ColLast };		/* color */
    54 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
    55 enum { NetSupported, NetWMName, NetLast };		/* EWMH atoms */
    55 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
       
    56 enum { NetSupported, NetWMName, NetLast };              /* EWMH atoms */
    56 enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
    57 enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
    57 
    58 
    58 /* typedefs */
    59 /* typedefs */
    59 typedef struct Client Client;
    60 typedef struct Client Client;
    60 struct Client {
    61 struct Client {
   164 void setup(void);
   165 void setup(void);
   165 void spawn(const char *arg);
   166 void spawn(const char *arg);
   166 void tag(const char *arg);
   167 void tag(const char *arg);
   167 unsigned int textnw(const char *text, unsigned int len);
   168 unsigned int textnw(const char *text, unsigned int len);
   168 unsigned int textw(const char *text);
   169 unsigned int textw(const char *text);
       
   170 void togglebar(const char *arg);
   169 void togglefloating(const char *arg);
   171 void togglefloating(const char *arg);
   170 void togglelayout(const char *arg);
   172 void togglelayout(const char *arg);
   171 void toggletag(const char *arg);
   173 void toggletag(const char *arg);
   172 void toggleview(const char *arg);
   174 void toggleview(const char *arg);
   173 void unban(Client *c);
   175 void unban(Client *c);
   177 void updategeom(void);
   179 void updategeom(void);
   178 void updatesizehints(Client *c);
   180 void updatesizehints(Client *c);
   179 void updatetitle(Client *c);
   181 void updatetitle(Client *c);
   180 void updatewmhints(Client *c);
   182 void updatewmhints(Client *c);
   181 void view(const char *arg);
   183 void view(const char *arg);
   182 void viewprevtag(const char *arg);	/* views previous selected tags */
   184 void viewprevtag(const char *arg);
   183 int xerror(Display *dpy, XErrorEvent *ee);
   185 int xerror(Display *dpy, XErrorEvent *ee);
   184 int xerrordummy(Display *dpy, XErrorEvent *ee);
   186 int xerrordummy(Display *dpy, XErrorEvent *ee);
   185 int xerrorstart(Display *dpy, XErrorEvent *ee);
   187 int xerrorstart(Display *dpy, XErrorEvent *ee);
   186 void zoom(const char *arg);
   188 void zoom(const char *arg);
   187 
   189 
   188 /* variables */
   190 /* variables */
   189 char stext[256];
   191 char stext[256];
   190 int screen, sx, sy, sw, sh;
   192 int screen, sx, sy, sw, sh;
   191 int (*xerrorxlib)(Display *, XErrorEvent *);
       
   192 int bx, by, bw, bh, blw, wx, wy, ww, wh;
   193 int bx, by, bw, bh, blw, wx, wy, ww, wh;
   193 int seltags = 0;
   194 int seltags = 0;
       
   195 int (*xerrorxlib)(Display *, XErrorEvent *);
   194 unsigned int numlockmask = 0;
   196 unsigned int numlockmask = 0;
   195 void (*handler[LASTEvent]) (XEvent *) = {
   197 void (*handler[LASTEvent]) (XEvent *) = {
   196 	[ButtonPress] = buttonpress,
   198 	[ButtonPress] = buttonpress,
   197 	[ConfigureRequest] = configurerequest,
   199 	[ConfigureRequest] = configurerequest,
   198 	[ConfigureNotify] = configurenotify,
   200 	[ConfigureNotify] = configurenotify,
   957 			c->x = wx + ww - c->w - 2 * c->bw;
   959 			c->x = wx + ww - c->w - 2 * c->bw;
   958 		if(c->y + c->h + 2 * c->bw > wy + wh)
   960 		if(c->y + c->h + 2 * c->bw > wy + wh)
   959 			c->y = wy + wh - c->h - 2 * c->bw;
   961 			c->y = wy + wh - c->h - 2 * c->bw;
   960 		c->x = MAX(c->x, wx);
   962 		c->x = MAX(c->x, wx);
   961 		c->y = MAX(c->y, wy);
   963 		c->y = MAX(c->y, wy);
   962 		c->bw = BORDERPX;
   964 		c->bw = borderpx;
   963 	}
   965 	}
   964 
   966 
   965 	wc.border_width = c->bw;
   967 	wc.border_width = c->bw;
   966 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
   968 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
   967 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
   969 	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
  1035 			break;
  1037 			break;
  1036 		case MotionNotify:
  1038 		case MotionNotify:
  1037 			XSync(dpy, False);
  1039 			XSync(dpy, False);
  1038 			nx = ocx + (ev.xmotion.x - x1);
  1040 			nx = ocx + (ev.xmotion.x - x1);
  1039 			ny = ocy + (ev.xmotion.y - y1);
  1041 			ny = ocy + (ev.xmotion.y - y1);
  1040 			if(abs(wx - nx) < SNAP)
  1042 			if(abs(wx - nx) < snap)
  1041 				nx = wx;
  1043 				nx = wx;
  1042 			else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < SNAP)
  1044 			else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < snap)
  1043 				nx = wx + ww - c->w - 2 * c->bw;
  1045 				nx = wx + ww - c->w - 2 * c->bw;
  1044 			if(abs(wy - ny) < SNAP)
  1046 			if(abs(wy - ny) < snap)
  1045 				ny = wy;
  1047 				ny = wy;
  1046 			else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
  1048 			else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < snap)
  1047 				ny = wy + wh - c->h - 2 * c->bw;
  1049 				ny = wy + wh - c->h - 2 * c->bw;
  1048 			if(!c->isfloating && lt->arrange && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
  1050 			if(!c->isfloating && lt->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
  1049 				togglefloating(NULL);
  1051 				togglefloating(NULL);
  1050 			if(!lt->arrange || c->isfloating)
  1052 			if(!lt->arrange || c->isfloating)
  1051 				resize(c, nx, ny, c->w, c->h, False);
  1053 				resize(c, nx, ny, c->w, c->h, False);
  1052 			break;
  1054 			break;
  1053 		}
  1055 		}
  1189 			break;
  1191 			break;
  1190 		case MotionNotify:
  1192 		case MotionNotify:
  1191 			XSync(dpy, False);
  1193 			XSync(dpy, False);
  1192 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1194 			nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
  1193 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1195 			nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
  1194 			if(!c->isfloating && lt->arrange && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) {
  1196 			if(!c->isfloating && lt->arrange && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) {
  1195 				togglefloating(NULL);
  1197 				togglefloating(NULL);
  1196 			}
  1198 			}
  1197 			if(!lt->arrange || c->isfloating)
  1199 			if(!lt->arrange || c->isfloating)
  1198 				resize(c, c->x, c->y, nw, nh, True);
  1200 				resize(c, c->x, c->y, nw, nh, True);
  1199 			break;
  1201 			break;
  1453 textw(const char *text) {
  1455 textw(const char *text) {
  1454 	return textnw(text, strlen(text)) + dc.font.height;
  1456 	return textnw(text, strlen(text)) + dc.font.height;
  1455 }
  1457 }
  1456 
  1458 
  1457 void
  1459 void
       
  1460 togglebar(const char *arg) {
       
  1461 	showbar = !showbar;
       
  1462 	updategeom();
       
  1463 	updatebar();
       
  1464 	arrange();
       
  1465 }
       
  1466 
       
  1467 void
  1458 togglefloating(const char *arg) {
  1468 togglefloating(const char *arg) {
  1459 	if(!sel)
  1469 	if(!sel)
  1460 		return;
  1470 		return;
  1461 	sel->isfloating = !sel->isfloating;
  1471 	sel->isfloating = !sel->isfloating;
  1462 	if(sel->isfloating)
  1472 	if(sel->isfloating)
  1562 
  1572 
  1563 void
  1573 void
  1564 updategeom(void) {
  1574 updategeom(void) {
  1565 	unsigned int i;
  1575 	unsigned int i;
  1566 
  1576 
  1567 	/* bar geometry */
  1577 #ifdef DEFGEOM /* define your own if you are Xinerama user */
       
  1578 	DEFGEOM
       
  1579 #else
       
  1580 	/* bar geometry*/
  1568 	bx = 0;
  1581 	bx = 0;
  1569 	by = 0;
  1582 	by = showbar ? (topbar ? 0 : sh - bh) : -bh;
  1570 	bw = sw;
  1583 	bw = sw;
  1571 
  1584 
  1572 	/* window area geometry */
  1585 	/* window area geometry */
  1573 	wx = sx;
  1586 	wx = sx;
  1574 	wy = sy + bh;
  1587 	wy = showbar && topbar ? sy + bh : sy;
  1575 	ww = sw;
  1588 	ww = sw;
  1576 	wh = sh - bh;
  1589 	wh = showbar ? sh - bh : sh;
       
  1590 #endif
  1577 
  1591 
  1578 	/* update layout geometries */
  1592 	/* update layout geometries */
  1579 	for(i = 0; i < LENGTH(layouts); i++)
  1593 	for(i = 0; i < LENGTH(layouts); i++)
  1580 		if(layouts[i].updategeom)
  1594 		if(layouts[i].updategeom)
  1581 			layouts[i].updategeom();
  1595 			layouts[i].updategeom();