dwm.c
changeset 1106 084b17f96d9b
parent 1104 167446962e09
child 1107 589074fac88d
equal deleted inserted replaced
1105:8427b03e56db 1106:084b17f96d9b
    65 struct Client {
    65 struct Client {
    66 	char name[256];
    66 	char name[256];
    67 	int x, y, w, h;
    67 	int x, y, w, h;
    68 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    68 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    69 	int minax, maxax, minay, maxay;
    69 	int minax, maxax, minay, maxay;
    70 	int *tags;
       
    71 	long flags;
    70 	long flags;
    72 	unsigned int border, oldborder;
    71 	unsigned int border, oldborder;
    73 	Bool isbanned, isfixed, isfloating, isurgent;
    72 	Bool isbanned, isfixed, isfloating, isurgent;
       
    73 	Bool *tags;
    74 	Client *next;
    74 	Client *next;
    75 	Client *prev;
    75 	Client *prev;
    76 	Client *snext;
    76 	Client *snext;
    77 	Window win;
    77 	Window win;
    78 };
    78 };
   108 	const char *prop;
   108 	const char *prop;
   109 	const char *tag;
   109 	const char *tag;
   110 	Bool isfloating;
   110 	Bool isfloating;
   111 } Rule;
   111 } Rule;
   112 
   112 
       
   113 typedef struct {
       
   114 	const char name[MAXTAGLEN];
       
   115 	unsigned int view;
       
   116 } Tag;
       
   117 
   113 struct View {
   118 struct View {
   114 	int id;
       
   115 	int x, y, w, h, wax, way, wah, waw;
   119 	int x, y, w, h, wax, way, wah, waw;
   116 	double mwfact;
   120 	double mwfact;
   117 	Layout *layout;
   121 	Layout *layout;
   118 	Window barwin;
   122 	Window barwin;
   119 };
   123 };
   120 
   124 
   121 /* function declarations */
   125 /* function declarations */
       
   126 void addtag(Client *c, const char *t);
   122 void applyrules(Client *c);
   127 void applyrules(Client *c);
   123 void arrange(void);
   128 void arrange(void);
   124 void attach(Client *c);
   129 void attach(Client *c);
   125 void attachstack(Client *c);
   130 void attachstack(Client *c);
   126 void ban(Client *c);
   131 void ban(Client *c);
   151 View *getview(Client *c);
   156 View *getview(Client *c);
   152 long getstate(Window w);
   157 long getstate(Window w);
   153 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
   158 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
   154 void grabbuttons(Client *c, Bool focused);
   159 void grabbuttons(Client *c, Bool focused);
   155 void grabkeys(void);
   160 void grabkeys(void);
   156 unsigned int idxoftag(const char *tag);
   161 unsigned int idxoftag(const char *t);
   157 void initfont(const char *fontstr);
   162 void initfont(const char *fontstr);
   158 Bool isoccupied(unsigned int t);
   163 Bool isoccupied(unsigned int t);
   159 Bool isprotodel(Client *c);
   164 Bool isprotodel(Client *c);
   160 Bool isurgent(unsigned int t);
   165 Bool isurgent(unsigned int t);
   161 Bool isvisible(Client *c);
   166 Bool isvisible(Client *c);
   206 /* variables */
   211 /* variables */
   207 char stext[256], buf[256];
   212 char stext[256], buf[256];
   208 int nviews = 1;
   213 int nviews = 1;
   209 View *selview;
   214 View *selview;
   210 int screen;
   215 int screen;
   211 int *seltags;
       
   212 int *prevtags;
       
   213 int (*xerrorxlib)(Display *, XErrorEvent *);
   216 int (*xerrorxlib)(Display *, XErrorEvent *);
   214 unsigned int bh, bpos;
   217 unsigned int bh, bpos;
   215 unsigned int blw = 0;
   218 unsigned int blw = 0;
   216 unsigned int numlockmask = 0;
   219 unsigned int numlockmask = 0;
   217 void (*handler[LASTEvent]) (XEvent *) = {
   220 void (*handler[LASTEvent]) (XEvent *) = {
   232 Bool isxinerama = False;
   235 Bool isxinerama = False;
   233 Bool domwfact = True;
   236 Bool domwfact = True;
   234 Bool dozoom = True;
   237 Bool dozoom = True;
   235 Bool otherwm, readin;
   238 Bool otherwm, readin;
   236 Bool running = True;
   239 Bool running = True;
       
   240 Bool *prevtags;
       
   241 Bool *seltags;
   237 Client *clients = NULL;
   242 Client *clients = NULL;
   238 Client *sel = NULL;
   243 Client *sel = NULL;
   239 Client *stack = NULL;
   244 Client *stack = NULL;
   240 Cursor cursor[CurLast];
   245 Cursor cursor[CurLast];
   241 Display *dpy;
   246 Display *dpy;
   246 /* configuration, allows nested code to access above variables */
   251 /* configuration, allows nested code to access above variables */
   247 #include "config.h"
   252 #include "config.h"
   248 
   253 
   249 /* function implementations */
   254 /* function implementations */
   250 void
   255 void
       
   256 addtag(Client *c, const char *t) {
       
   257 	unsigned int i, tidx = idxoftag(t);
       
   258 
       
   259 	for(i = 0; i < LENGTH(tags); i++)
       
   260 		if(c->tags[i] && vtags[i] != vtags[tidx])
       
   261 			return; /* conflict */
       
   262 	c->tags[tidx] = True;
       
   263 }
       
   264 
       
   265 void
   251 applyrules(Client *c) {
   266 applyrules(Client *c) {
   252 	unsigned int i;
   267 	unsigned int i;
   253 	Bool matched_tag = False;
   268 	Bool matched = False;
   254 	Rule *r;
   269 	Rule *r;
   255 	XClassHint ch = { 0 };
   270 	XClassHint ch = { 0 };
   256 
   271 
   257 	/* rule matching */
   272 	/* rule matching */
   258 	XGetClassHint(dpy, c->win, &ch);
   273 	XGetClassHint(dpy, c->win, &ch);
   259 	snprintf(buf, sizeof buf, "%s:%s:%s",
       
   260 			ch.res_class ? ch.res_class : "",
       
   261 			ch.res_name ? ch.res_name : "", c->name);
       
   262 	for(i = 0; i < LENGTH(rules); i++) {
   274 	for(i = 0; i < LENGTH(rules); i++) {
   263 		r = &rules[i];
   275 		r = &rules[i];
   264 		if(strstr(c->name, r->prop)
   276 		if(strstr(c->name, r->prop)
   265 		|| (ch.res_class && strstr(ch.res_class, r->prop))
   277 		|| (ch.res_class && strstr(ch.res_class, r->prop))
   266 		|| (ch.res_name && strstr(ch.res_name, r->prop)))
   278 		|| (ch.res_name && strstr(ch.res_name, r->prop)))
   267 		{
   279 		{
   268 			c->isfloating = r->isfloating;
   280 			c->isfloating = r->isfloating;
   269 			if(r->tag) {
   281 			if(r->tag) {
   270 				matched_tag = True;
   282 				addtag(c, r->tag);
   271 				c->tags[idxoftag(r->tag)] = selview->id;
   283 				matched = True;
   272 			}
   284 			}
   273 		}
   285 		}
   274 	}
   286 	}
   275 	if(ch.res_class)
   287 	if(ch.res_class)
   276 		XFree(ch.res_class);
   288 		XFree(ch.res_class);
   277 	if(ch.res_name)
   289 	if(ch.res_name)
   278 		XFree(ch.res_name);
   290 		XFree(ch.res_name);
   279 	if(!matched_tag)
   291 	if(!matched)
   280 		memcpy(c->tags, seltags, sizeof initags);
   292 		memcpy(c->tags, seltags, sizeof initags);
   281 }
   293 }
   282 
   294 
   283 
   295 
   284 
   296 
   530 
   542 
   531 	dc.x = 0;
   543 	dc.x = 0;
   532 	for(c = stack; c && (!isvisible(c) || getview(c) != v); c = c->snext);
   544 	for(c = stack; c && (!isvisible(c) || getview(c) != v); c = c->snext);
   533 	for(i = 0; i < LENGTH(tags); i++) {
   545 	for(i = 0; i < LENGTH(tags); i++) {
   534 		dc.w = textw(tags[i]);
   546 		dc.w = textw(tags[i]);
   535 		if(seltags[i] && seltags[i] == v->id) {
   547 		if(seltags[i]) {
   536 			drawtext(v, tags[i], dc.sel, isurgent(i));
   548 			drawtext(v, tags[i], dc.sel, isurgent(i));
   537 			drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.sel);
   549 			drawsquare(v, c && c->tags[i], isoccupied(i), isurgent(i), dc.sel);
   538 		}
   550 		}
   539 		else {
   551 		else {
   540 			drawtext(v, tags[i], dc.norm, isurgent(i));
   552 			drawtext(v, tags[i], dc.norm, isurgent(i));
   900 				GrabModeAsync, GrabModeAsync);
   912 				GrabModeAsync, GrabModeAsync);
   901 	}
   913 	}
   902 }
   914 }
   903 
   915 
   904 unsigned int
   916 unsigned int
   905 idxoftag(const char *tag) {
   917 idxoftag(const char *t) {
   906 	unsigned int i;
   918 	unsigned int i;
   907 
   919 
   908 	for(i = 0; (i < LENGTH(tags)) && (tags[i] != tag); i++);
   920 	for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++);
   909 	return (i < LENGTH(tags)) ? i : 0;
   921 	return (i < LENGTH(tags)) ? i : 0;
   910 }
   922 }
   911 
   923 
   912 void
   924 void
   913 initfont(const char *fontstr) {
   925 initfont(const char *fontstr) {
  1557 	memcpy(prevtags, initags, sizeof initags);
  1569 	memcpy(prevtags, initags, sizeof initags);
  1558 
  1570 
  1559 	for(i = 0; i < nviews; i++) {
  1571 	for(i = 0; i < nviews; i++) {
  1560 		/* init geometry */
  1572 		/* init geometry */
  1561 		v = &views[i];
  1573 		v = &views[i];
  1562 		v->id = i + 1;
       
  1563 
  1574 
  1564 		if(nviews != 1 && isxinerama) {
  1575 		if(nviews != 1 && isxinerama) {
  1565 
  1576 
  1566 #if defined(AIM_XINERAMA)
  1577 #if defined(AIM_XINERAMA)
  1567 v->w = DisplayWidth(dpy, screen) / 2;
  1578 v->w = DisplayWidth(dpy, screen) / 2;
  1651 	unsigned int i;
  1662 	unsigned int i;
  1652 
  1663 
  1653 	if(!sel)
  1664 	if(!sel)
  1654 		return;
  1665 		return;
  1655 	for(i = 0; i < LENGTH(tags); i++)
  1666 	for(i = 0; i < LENGTH(tags); i++)
  1656 		sel->tags[i] = (NULL == arg) ? selview->id : 0;
  1667 		sel->tags[i] = (NULL == arg);
  1657 	sel->tags[idxoftag(arg)] = selview->id;
  1668 	sel->tags[idxoftag(arg)] = True;
  1658 	arrange();
  1669 	arrange();
  1659 }
  1670 }
  1660 
  1671 
  1661 unsigned int
  1672 unsigned int
  1662 textnw(const char *text, unsigned int len) {
  1673 textnw(const char *text, unsigned int len) {
  1748 		return;
  1759 		return;
  1749 	i = idxoftag(arg);
  1760 	i = idxoftag(arg);
  1750 	sel->tags[i] = !sel->tags[i];
  1761 	sel->tags[i] = !sel->tags[i];
  1751 	for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++);
  1762 	for(j = 0; j < LENGTH(tags) && !sel->tags[j]; j++);
  1752 	if(j == LENGTH(tags))
  1763 	if(j == LENGTH(tags))
  1753 		sel->tags[i] = selview->id; /* at least one tag must be enabled */
  1764 		sel->tags[i] = True; /* at least one tag must be enabled */
  1754 	arrange();
  1765 	arrange();
  1755 }
  1766 }
  1756 
  1767 
  1757 void
  1768 void
  1758 toggleview(const char *arg) {
  1769 toggleview(const char *arg) {
  1760 
  1771 
  1761 	i = idxoftag(arg);
  1772 	i = idxoftag(arg);
  1762 	seltags[i] = !seltags[i];
  1773 	seltags[i] = !seltags[i];
  1763 	for(j = 0; j < LENGTH(tags) && !seltags[j]; j++);
  1774 	for(j = 0; j < LENGTH(tags) && !seltags[j]; j++);
  1764 	if(j == LENGTH(tags))
  1775 	if(j == LENGTH(tags))
  1765 		seltags[i] = selview->id; /* at least one tag must be viewed */
  1776 		seltags[i] = True; /* at least one tag must be viewed */
  1766 	arrange();
  1777 	arrange();
  1767 }
  1778 }
  1768 
  1779 
  1769 void
  1780 void
  1770 unban(Client *c) {
  1781 unban(Client *c) {
  1901 }
  1912 }
  1902 
  1913 
  1903 void
  1914 void
  1904 view(const char *arg) {
  1915 view(const char *arg) {
  1905 	unsigned int i;
  1916 	unsigned int i;
  1906 	int tmp[LENGTH(tags)];
  1917 	Bool tmp[LENGTH(tags)];
  1907 
  1918 
  1908 	for(i = 0; i < LENGTH(tags); i++)
  1919 	for(i = 0; i < LENGTH(tags); i++)
  1909 		tmp[i] = (NULL == arg) ? selview->id : 0;
  1920 		tmp[i] = (NULL == arg);
  1910 	tmp[idxoftag(arg)] = selview->id;
  1921 	tmp[idxoftag(arg)] = True;
       
  1922 
  1911 	if(memcmp(seltags, tmp, sizeof initags) != 0) {
  1923 	if(memcmp(seltags, tmp, sizeof initags) != 0) {
  1912 		memcpy(prevtags, seltags, sizeof initags);
  1924 		memcpy(prevtags, seltags, sizeof initags);
  1913 		memcpy(seltags, tmp, sizeof initags);
  1925 		memcpy(seltags, tmp, sizeof initags);
  1914 		arrange();
  1926 		arrange();
  1915 	}
  1927 	}