diff --git a/README.md b/README.md index 5cc9935..4e8c117 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2020-03-25 - Added dragcfact patch + 2020-03-23 - Added stacker patch 2020-03-21 - Reworked a series of layouts to re-allocate remaining pixels following an even (or cfacts) split with the aim of presenting a pixel perfect layout. This affects the following layouts: tile, bstack, bstackhoriz, centered master, centered floating master, columns, deck, and corresponding flextile-deluxe layouts @@ -146,6 +148,9 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - updates the position of dmenu to match that of the bar - i.e. if topbar is 0 then dmenu will appear at the bottom and if 1 then dmenu will appear at the top + - dragcfact + - lets you resize clients' size (i.e. modify cfact) by holding modkey + shift and dragging the mouse + - [dragmfact](https://dwm.suckless.org/patches/dragmfact/) - lets you resize the split in the tile layout (i.e. modify mfact) by holding the modkey and dragging the mouse diff --git a/config.def.h b/config.def.h index 6fd948a..750285e 100644 --- a/config.def.h +++ b/config.def.h @@ -720,7 +720,7 @@ static Key keys[] = { #if CFACTS_PATCH { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, - { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + { MODKEY|ShiftMask, XK_o, setcfact, {0} }, #endif // CFACTS_PATCH #if MOVESTACK_PATCH { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, @@ -939,20 +939,23 @@ static Key keys[] = { /* button definitions */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, #if AWESOMEBAR_PATCH - { ClkWinTitle, 0, Button1, togglewin, {0} }, - { ClkWinTitle, 0, Button3, showhideclient, {0} }, + { ClkWinTitle, 0, Button1, togglewin, {0} }, + { ClkWinTitle, 0, Button3, showhideclient, {0} }, #endif // AWESOMEBAR_PATCH - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + #if DRAGCFACT_PATCH && CFACTS_PATCH + { ClkClientWin, MODKEY|ShiftMask, Button3, dragcfact, {0} }, + #endif // DRAGCFACT_PATCH + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; diff --git a/patch/cfacts.c b/patch/cfacts.c index 0307eb6..223436f 100644 --- a/patch/cfacts.c +++ b/patch/cfacts.c @@ -8,11 +8,14 @@ setcfact(const Arg *arg) if (!arg || !c || !selmon->lt[selmon->sellt]->arrange) return; - f = arg->f + c->cfact; - if (arg->f == 0.0) + if (!arg->f) f = 1.0; - else if (f < 0.25 || f > 4.0) - return; + else + f = arg->f + c->cfact; + if (f < 0.25) + f = 0.25; + else if (f > 4.0) + f = 4.0; c->cfact = f; arrange(selmon); } \ No newline at end of file diff --git a/patch/dragcfact.c b/patch/dragcfact.c new file mode 100644 index 0000000..205b12a --- /dev/null +++ b/patch/dragcfact.c @@ -0,0 +1,71 @@ +void +dragcfact(const Arg *arg) +{ + int prev_x, prev_y, dist_x, dist_y; + float fact; + Client *c; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfloating) /* no support rezising floating windows */ + return; + #if !FAKEFULLSCREEN_PATCH + #if FAKEFULLSCREEN_CLIENT_PATCH + if (c->isfullscreen && !c->fakefullscreen) /* no support resizing fullscreen windows by mouse */ + return; + #else + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; + #endif // FAKEFULLSCREEN_CLIENT_PATCH + #endif // !FAKEFULLSCREEN_PATCH + restack(selmon); + + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); + + prev_x = prev_y = -999999; + + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + if (prev_x == -999999) { + prev_x = ev.xmotion.x_root; + prev_y = ev.xmotion.y_root; + } + + dist_x = ev.xmotion.x - prev_x; + dist_y = ev.xmotion.y - prev_y; + + if (abs(dist_x) > abs(dist_y)) { + fact = (float) 4.0 * dist_x / c->mon->ww; + } else { + fact = (float) -4.0 * dist_y / c->mon->wh; + } + + setcfact(&((Arg) { .f = fact })); + + prev_x = ev.xmotion.x; + prev_y = ev.xmotion.y; + break; + } + } while (ev.type != ButtonRelease); + + + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); + + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} \ No newline at end of file diff --git a/patch/dragcfact.h b/patch/dragcfact.h new file mode 100644 index 0000000..6cf6b9c --- /dev/null +++ b/patch/dragcfact.h @@ -0,0 +1 @@ +static void dragcfact(const Arg *arg); \ No newline at end of file diff --git a/patch/include.c b/patch/include.c index 723147b..b881f4d 100644 --- a/patch/include.c +++ b/patch/include.c @@ -26,6 +26,9 @@ #if CYCLELAYOUTS_PATCH #include "cyclelayouts.c" #endif +#if DRAGCFACT_PATCH && CFACTS_PATCH +#include "dragcfact.c" +#endif #if DWMC_PATCH #include "dwmc.c" #elif FSIGNAL_PATCH diff --git a/patch/include.h b/patch/include.h index d97b503..9556675 100644 --- a/patch/include.h +++ b/patch/include.h @@ -26,6 +26,9 @@ #if CYCLELAYOUTS_PATCH #include "cyclelayouts.h" #endif +#if DRAGCFACT_PATCH && CFACTS_PATCH +#include "dragcfact.h" +#endif #if DWMC_PATCH #include "dwmc.h" #elif FSIGNAL_PATCH diff --git a/patches.def.h b/patches.def.h index 176ab90..4758ce2 100644 --- a/patches.def.h +++ b/patches.def.h @@ -126,6 +126,11 @@ */ #define DMENUMATCHTOP_PATCH 0 +/* Similarly to the dragmfact patch this allows you to click and drag clients to change the + * cfact to adjust the client's size in the stack. This patch depends on the cfacts patch. + */ +#define DRAGCFACT_PATCH 0 + /* This patch lets you resize the split in the tile layout (i.e. modify mfact) by holding * the modkey and dragging the mouse. * This patch can be a bit wonky with other layouts, but generally works.