diff --git a/config.def.h.orig b/config.def.h.orig index bc4749f..7d612e6 100644 --- a/config.def.h.orig +++ b/config.def.h.orig @@ -109,6 +109,10 @@ static const Key keys[] = { { MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_Left, focusdir, {.i = 0 } }, // left + { MODKEY, XK_Right, focusdir, {.i = 1 } }, // right + { MODKEY, XK_Up, focusdir, {.i = 2 } }, // up + { MODKEY, XK_Down, focusdir, {.i = 3 } }, // down { MODKEY, XK_i, incnmaster, {.i = +1 } }, { MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, diff --git a/config.def.h.rej b/config.def.h.rej index 415fe60..dd1a041 100644 --- a/config.def.h.rej +++ b/config.def.h.rej @@ -1,25 +1,13 @@ --- config.def.h +++ config.def.h -@@ -3,6 +3,7 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ -+static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -@@ -26,9 +27,11 @@ static const Rule rules[] = { - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -- /* class instance title tags mask isfloating monitor */ -- { "Gimp", NULL, NULL, 0, 1, -1 }, -- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -+ /* class instance title tags mask isfloating isterminal noswallow monitor */ -+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, -+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 }, -+ { "St", NULL, NULL, 0, 0, 1, 0, -1 }, -+ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ - }; - - /* layout(s) */ +@@ -67,6 +67,10 @@ static const Key keys[] = { + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, ++ { MODKEY|ControlMask, XK_Left, placedir, {.i = 0 } }, // left ++ { MODKEY|ControlMask, XK_Right, placedir, {.i = 1 } }, // right ++ { MODKEY|ControlMask, XK_Up, placedir, {.i = 2 } }, // up ++ { MODKEY|ControlMask, XK_Down, placedir, {.i = 3 } }, // down + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, diff --git a/config.h b/config.h index f6728fc..511fb5f 100644 --- a/config.h +++ b/config.h @@ -123,10 +123,14 @@ static const Key keys[] = { { MODKEY, XK_i, incnmaster, {.i = +1 } }, { MODKEY, XK_p, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, focusdir, {.i = 0} }, - { MODKEY, XK_k, focusdir, {.i = 1 } }, - { MODKEY, XK_l, focusdir, {.i = 2 } }, + { MODKEY, XK_h, focusdir, {.i = 0 } }, + { MODKEY, XK_l, focusdir, {.i = 1 } }, + { MODKEY, XK_k, focusdir, {.i = 2 } }, { MODKEY, XK_j, focusdir, {.i = 3 } }, + { MODKEY|ShiftMask, XK_h, placedir, {.i = 0 } }, + { MODKEY|ShiftMask, XK_l, placedir, {.i = 1 } }, + { MODKEY|ShiftMask, XK_k, placedir, {.i = 2 } }, + { MODKEY|ShiftMask, XK_j, placedir, {.i = 3 } }, { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, diff --git a/dwm b/dwm index 0149747..e43878b 100755 Binary files a/dwm and b/dwm differ diff --git a/dwm.c b/dwm.c index 11f1677..938ba3e 100644 --- a/dwm.c +++ b/dwm.c @@ -228,6 +228,7 @@ static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); static Client *nexttagged(Client *c); static Client *nexttiled(Client *c); +static void placedir(const Arg *arg); static void pop(Client *c); static void propertynotify(XEvent *e); static void quit(const Arg *arg); @@ -1577,6 +1578,103 @@ nexttiled(Client *c) return c; } +void +placedir(const Arg *arg) +{ + Client *s = selmon->sel, *f = NULL, *c, *next, *fprior, *sprior; + + if (!s || s->isfloating) + return; + + unsigned int score = -1; + unsigned int client_score; + int dist; + int dirweight = 20; + + next = s->next; + if (!next) + next = s->mon->clients; + for (c = next; c != s; c = next) { + + next = c->next; + if (!next) + next = s->mon->clients; + + if (!ISVISIBLE(c)) // || HIDDEN(c) + continue; + + switch (arg->i) { + case 0: // left + dist = s->x - c->x - c->w; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + + abs(s->y - c->y); + break; + case 1: // right + dist = c->x - s->x - s->w; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + + abs(c->y - s->y); + break; + case 2: // up + dist = s->y - c->y - c->h; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + + abs(s->x - c->x); + break; + default: + case 3: // down + dist = c->y - s->y - s->h; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + + abs(c->x - s->x); + break; + } + + if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) { + score = client_score; + f = c; + } + } + + if (f && f != s) { + for (fprior = f->mon->clients; fprior && fprior->next != f; fprior = fprior->next); + for (sprior = s->mon->clients; sprior && sprior->next != s; sprior = sprior->next); + + if (s == fprior) { + next = f->next; + if (sprior) + sprior->next = f; + else + f->mon->clients = f; + f->next = s; + s->next = next; + } else if (f == sprior) { + next = s->next; + if (fprior) + fprior->next = s; + else + s->mon->clients = s; + s->next = f; + f->next = next; + } else { // clients are not adjacent to each other + next = f->next; + f->next = s->next; + s->next = next; + if (fprior) + fprior->next = s; + else + s->mon->clients = s; + if (sprior) + sprior->next = f; + else + f->mon->clients = f; + } + + arrange(f->mon); + } +} + void pop(Client *c) { diff --git a/dwm.c.orig b/dwm.c.orig index bbb0e1f..11f1677 100644 --- a/dwm.c.orig +++ b/dwm.c.orig @@ -206,6 +206,7 @@ static void drawbars(void); static void enternotify(XEvent *e); static void expose(XEvent *e); static void focus(Client *c); +static void focusdir(const Arg *arg); static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -1051,6 +1052,72 @@ focus(Client *c) drawbars(); } +void +focusdir(const Arg *arg) +{ + Client *s = selmon->sel, *f = NULL, *c, *next; + + if (!s) + return; + + unsigned int score = -1; + unsigned int client_score; + int dist; + int dirweight = 20; + int isfloating = s->isfloating; + + next = s->next; + if (!next) + next = s->mon->clients; + for (c = next; c != s; c = next) { + + next = c->next; + if (!next) + next = s->mon->clients; + + if (!ISVISIBLE(c) || c->isfloating != isfloating) // || HIDDEN(c) + continue; + + switch (arg->i) { + case 0: // left + dist = s->x - c->x - c->w; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + + abs(s->y - c->y); + break; + case 1: // right + dist = c->x - s->x - s->w; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + + abs(c->y - s->y); + break; + case 2: // up + dist = s->y - c->y - c->h; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + + abs(s->x - c->x); + break; + default: + case 3: // down + dist = c->y - s->y - s->h; + client_score = + dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + + abs(c->x - s->x); + break; + } + + if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) { + score = client_score; + f = c; + } + } + + if (f && f != s) { + focus(f); + restack(f->mon); + } +} + /* there are some broken focus acquiring clients needing extra handling */ void focusin(XEvent *e) diff --git a/dwm.o b/dwm.o index a6076d9..227e964 100644 Binary files a/dwm.o and b/dwm.o differ