|
@ -54,7 +54,7 @@ |
|
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw) |
|
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw) |
|
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw) |
|
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw) |
|
|
#define TAGMASK ((1 << LENGTH(tags)) - 1) |
|
|
#define TAGMASK ((1 << LENGTH(tags)) - 1) |
|
|
#define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) |
|
|
|
|
|
|
|
|
#define TEXTW(X) (drw_font_getexts_width(drw->font, X, strlen(X)) + drw->font->h) |
|
|
|
|
|
|
|
|
/* enums */ |
|
|
/* enums */ |
|
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
|
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
|
@ -98,21 +98,6 @@ struct Client { |
|
|
Window win; |
|
|
Window win; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
int x, y, w, h; |
|
|
|
|
|
unsigned long norm[ColLast]; |
|
|
|
|
|
unsigned long sel[ColLast]; |
|
|
|
|
|
Drawable drawable; |
|
|
|
|
|
GC gc; |
|
|
|
|
|
struct { |
|
|
|
|
|
int ascent; |
|
|
|
|
|
int descent; |
|
|
|
|
|
int height; |
|
|
|
|
|
XFontSet set; |
|
|
|
|
|
XFontStruct *xfont; |
|
|
|
|
|
} font; |
|
|
|
|
|
} DC; /* draw context */ |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
typedef struct { |
|
|
unsigned int mod; |
|
|
unsigned int mod; |
|
|
KeySym keysym; |
|
|
KeySym keysym; |
|
@ -178,22 +163,18 @@ static void detachstack(Client *c); |
|
|
static Monitor *dirtomon(int dir); |
|
|
static Monitor *dirtomon(int dir); |
|
|
static void drawbar(Monitor *m); |
|
|
static void drawbar(Monitor *m); |
|
|
static void drawbars(void); |
|
|
static void drawbars(void); |
|
|
static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
|
|
|
|
|
static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
|
|
|
|
|
static void enternotify(XEvent *e); |
|
|
static void enternotify(XEvent *e); |
|
|
static void expose(XEvent *e); |
|
|
static void expose(XEvent *e); |
|
|
static void focus(Client *c); |
|
|
static void focus(Client *c); |
|
|
static void focusin(XEvent *e); |
|
|
static void focusin(XEvent *e); |
|
|
static void focusmon(const Arg *arg); |
|
|
static void focusmon(const Arg *arg); |
|
|
static void focusstack(const Arg *arg); |
|
|
static void focusstack(const Arg *arg); |
|
|
static unsigned long getcolor(const char *colstr); |
|
|
|
|
|
static Bool getrootptr(int *x, int *y); |
|
|
static Bool getrootptr(int *x, int *y); |
|
|
static long getstate(Window w); |
|
|
static long getstate(Window w); |
|
|
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
|
|
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
|
|
static void grabbuttons(Client *c, Bool focused); |
|
|
static void grabbuttons(Client *c, Bool focused); |
|
|
static void grabkeys(void); |
|
|
static void grabkeys(void); |
|
|
static void incnmaster(const Arg *arg); |
|
|
static void incnmaster(const Arg *arg); |
|
|
static void initfont(const char *fontstr); |
|
|
|
|
|
static void keypress(XEvent *e); |
|
|
static void keypress(XEvent *e); |
|
|
static void killclient(const Arg *arg); |
|
|
static void killclient(const Arg *arg); |
|
|
static void manage(Window w, XWindowAttributes *wa); |
|
|
static void manage(Window w, XWindowAttributes *wa); |
|
@ -226,7 +207,6 @@ static void sigchld(int unused); |
|
|
static void spawn(const Arg *arg); |
|
|
static void spawn(const Arg *arg); |
|
|
static void tag(const Arg *arg); |
|
|
static void tag(const Arg *arg); |
|
|
static void tagmon(const Arg *arg); |
|
|
static void tagmon(const Arg *arg); |
|
|
static int textnw(const char *text, unsigned int len); |
|
|
|
|
|
static void tile(Monitor *); |
|
|
static void tile(Monitor *); |
|
|
static void togglebar(const Arg *arg); |
|
|
static void togglebar(const Arg *arg); |
|
|
static void togglefloating(const Arg *arg); |
|
|
static void togglefloating(const Arg *arg); |
|
@ -279,10 +259,13 @@ static void (*handler[LASTEvent]) (XEvent *) = { |
|
|
}; |
|
|
}; |
|
|
static Atom wmatom[WMLast], netatom[NetLast]; |
|
|
static Atom wmatom[WMLast], netatom[NetLast]; |
|
|
static Bool running = True; |
|
|
static Bool running = True; |
|
|
static Cursor cursor[CurLast]; |
|
|
|
|
|
|
|
|
static Cur *cursor[CurLast]; |
|
|
|
|
|
static Theme thmnorm[ColLast]; |
|
|
|
|
|
static Theme thmsel[ColLast]; |
|
|
static Display *dpy; |
|
|
static Display *dpy; |
|
|
static DC dc; |
|
|
|
|
|
static Monitor *mons = NULL, *selmon = NULL; |
|
|
|
|
|
|
|
|
static Drw *drw; |
|
|
|
|
|
static Fnt *fnt; |
|
|
|
|
|
static Monitor *mons, *selmon; |
|
|
static Window root; |
|
|
static Window root; |
|
|
|
|
|
|
|
|
/* configuration, allows nested code to access above variables */ |
|
|
/* configuration, allows nested code to access above variables */ |
|
@ -486,18 +469,20 @@ cleanup(void) { |
|
|
for(m = mons; m; m = m->next) |
|
|
for(m = mons; m; m = m->next) |
|
|
while(m->stack) |
|
|
while(m->stack) |
|
|
unmanage(m->stack, False); |
|
|
unmanage(m->stack, False); |
|
|
if(dc.font.set) |
|
|
|
|
|
XFreeFontSet(dpy, dc.font.set); |
|
|
|
|
|
else |
|
|
|
|
|
XFreeFont(dpy, dc.font.xfont); |
|
|
|
|
|
XUngrabKey(dpy, AnyKey, AnyModifier, root); |
|
|
XUngrabKey(dpy, AnyKey, AnyModifier, root); |
|
|
XFreePixmap(dpy, dc.drawable); |
|
|
|
|
|
XFreeGC(dpy, dc.gc); |
|
|
|
|
|
XFreeCursor(dpy, cursor[CurNormal]); |
|
|
|
|
|
XFreeCursor(dpy, cursor[CurResize]); |
|
|
|
|
|
XFreeCursor(dpy, cursor[CurMove]); |
|
|
|
|
|
while(mons) |
|
|
while(mons) |
|
|
cleanupmon(mons); |
|
|
cleanupmon(mons); |
|
|
|
|
|
drw_cur_free(drw, cursor[CurNormal]); |
|
|
|
|
|
drw_cur_free(drw, cursor[CurResize]); |
|
|
|
|
|
drw_cur_free(drw, cursor[CurMove]); |
|
|
|
|
|
drw_font_free(dpy, fnt); |
|
|
|
|
|
drw_clr_free(thmnorm->border); |
|
|
|
|
|
drw_clr_free(thmnorm->bg); |
|
|
|
|
|
drw_clr_free(thmnorm->fg); |
|
|
|
|
|
drw_clr_free(thmsel->border); |
|
|
|
|
|
drw_clr_free(thmsel->bg); |
|
|
|
|
|
drw_clr_free(thmsel->fg); |
|
|
|
|
|
drw_free(drw); |
|
|
XSync(dpy, False); |
|
|
XSync(dpy, False); |
|
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
|
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
|
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]); |
|
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]); |
|
@ -581,9 +566,7 @@ configurenotify(XEvent *e) { |
|
|
sw = ev->width; |
|
|
sw = ev->width; |
|
|
sh = ev->height; |
|
|
sh = ev->height; |
|
|
if(updategeom() || dirty) { |
|
|
if(updategeom() || dirty) { |
|
|
if(dc.drawable != 0) |
|
|
|
|
|
XFreePixmap(dpy, dc.drawable); |
|
|
|
|
|
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); |
|
|
|
|
|
|
|
|
drw_resize(drw, sw, bh); |
|
|
updatebars(); |
|
|
updatebars(); |
|
|
for(m = mons; m; m = m->next) |
|
|
for(m = mons; m; m = m->next) |
|
|
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
|
|
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); |
|
@ -710,9 +693,8 @@ dirtomon(int dir) { |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
drawbar(Monitor *m) { |
|
|
drawbar(Monitor *m) { |
|
|
int x; |
|
|
|
|
|
|
|
|
int x, xx, w; |
|
|
unsigned int i, occ = 0, urg = 0; |
|
|
unsigned int i, occ = 0, urg = 0; |
|
|
unsigned long *col; |
|
|
|
|
|
Client *c; |
|
|
Client *c; |
|
|
|
|
|
|
|
|
for(c = m->clients; c; c = c->next) { |
|
|
for(c = m->clients; c; c = c->next) { |
|
@ -720,42 +702,44 @@ drawbar(Monitor *m) { |
|
|
if(c->isurgent) |
|
|
if(c->isurgent) |
|
|
urg |= c->tags; |
|
|
urg |= c->tags; |
|
|
} |
|
|
} |
|
|
dc.x = 0; |
|
|
|
|
|
|
|
|
x = 0; |
|
|
for(i = 0; i < LENGTH(tags); i++) { |
|
|
for(i = 0; i < LENGTH(tags); i++) { |
|
|
dc.w = TEXTW(tags[i]); |
|
|
|
|
|
col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; |
|
|
|
|
|
drawtext(tags[i], col, urg & 1 << i); |
|
|
|
|
|
drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, |
|
|
|
|
|
occ & 1 << i, urg & 1 << i, col); |
|
|
|
|
|
dc.x += dc.w; |
|
|
|
|
|
} |
|
|
|
|
|
dc.w = blw = TEXTW(m->ltsymbol); |
|
|
|
|
|
drawtext(m->ltsymbol, dc.norm, False); |
|
|
|
|
|
dc.x += dc.w; |
|
|
|
|
|
x = dc.x; |
|
|
|
|
|
|
|
|
w = TEXTW(tags[i]); |
|
|
|
|
|
drw_settheme(drw, m->tagset[m->seltags] & 1 << i ? thmsel : thmnorm); |
|
|
|
|
|
drw_text(drw, x, 0, w, bh, tags[i], urg & 1 << i); |
|
|
|
|
|
drw_rect(drw, x, 0, w, bh, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, |
|
|
|
|
|
occ & 1 << i, urg & 1 << i); |
|
|
|
|
|
x += w; |
|
|
|
|
|
} |
|
|
|
|
|
w = blw = TEXTW(m->ltsymbol); |
|
|
|
|
|
drw_settheme(drw, thmnorm); |
|
|
|
|
|
drw_text(drw, x, 0, w, bh, m->ltsymbol, 0); |
|
|
|
|
|
x += w; |
|
|
|
|
|
xx = x; |
|
|
if(m == selmon) { /* status is only drawn on selected monitor */ |
|
|
if(m == selmon) { /* status is only drawn on selected monitor */ |
|
|
dc.w = TEXTW(stext); |
|
|
|
|
|
dc.x = m->ww - dc.w; |
|
|
|
|
|
if(dc.x < x) { |
|
|
|
|
|
dc.x = x; |
|
|
|
|
|
dc.w = m->ww - x; |
|
|
|
|
|
|
|
|
w = TEXTW(stext); |
|
|
|
|
|
x = m->ww - w; |
|
|
|
|
|
if(x < xx) { |
|
|
|
|
|
x = xx; |
|
|
|
|
|
w = m->ww - xx; |
|
|
} |
|
|
} |
|
|
drawtext(stext, dc.norm, False); |
|
|
|
|
|
|
|
|
drw_text(drw, x, 0, w, bh, stext, 0); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
dc.x = m->ww; |
|
|
|
|
|
if((dc.w = dc.x - x) > bh) { |
|
|
|
|
|
dc.x = x; |
|
|
|
|
|
|
|
|
x = m->ww; |
|
|
|
|
|
if((w = x - xx) > bh) { |
|
|
|
|
|
x = xx; |
|
|
if(m->sel) { |
|
|
if(m->sel) { |
|
|
col = m == selmon ? dc.sel : dc.norm; |
|
|
|
|
|
drawtext(m->sel->name, col, False); |
|
|
|
|
|
drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); |
|
|
|
|
|
|
|
|
drw_settheme(drw, m == selmon ? thmsel : thmnorm); |
|
|
|
|
|
drw_text(drw, x, 0, w, bh, m->sel->name, 0); |
|
|
|
|
|
drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, 0); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
drw_settheme(drw, thmnorm); |
|
|
|
|
|
drw_text(drw, x, 0, w, bh, NULL, 0); |
|
|
} |
|
|
} |
|
|
else |
|
|
|
|
|
drawtext(NULL, dc.norm, False); |
|
|
|
|
|
} |
|
|
} |
|
|
XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); |
|
|
|
|
|
XSync(dpy, False); |
|
|
|
|
|
|
|
|
drw_map(drw, m->barwin, 0, 0, m->ww, bh); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
@ -766,45 +750,6 @@ drawbars(void) { |
|
|
drawbar(m); |
|
|
drawbar(m); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { |
|
|
|
|
|
int x; |
|
|
|
|
|
|
|
|
|
|
|
XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); |
|
|
|
|
|
x = (dc.font.ascent + dc.font.descent + 2) / 4; |
|
|
|
|
|
if(filled) |
|
|
|
|
|
XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1); |
|
|
|
|
|
else if(empty) |
|
|
|
|
|
XDrawRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x, x); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
drawtext(const char *text, unsigned long col[ColLast], Bool invert) { |
|
|
|
|
|
char buf[256]; |
|
|
|
|
|
int i, x, y, h, len, olen; |
|
|
|
|
|
|
|
|
|
|
|
XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); |
|
|
|
|
|
XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h); |
|
|
|
|
|
if(!text) |
|
|
|
|
|
return; |
|
|
|
|
|
olen = strlen(text); |
|
|
|
|
|
h = dc.font.ascent + dc.font.descent; |
|
|
|
|
|
y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; |
|
|
|
|
|
x = dc.x + (h / 2); |
|
|
|
|
|
/* shorten text if necessary */ |
|
|
|
|
|
for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); |
|
|
|
|
|
if(!len) |
|
|
|
|
|
return; |
|
|
|
|
|
memcpy(buf, text, len); |
|
|
|
|
|
if(len < olen) |
|
|
|
|
|
for(i = len; i && i > len - 3; buf[--i] = '.'); |
|
|
|
|
|
XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); |
|
|
|
|
|
if(dc.font.set) |
|
|
|
|
|
XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); |
|
|
|
|
|
else |
|
|
|
|
|
XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
enternotify(XEvent *e) { |
|
|
enternotify(XEvent *e) { |
|
|
Client *c; |
|
|
Client *c; |
|
@ -848,7 +793,7 @@ focus(Client *c) { |
|
|
detachstack(c); |
|
|
detachstack(c); |
|
|
attachstack(c); |
|
|
attachstack(c); |
|
|
grabbuttons(c, True); |
|
|
grabbuttons(c, True); |
|
|
XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); |
|
|
|
|
|
|
|
|
XSetWindowBorder(dpy, c->win, thmsel->border->rgb); |
|
|
setfocus(c); |
|
|
setfocus(c); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
@ -922,16 +867,6 @@ getatomprop(Client *c, Atom prop) { |
|
|
return atom; |
|
|
return atom; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
unsigned long |
|
|
|
|
|
getcolor(const char *colstr) { |
|
|
|
|
|
Colormap cmap = DefaultColormap(dpy, screen); |
|
|
|
|
|
XColor color; |
|
|
|
|
|
|
|
|
|
|
|
if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) |
|
|
|
|
|
die("error, cannot allocate color '%s'\n", colstr); |
|
|
|
|
|
return color.pixel; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Bool |
|
|
Bool |
|
|
getrootptr(int *x, int *y) { |
|
|
getrootptr(int *x, int *y) { |
|
|
int di; |
|
|
int di; |
|
@ -1028,40 +963,6 @@ incnmaster(const Arg *arg) { |
|
|
arrange(selmon); |
|
|
arrange(selmon); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
initfont(const char *fontstr) { |
|
|
|
|
|
char *def, **missing; |
|
|
|
|
|
int n; |
|
|
|
|
|
|
|
|
|
|
|
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); |
|
|
|
|
|
if(missing) { |
|
|
|
|
|
while(n--) |
|
|
|
|
|
fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]); |
|
|
|
|
|
XFreeStringList(missing); |
|
|
|
|
|
} |
|
|
|
|
|
if(dc.font.set) { |
|
|
|
|
|
XFontStruct **xfonts; |
|
|
|
|
|
char **font_names; |
|
|
|
|
|
|
|
|
|
|
|
dc.font.ascent = dc.font.descent = 0; |
|
|
|
|
|
XExtentsOfFontSet(dc.font.set); |
|
|
|
|
|
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); |
|
|
|
|
|
while(n--) { |
|
|
|
|
|
dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); |
|
|
|
|
|
dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent); |
|
|
|
|
|
xfonts++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) |
|
|
|
|
|
&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) |
|
|
|
|
|
die("error, cannot load font: '%s'\n", fontstr); |
|
|
|
|
|
dc.font.ascent = dc.font.xfont->ascent; |
|
|
|
|
|
dc.font.descent = dc.font.xfont->descent; |
|
|
|
|
|
} |
|
|
|
|
|
dc.font.height = dc.font.ascent + dc.font.descent; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef XINERAMA |
|
|
#ifdef XINERAMA |
|
|
static Bool |
|
|
static Bool |
|
|
isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { |
|
|
isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { |
|
@ -1140,7 +1041,7 @@ manage(Window w, XWindowAttributes *wa) { |
|
|
|
|
|
|
|
|
wc.border_width = c->bw; |
|
|
wc.border_width = c->bw; |
|
|
XConfigureWindow(dpy, w, CWBorderWidth, &wc); |
|
|
XConfigureWindow(dpy, w, CWBorderWidth, &wc); |
|
|
XSetWindowBorder(dpy, w, dc.norm[ColBorder]); |
|
|
|
|
|
|
|
|
XSetWindowBorder(dpy, w, thmnorm->border->rgb); |
|
|
configure(c); /* propagates border_width, if size doesn't change */ |
|
|
configure(c); /* propagates border_width, if size doesn't change */ |
|
|
updatewindowtype(c); |
|
|
updatewindowtype(c); |
|
|
updatesizehints(c); |
|
|
updatesizehints(c); |
|
@ -1232,7 +1133,7 @@ movemouse(const Arg *arg) { |
|
|
ocx = c->x; |
|
|
ocx = c->x; |
|
|
ocy = c->y; |
|
|
ocy = c->y; |
|
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
|
None, cursor[CurMove], CurrentTime) != GrabSuccess) |
|
|
|
|
|
|
|
|
None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) |
|
|
return; |
|
|
return; |
|
|
if(!getrootptr(&x, &y)) |
|
|
if(!getrootptr(&x, &y)) |
|
|
return; |
|
|
return; |
|
@ -1378,7 +1279,7 @@ resizemouse(const Arg *arg) { |
|
|
ocx = c->x; |
|
|
ocx = c->x; |
|
|
ocy = c->y; |
|
|
ocy = c->y; |
|
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
|
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, |
|
|
None, cursor[CurResize], CurrentTime) != GrabSuccess) |
|
|
|
|
|
|
|
|
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) |
|
|
return; |
|
|
return; |
|
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); |
|
|
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); |
|
|
do { |
|
|
do { |
|
@ -1597,10 +1498,12 @@ setup(void) { |
|
|
/* init screen */ |
|
|
/* init screen */ |
|
|
screen = DefaultScreen(dpy); |
|
|
screen = DefaultScreen(dpy); |
|
|
root = RootWindow(dpy, screen); |
|
|
root = RootWindow(dpy, screen); |
|
|
initfont(font); |
|
|
|
|
|
|
|
|
fnt = drw_font_create(dpy, font); |
|
|
sw = DisplayWidth(dpy, screen); |
|
|
sw = DisplayWidth(dpy, screen); |
|
|
sh = DisplayHeight(dpy, screen); |
|
|
sh = DisplayHeight(dpy, screen); |
|
|
bh = dc.h = dc.font.height + 2; |
|
|
|
|
|
|
|
|
bh = fnt->h + 2; |
|
|
|
|
|
drw = drw_create(dpy, screen, root, sw, sh); |
|
|
|
|
|
drw_setfont(drw, fnt); |
|
|
updategeom(); |
|
|
updategeom(); |
|
|
/* init atoms */ |
|
|
/* init atoms */ |
|
|
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); |
|
|
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); |
|
@ -1616,21 +1519,16 @@ setup(void) { |
|
|
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); |
|
|
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); |
|
|
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); |
|
|
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); |
|
|
/* init cursors */ |
|
|
/* init cursors */ |
|
|
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); |
|
|
|
|
|
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); |
|
|
|
|
|
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); |
|
|
|
|
|
|
|
|
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); |
|
|
|
|
|
cursor[CurResize] = drw_cur_create(drw, XC_sizing); |
|
|
|
|
|
cursor[CurMove] = drw_cur_create(drw, XC_fleur); |
|
|
/* init appearance */ |
|
|
/* init appearance */ |
|
|
dc.norm[ColBorder] = getcolor(normbordercolor); |
|
|
|
|
|
dc.norm[ColBG] = getcolor(normbgcolor); |
|
|
|
|
|
dc.norm[ColFG] = getcolor(normfgcolor); |
|
|
|
|
|
dc.sel[ColBorder] = getcolor(selbordercolor); |
|
|
|
|
|
dc.sel[ColBG] = getcolor(selbgcolor); |
|
|
|
|
|
dc.sel[ColFG] = getcolor(selfgcolor); |
|
|
|
|
|
dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); |
|
|
|
|
|
dc.gc = XCreateGC(dpy, root, 0, NULL); |
|
|
|
|
|
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); |
|
|
|
|
|
if(!dc.font.set) |
|
|
|
|
|
XSetFont(dpy, dc.gc, dc.font.xfont->fid); |
|
|
|
|
|
|
|
|
thmnorm->border = drw_clr_create(drw, normbordercolor); |
|
|
|
|
|
thmnorm->bg = drw_clr_create(drw, normbgcolor); |
|
|
|
|
|
thmnorm->fg = drw_clr_create(drw, normfgcolor); |
|
|
|
|
|
thmsel->border = drw_clr_create(drw, selbordercolor); |
|
|
|
|
|
thmsel->bg = drw_clr_create(drw, selbgcolor); |
|
|
|
|
|
thmsel->fg = drw_clr_create(drw, selfgcolor); |
|
|
/* init bars */ |
|
|
/* init bars */ |
|
|
updatebars(); |
|
|
updatebars(); |
|
|
updatestatus(); |
|
|
updatestatus(); |
|
@ -1639,7 +1537,7 @@ setup(void) { |
|
|
PropModeReplace, (unsigned char *) netatom, NetLast); |
|
|
PropModeReplace, (unsigned char *) netatom, NetLast); |
|
|
XDeleteProperty(dpy, root, netatom[NetClientList]); |
|
|
XDeleteProperty(dpy, root, netatom[NetClientList]); |
|
|
/* select for events */ |
|
|
/* select for events */ |
|
|
wa.cursor = cursor[CurNormal]; |
|
|
|
|
|
|
|
|
wa.cursor = cursor[CurNormal]->cursor; |
|
|
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask |
|
|
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask |
|
|
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; |
|
|
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; |
|
|
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); |
|
|
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); |
|
@ -1699,17 +1597,6 @@ tagmon(const Arg *arg) { |
|
|
sendmon(selmon->sel, dirtomon(arg->i)); |
|
|
sendmon(selmon->sel, dirtomon(arg->i)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
textnw(const 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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
tile(Monitor *m) { |
|
|
tile(Monitor *m) { |
|
|
unsigned int i, n, h, mw, my, ty; |
|
|
unsigned int i, n, h, mw, my, ty; |
|
@ -1787,7 +1674,7 @@ unfocus(Client *c, Bool setfocus) { |
|
|
if(!c) |
|
|
if(!c) |
|
|
return; |
|
|
return; |
|
|
grabbuttons(c, False); |
|
|
grabbuttons(c, False); |
|
|
XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); |
|
|
|
|
|
|
|
|
XSetWindowBorder(dpy, c->win, thmnorm->border->rgb); |
|
|
if(setfocus) { |
|
|
if(setfocus) { |
|
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
|
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
|
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]); |
|
|
XDeleteProperty(dpy, root, netatom[NetActiveWindow]); |
|
@ -1846,7 +1733,7 @@ updatebars(void) { |
|
|
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), |
|
|
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), |
|
|
CopyFromParent, DefaultVisual(dpy, screen), |
|
|
CopyFromParent, DefaultVisual(dpy, screen), |
|
|
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); |
|
|
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); |
|
|
XDefineCursor(dpy, m->barwin, cursor[CurNormal]); |
|
|
|
|
|
|
|
|
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); |
|
|
XMapRaised(dpy, m->barwin); |
|
|
XMapRaised(dpy, m->barwin); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|