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; |
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(); |