|
|
|
@ -214,7 +214,7 @@ static void motionnotify(XEvent *e);
|
|
|
|
|
static void movemouse(const Arg *arg);
|
|
|
|
|
static Client *nexttagged(Client *c);
|
|
|
|
|
static Client *nexttiled(Client *c);
|
|
|
|
|
static void pop(Client *);
|
|
|
|
|
static void pop(Client *c);
|
|
|
|
|
static void propertynotify(XEvent *e);
|
|
|
|
|
static void quit(const Arg *arg);
|
|
|
|
|
static Monitor *recttomon(int x, int y, int w, int h);
|
|
|
|
@ -239,7 +239,7 @@ static void sigchld(int unused);
|
|
|
|
|
static void spawn(const Arg *arg);
|
|
|
|
|
static void tag(const Arg *arg);
|
|
|
|
|
static void tagmon(const Arg *arg);
|
|
|
|
|
static void tile(Monitor *);
|
|
|
|
|
static void tile(Monitor *m);
|
|
|
|
|
static void togglebar(const Arg *arg);
|
|
|
|
|
static void togglefloating(const Arg *arg);
|
|
|
|
|
static void toggletag(const Arg *arg);
|
|
|
|
@ -278,7 +278,7 @@ static const char broken[] = "broken";
|
|
|
|
|
static char stext[256];
|
|
|
|
|
static int screen;
|
|
|
|
|
static int sw, sh; /* X display screen geometry width, height */
|
|
|
|
|
static int bh, blw = 0; /* bar geometry */
|
|
|
|
|
static int bh; /* bar height */
|
|
|
|
|
static int lrpad; /* sum of left and right padding for text */
|
|
|
|
|
static int (*xerrorxlib)(Display *, XErrorEvent *);
|
|
|
|
|
static unsigned int numlockmask = 0;
|
|
|
|
@ -548,7 +548,7 @@ buttonpress(XEvent *e)
|
|
|
|
|
if (i < LENGTH(tags)) {
|
|
|
|
|
click = ClkTagBar;
|
|
|
|
|
arg.ui = 1 << i;
|
|
|
|
|
} else if (ev->x < x + blw)
|
|
|
|
|
} else if (ev->x < x + TEXTW(selmon->ltsymbol))
|
|
|
|
|
click = ClkLtSymbol;
|
|
|
|
|
else
|
|
|
|
|
click = ClkStatusText;
|
|
|
|
@ -840,7 +840,7 @@ drawbar(Monitor *m)
|
|
|
|
|
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
|
|
|
|
|
x += w;
|
|
|
|
|
}
|
|
|
|
|
w = blw = TEXTW(m->ltsymbol);
|
|
|
|
|
w = TEXTW(m->ltsymbol);
|
|
|
|
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
|
|
|
|
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
|
|
|
|
|
|
|
|
|
@ -1020,13 +1020,11 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
|
|
|
|
|
text[0] = '\0';
|
|
|
|
|
if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
|
|
|
|
|
return 0;
|
|
|
|
|
if (name.encoding == XA_STRING)
|
|
|
|
|
if (name.encoding == XA_STRING) {
|
|
|
|
|
strncpy(text, (char *)name.value, size - 1);
|
|
|
|
|
else {
|
|
|
|
|
if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
|
|
|
|
|
strncpy(text, *list, size - 1);
|
|
|
|
|
XFreeStringList(list);
|
|
|
|
|
}
|
|
|
|
|
} else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
|
|
|
|
|
strncpy(text, *list, size - 1);
|
|
|
|
|
XFreeStringList(list);
|
|
|
|
|
}
|
|
|
|
|
text[size - 1] = '\0';
|
|
|
|
|
XFree(name.value);
|
|
|
|
@ -1059,16 +1057,26 @@ grabkeys(void)
|
|
|
|
|
{
|
|
|
|
|
updatenumlockmask();
|
|
|
|
|
{
|
|
|
|
|
unsigned int i, j;
|
|
|
|
|
unsigned int i, j, k;
|
|
|
|
|
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
|
|
|
|
|
KeyCode code;
|
|
|
|
|
int start, end, skip;
|
|
|
|
|
KeySym *syms;
|
|
|
|
|
|
|
|
|
|
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
|
|
|
|
for (i = 0; i < LENGTH(keys); i++)
|
|
|
|
|
if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
|
|
|
|
|
for (j = 0; j < LENGTH(modifiers); j++)
|
|
|
|
|
XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
|
|
|
|
|
True, GrabModeAsync, GrabModeAsync);
|
|
|
|
|
XDisplayKeycodes(dpy, &start, &end);
|
|
|
|
|
syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
|
|
|
|
|
if (!syms)
|
|
|
|
|
return;
|
|
|
|
|
for (k = start; k <= end; k++)
|
|
|
|
|
for (i = 0; i < LENGTH(keys); i++)
|
|
|
|
|
/* skip modifier codes, we do that ourselves */
|
|
|
|
|
if (keys[i].keysym == syms[(k - start) * skip])
|
|
|
|
|
for (j = 0; j < LENGTH(modifiers); j++)
|
|
|
|
|
XGrabKey(dpy, k,
|
|
|
|
|
keys[i].mod | modifiers[j],
|
|
|
|
|
root, True,
|
|
|
|
|
GrabModeAsync, GrabModeAsync);
|
|
|
|
|
XFree(syms);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1150,14 +1158,12 @@ manage(Window w, XWindowAttributes *wa)
|
|
|
|
|
term = termforwin(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
|
|
|
|
|
c->x = c->mon->mx + c->mon->mw - WIDTH(c);
|
|
|
|
|
if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
|
|
|
|
|
c->y = c->mon->my + c->mon->mh - HEIGHT(c);
|
|
|
|
|
c->x = MAX(c->x, c->mon->mx);
|
|
|
|
|
/* only fix client y-offset, if the client center might cover the bar */
|
|
|
|
|
c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
|
|
|
|
|
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
|
|
|
|
|
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
|
|
|
|
|
c->x = c->mon->wx + c->mon->ww - WIDTH(c);
|
|
|
|
|
if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
|
|
|
|
|
c->y = c->mon->wy + c->mon->wh - HEIGHT(c);
|
|
|
|
|
c->x = MAX(c->x, c->mon->wx);
|
|
|
|
|
c->y = MAX(c->y, c->mon->wy);
|
|
|
|
|
c->bw = borderpx;
|
|
|
|
|
|
|
|
|
|
wc.border_width = c->bw;
|
|
|
|
@ -1165,6 +1171,7 @@ manage(Window w, XWindowAttributes *wa)
|
|
|
|
|
XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
|
|
|
|
|
configure(c); /* propagates border_width, if size doesn't change */
|
|
|
|
|
updatewindowtype(c);
|
|
|
|
|
updatesizehints(c);
|
|
|
|
|
updatewmhints(c);
|
|
|
|
|
if (c->iscentered) {
|
|
|
|
|
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
|
|
|
@ -1173,7 +1180,7 @@ manage(Window w, XWindowAttributes *wa)
|
|
|
|
|
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
|
|
|
|
grabbuttons(c, 0);
|
|
|
|
|
if (!c->isfloating)
|
|
|
|
|
c->isfloating = c->oldstate = t || c->isfixed;
|
|
|
|
|
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
|
|
|
|
if (c->isfloating)
|
|
|
|
|
XRaiseWindow(dpy, c->win);
|
|
|
|
|
attachaside(c);
|
|
|
|
@ -1208,9 +1215,7 @@ maprequest(XEvent *e)
|
|
|
|
|
static XWindowAttributes wa;
|
|
|
|
|
XMapRequestEvent *ev = &e->xmaprequest;
|
|
|
|
|
|
|
|
|
|
if (!XGetWindowAttributes(dpy, ev->window, &wa))
|
|
|
|
|
return;
|
|
|
|
|
if (wa.override_redirect)
|
|
|
|
|
if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect)
|
|
|
|
|
return;
|
|
|
|
|
if (!wintoclient(ev->window))
|
|
|
|
|
manage(ev->window, &wa);
|
|
|
|
@ -1737,7 +1742,6 @@ setup(void)
|
|
|
|
|
focus(NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
seturgent(Client *c, int urg)
|
|
|
|
|
{
|
|
|
|
@ -1787,9 +1791,7 @@ spawn(const Arg *arg)
|
|
|
|
|
close(ConnectionNumber(dpy));
|
|
|
|
|
setsid();
|
|
|
|
|
execvp(((char **)arg->v)[0], (char **)arg->v);
|
|
|
|
|
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
|
|
|
|
|
perror(" failed");
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1928,6 +1930,7 @@ unmanage(Client *c, int destroyed)
|
|
|
|
|
wc.border_width = c->oldbw;
|
|
|
|
|
XGrabServer(dpy); /* avoid race conditions */
|
|
|
|
|
XSetErrorHandler(xerrordummy);
|
|
|
|
|
XSelectInput(dpy, c->win, NoEventMask);
|
|
|
|
|
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
|
|
|
|
|
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
|
|
|
|
setclientstate(c, WithdrawnState);
|
|
|
|
@ -2408,12 +2411,10 @@ zoom(const Arg *arg)
|
|
|
|
|
{
|
|
|
|
|
Client *c = selmon->sel;
|
|
|
|
|
|
|
|
|
|
if (!selmon->lt[selmon->sellt]->arrange
|
|
|
|
|
|| (selmon->sel && selmon->sel->isfloating))
|
|
|
|
|
if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating)
|
|
|
|
|
return;
|
|
|
|
|
if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
|
|
|
|
|
return;
|
|
|
|
|
if (c == nexttiled(selmon->clients))
|
|
|
|
|
if (!c || !(c = nexttiled(c->next)))
|
|
|
|
|
return;
|
|
|
|
|
pop(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|