66 /* typedefs */ |
66 /* typedefs */ |
67 typedef struct Client Client; |
67 typedef struct Client Client; |
68 struct Client { |
68 struct Client { |
69 char name[256]; |
69 char name[256]; |
70 int x, y, w, h; |
70 int x, y, w, h; |
|
71 int fx, fy, fw, fh; |
71 int basew, baseh, incw, inch, maxw, maxh, minw, minh; |
72 int basew, baseh, incw, inch, maxw, maxh, minw, minh; |
72 int minax, maxax, minay, maxay; |
73 int minax, maxax, minay, maxay; |
73 long flags; |
74 long flags; |
74 unsigned int bw, oldbw; |
75 unsigned int bw, oldbw; |
75 Bool isbanned, isfixed, isfloating, isurgent; |
76 Bool isbanned, isfixed, isfloating, isurgent; |
142 void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
143 void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
143 void *emallocz(unsigned int size); |
144 void *emallocz(unsigned int size); |
144 void enternotify(XEvent *e); |
145 void enternotify(XEvent *e); |
145 void eprint(const char *errstr, ...); |
146 void eprint(const char *errstr, ...); |
146 void expose(XEvent *e); |
147 void expose(XEvent *e); |
147 void floating(void); /* default floating layout */ |
|
148 void focus(Client *c); |
148 void focus(Client *c); |
149 void focusin(XEvent *e); |
149 void focusin(XEvent *e); |
150 void focusnext(const char *arg); |
150 void focusnext(const char *arg); |
151 void focusprev(const char *arg); |
151 void focusprev(const char *arg); |
152 Client *getclient(Window w); |
152 Client *getclient(Window w); |
358 if(ev->button == Button1) { |
362 if(ev->button == Button1) { |
359 restack(); |
363 restack(); |
360 movemouse(c); |
364 movemouse(c); |
361 } |
365 } |
362 else if(ev->button == Button2) { |
366 else if(ev->button == Button2) { |
363 if((floating != lt->arrange) && c->isfloating) |
367 if(!lt->isfloating && c->isfloating) |
364 togglefloating(NULL); |
368 togglefloating(NULL); |
365 else |
369 else |
366 zoom(NULL); |
370 zoom(NULL); |
367 } |
371 } |
368 else if(ev->button == Button3 && !c->isfixed) { |
372 else if(ev->button == Button3 && !c->isfixed) { |
668 if(ev->count == 0 && (ev->window == barwin)) |
672 if(ev->count == 0 && (ev->window == barwin)) |
669 drawbar(); |
673 drawbar(); |
670 } |
674 } |
671 |
675 |
672 void |
676 void |
673 floating(void) { /* default floating layout */ |
|
674 Client *c; |
|
675 |
|
676 for(c = clients; c; c = c->next) |
|
677 if(isvisible(c)) |
|
678 resize(c, c->x, c->y, c->w, c->h, True); |
|
679 } |
|
680 |
|
681 void |
|
682 focus(Client *c) { |
677 focus(Client *c) { |
683 if(!c || (c && !isvisible(c))) |
678 if(!c || (c && !isvisible(c))) |
684 for(c = stack; c && !isvisible(c); c = c->snext); |
679 for(c = stack; c && !isvisible(c); c = c->snext); |
685 if(sel && sel != c) { |
680 if(sel && sel != c) { |
686 grabbuttons(sel, False); |
681 grabbuttons(sel, False); |
1008 c->y = wy + wh - c->h - 2 * c->bw; |
1003 c->y = wy + wh - c->h - 2 * c->bw; |
1009 c->x = MAX(c->x, wx); |
1004 c->x = MAX(c->x, wx); |
1010 c->y = MAX(c->y, wy); |
1005 c->y = MAX(c->y, wy); |
1011 c->bw = BORDERPX; |
1006 c->bw = BORDERPX; |
1012 } |
1007 } |
|
1008 c->fx = c->x; |
|
1009 c->fy = c->y; |
1013 |
1010 |
1014 wc.border_width = c->bw; |
1011 wc.border_width = c->bw; |
1015 XConfigureWindow(dpy, w, CWBorderWidth, &wc); |
1012 XConfigureWindow(dpy, w, CWBorderWidth, &wc); |
1016 XSetWindowBorder(dpy, w, dc.norm[ColBorder]); |
1013 XSetWindowBorder(dpy, w, dc.norm[ColBorder]); |
1017 configure(c); /* propagates border_width, if size doesn't change */ |
1014 configure(c); /* propagates border_width, if size doesn't change */ |
1103 ny = wy; |
1100 ny = wy; |
1104 else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP) |
1101 else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP) |
1105 ny = wy + wh - c->h - 2 * c->bw; |
1102 ny = wy + wh - c->h - 2 * c->bw; |
1106 if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP)) |
1103 if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP)) |
1107 togglefloating(NULL); |
1104 togglefloating(NULL); |
1108 if((lt->isfloating) || c->isfloating) |
1105 if(lt->isfloating || c->isfloating) { |
|
1106 c->fx = nx; |
|
1107 c->fy = ny; |
1109 resize(c, nx, ny, c->w, c->h, False); |
1108 resize(c, nx, ny, c->w, c->h, False); |
|
1109 } |
1110 break; |
1110 break; |
1111 } |
1111 } |
1112 } |
1112 } |
1113 } |
1113 } |
1114 |
1114 |
1259 break; |
1259 break; |
1260 case MotionNotify: |
1260 case MotionNotify: |
1261 XSync(dpy, False); |
1261 XSync(dpy, False); |
1262 nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); |
1262 nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); |
1263 nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); |
1263 nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); |
1264 if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) |
1264 if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP)) { |
|
1265 c->fx = c->x; |
|
1266 c->fy = c->y; |
1265 togglefloating(NULL); |
1267 togglefloating(NULL); |
1266 if((lt->isfloating) || c->isfloating) |
1268 } |
|
1269 if((lt->isfloating) || c->isfloating) { |
1267 resize(c, c->x, c->y, nw, nh, True); |
1270 resize(c, c->x, c->y, nw, nh, True); |
|
1271 c->fw = nw; |
|
1272 c->fh = nh; |
|
1273 } |
1268 break; |
1274 break; |
1269 } |
1275 } |
1270 } |
1276 } |
1271 } |
1277 } |
1272 |
1278 |
1282 if(sel->isfloating || lt->isfloating) |
1288 if(sel->isfloating || lt->isfloating) |
1283 XRaiseWindow(dpy, sel->win); |
1289 XRaiseWindow(dpy, sel->win); |
1284 if(!lt->isfloating) { |
1290 if(!lt->isfloating) { |
1285 wc.stack_mode = Below; |
1291 wc.stack_mode = Below; |
1286 wc.sibling = barwin; |
1292 wc.sibling = barwin; |
1287 if(!sel->isfloating) { |
1293 for(c = stack; c; c = c->snext) |
1288 XConfigureWindow(dpy, sel->win, CWSibling|CWStackMode, &wc); |
1294 if(!c->isfloating && isvisible(c)) { |
1289 wc.sibling = sel->win; |
1295 XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); |
1290 } |
1296 wc.sibling = c->win; |
1291 for(c = nexttiled(clients); c; c = nexttiled(c->next)) { |
1297 } |
1292 if(c == sel) |
|
1293 continue; |
|
1294 XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); |
|
1295 wc.sibling = c->win; |
|
1296 } |
|
1297 } |
1298 } |
1298 XSync(dpy, False); |
1299 XSync(dpy, False); |
1299 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
1300 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
1300 } |
1301 } |
1301 |
1302 |
1839 if(memcmp(seltags, tmp, TAGSZ) != 0) { |
1840 if(memcmp(seltags, tmp, TAGSZ) != 0) { |
1840 seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ |
1841 seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ |
1841 memcpy(seltags, tmp, TAGSZ); |
1842 memcpy(seltags, tmp, TAGSZ); |
1842 arrange(); |
1843 arrange(); |
1843 } |
1844 } |
|
1845 else |
|
1846 viewprevtag(NULL); |
1844 } |
1847 } |
1845 |
1848 |
1846 void |
1849 void |
1847 viewprevtag(const char *arg) { |
1850 viewprevtag(const char *arg) { |
1848 seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ |
1851 seltags = viewtags[viewtags_set ^= 1]; /* toggle tagset */ |
1883 |
1886 |
1884 void |
1887 void |
1885 zoom(const char *arg) { |
1888 zoom(const char *arg) { |
1886 Client *c = sel; |
1889 Client *c = sel; |
1887 |
1890 |
1888 if(!sel || lt->isfloating || sel->isfloating) |
|
1889 return; |
|
1890 if(c == nexttiled(clients)) |
1891 if(c == nexttiled(clients)) |
1891 if(!(c = nexttiled(c->next))) |
1892 if(!c || !(c = nexttiled(c->next))) |
1892 return; |
1893 return; |
1893 detach(c); |
1894 if(!lt->isfloating && !sel->isfloating) { |
1894 attach(c); |
1895 detach(c); |
1895 focus(c); |
1896 attach(c); |
|
1897 focus(c); |
|
1898 } |
1896 arrange(); |
1899 arrange(); |
1897 } |
1900 } |
1898 |
1901 |
1899 int |
1902 int |
1900 main(int argc, char *argv[]) { |
1903 main(int argc, char *argv[]) { |