diff --git a/README.md b/README.md index 302c77d..1e04213 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2019-10-04 - Added maximize patch + 2019-10-03 - Added onlyquitonempty and switchcol patches 2019-10-02 - Added restartsig, emptyview, focusurgent and focusadjacenttag patches @@ -133,6 +135,9 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - it is also possible to spawn new windows (e.g. a terminal) that end up getting focus while the previous window remains in fullscreen - this patch ensures that in such scenarios the previous window loses fullscreen + - [maximize](https://dwm.suckless.org/patches/maximize/) + - adds helper functions for maximizing, horizontally and vertically, floating windows using keybindings + - monitorrules - adds rules per monitor, e.g. have default layouts per monitor - the use case for this is if the second monitor is vertical (i.e. rotated) then you may want to use a different default layout for this monitor than what is used for the main monitor (for example normal vertical split for main monitor and horizontal split for the second) diff --git a/config.def.h b/config.def.h index 33d4436..1cda331 100644 --- a/config.def.h +++ b/config.def.h @@ -313,137 +313,144 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, static const char *termcmd[] = { "st", NULL }; static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, #if ROTATESTACK_PATCH - { MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } }, + { MODKEY|ShiftMask, XK_j, rotatestack, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, rotatestack, {.i = -1 } }, #endif // ROTATESTACK_PATCH #if PUSH_PATCH || PUSH_NO_MASTER_PATCH - { MODKEY|ControlMask, XK_j, pushdown, {0} }, - { MODKEY|ControlMask, XK_k, pushup, {0} }, + { MODKEY|ControlMask, XK_j, pushdown, {0} }, + { MODKEY|ControlMask, XK_k, pushup, {0} }, #endif // PUSH_PATCH / PUSH_NO_MASTER_PATCH - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, #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_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, #endif // CFACTS_PATCH - { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Return, zoom, {0} }, #if VANITYGAPS_PATCH - { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, - { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, - { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, + { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, + { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, #endif // VANITYGAPS_PATCH - { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_Tab, view, {0} }, #if AWESOMEBAR_PATCH - { MODKEY, XK_z, showhideclient, {0} }, + { MODKEY, XK_z, showhideclient, {0} }, #endif // AWESOMEBAR_PATCH - { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, #if SELFRESTART_PATCH - { MODKEY|ShiftMask, XK_r, self_restart, {0} }, + { MODKEY|ShiftMask, XK_r, self_restart, {0} }, #endif // SELFRESTART_PATCH - { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY|ShiftMask, XK_q, quit, {0} }, #if RESTARTSIG_PATCH - { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, + { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, #endif // RESTARTSIG_PATCH #if FOCUSURGENT_PATCH - { MODKEY, XK_u, focusurgent, {0} }, + { MODKEY, XK_u, focusurgent, {0} }, #endif // FOCUSURGENT_PATCH #if HOLDBAR_PATCH - { 0, HOLDKEY, holdbar, {0} }, + { 0, HOLDKEY, holdbar, {0} }, #endif // HOLDBAR_PATCH #if WINVIEW_PATCH - { MODKEY, XK_o, winview, {0} }, + { MODKEY, XK_o, winview, {0} }, #endif // WINVIEW_PATCH #if XRDB_PATCH - { MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } }, + { MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } }, #endif // XRDB_PATCH - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, #if FLEXTILE_DELUXE_LAYOUT - { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0 } }, /* flextile, 0 = layout axis */ - { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1 } }, /* flextile, 1 = master axis */ - { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2 } }, /* flextile, 2 = stack axis */ - { MODKEY|ControlMask|Mod1Mask, XK_Tab, rotatelayoutaxis, {.i = 3 } }, /* flextile, 3 = secondary stack axis */ - { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, /* flextile, flip master and stack areas */ + { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0 } }, /* flextile, 0 = layout axis */ + { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1 } }, /* flextile, 1 = master axis */ + { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2 } }, /* flextile, 2 = stack axis */ + { MODKEY|ControlMask|Mod1Mask, XK_Tab, rotatelayoutaxis, {.i = 3 } }, /* flextile, 3 = secondary stack axis */ + { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, /* flextile, flip master and stack areas */ #endif // FLEXTILE_DELUXE_LAYOUT - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + #if MAXIMIZE_PATCH + { MODKEY|ControlMask|ShiftMask, XK_h, togglehorizontalmax, {0} }, + { MODKEY|ControlMask|ShiftMask, XK_l, togglehorizontalmax, {0} }, + { MODKEY|ControlMask|ShiftMask, XK_j, toggleverticalmax, {0} }, + { MODKEY|ControlMask|ShiftMask, XK_k, toggleverticalmax, {0} }, + { MODKEY|ControlMask, XK_m, togglemaximize, {0} }, + #endif // MAXIMIZE_PATCH #if UNFLOATVISIBLE_PATCH - { MODKEY|Mod4Mask, XK_space, unfloatvisible, {0} }, - { MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[0]} }, + { MODKEY|Mod4Mask, XK_space, unfloatvisible, {0} }, + { MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[0]} }, #endif // UNFLOATVISIBLE_PATCH #if TOGGLEFULLSCREEN_PATCH - { MODKEY, XK_y, togglefullscreen, {0} }, + { MODKEY, XK_y, togglefullscreen, {0} }, #endif // TOGGLEFULLSCREEN_PATCH #if STICKY_PATCH - { MODKEY, XK_s, togglesticky, {0} }, + { MODKEY, XK_s, togglesticky, {0} }, #endif // STICKY_PATCH - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, #if FOCUSADJACENTTAG_PATCH - { MODKEY, XK_Left, viewtoleft, {0} }, - { MODKEY, XK_Right, viewtoright, {0} }, - { MODKEY|ShiftMask, XK_Left, tagtoleft, {0} }, - { MODKEY|ShiftMask, XK_Right, tagtoright, {0} }, - { MODKEY|ControlMask, XK_Left, tagandviewtoleft, {0} }, - { MODKEY|ControlMask, XK_Right, tagandviewtoright, {0} }, + { MODKEY, XK_Left, viewtoleft, {0} }, + { MODKEY, XK_Right, viewtoright, {0} }, + { MODKEY|ShiftMask, XK_Left, tagtoleft, {0} }, + { MODKEY|ShiftMask, XK_Right, tagtoright, {0} }, + { MODKEY|ControlMask, XK_Left, tagandviewtoleft, {0} }, + { MODKEY|ControlMask, XK_Right, tagandviewtoright, {0} }, #endif // FOCUSADJACENTTAG_PATCH #if TAGALLMON_PATCH - { MODKEY|Mod4Mask|ShiftMask, XK_comma, tagallmon, {.i = +1 } }, - { MODKEY|Mod4Mask|ShiftMask, XK_period, tagallmon, {.i = -1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_comma, tagallmon, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_period, tagallmon, {.i = -1 } }, #endif // TAGALLMON_PATCH #if TAGSWAPMON_PATCH - { MODKEY|Mod4Mask|ControlMask, XK_comma, tagswapmon, {.i = +1 } }, - { MODKEY|Mod4Mask|ControlMask, XK_period, tagswapmon, {.i = -1 } }, + { MODKEY|Mod4Mask|ControlMask, XK_comma, tagswapmon, {.i = +1 } }, + { MODKEY|Mod4Mask|ControlMask, XK_period, tagswapmon, {.i = -1 } }, #endif // TAGSWAPMON_PATCH #if ALTERNATIVE_TAGS_PATCH - { MODKEY, XK_n, togglealttag, {0} }, + { MODKEY, XK_n, togglealttag, {0} }, #endif // ALTERNATIVE_TAGS_PATCH #if SETBORDERPX_PATCH - { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } }, - { MODKEY|ShiftMask, XK_plus, setborderpx, {.i = +1 } }, - { MODKEY|ShiftMask, XK_numbersign, setborderpx, {.i = 0 } }, + { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } }, + { MODKEY|ShiftMask, XK_plus, setborderpx, {.i = +1 } }, + { MODKEY|ShiftMask, XK_numbersign, setborderpx, {.i = 0 } }, #endif // SETBORDERPX_PATCH #if CYCLELAYOUTS_PATCH - { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, - { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, + { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, + { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, #endif // CYCLELAYOUTS_PATCH - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) }; /* button definitions */ diff --git a/dwm.c b/dwm.c index a14788f..6efac2e 100644 --- a/dwm.c +++ b/dwm.c @@ -140,6 +140,9 @@ struct Client { int bw, oldbw; unsigned int tags; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + #if MAXIMIZE_PATCH + int ismax, wasfloating; + #endif // MAXIMIZE_PATCH #if AUTORESIZE_PATCH int needresize; #endif // AUTORESIZE_PATCH @@ -1748,6 +1751,10 @@ manage(Window w, XWindowAttributes *wa) XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); grabbuttons(c, 0); + #if MAXIMIZE_PATCH + c->wasfloating = 0; + c->ismax = 0; + #endif // MAXIMIZE_PATCH if (!c->isfloating) c->isfloating = c->oldstate = trans != None || c->isfixed; if (c->isfloating) diff --git a/patch/include.c b/patch/include.c index ca231a0..3db5a6d 100644 --- a/patch/include.c +++ b/patch/include.c @@ -52,6 +52,10 @@ #include "holdbar.c" #endif +#if MAXIMIZE_PATCH +#include "maximize.c" +#endif + #if PERTAG_PATCH #include "pertag.c" #endif diff --git a/patch/include.h b/patch/include.h index 2522376..afdbf87 100644 --- a/patch/include.h +++ b/patch/include.h @@ -52,6 +52,10 @@ #include "holdbar.h" #endif +#if MAXIMIZE_PATCH +#include "maximize.h" +#endif + #if PERTAG_PATCH #include "pertag.h" #endif diff --git a/patch/maximize.c b/patch/maximize.c new file mode 100644 index 0000000..6f89538 --- /dev/null +++ b/patch/maximize.c @@ -0,0 +1,45 @@ +void +maximize(int x, int y, int w, int h) { + XEvent ev; + + if(!selmon->sel || selmon->sel->isfixed) + return; + XRaiseWindow(dpy, selmon->sel->win); + if(!selmon->sel->ismax) { + if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating) + selmon->sel->wasfloating = True; + else { + togglefloating(NULL); + selmon->sel->wasfloating = False; + } + selmon->sel->oldx = selmon->sel->x; + selmon->sel->oldy = selmon->sel->y; + selmon->sel->oldw = selmon->sel->w; + selmon->sel->oldh = selmon->sel->h; + resize(selmon->sel, x, y, w, h, True); + selmon->sel->ismax = True; + } + else { + resize(selmon->sel, selmon->sel->oldx, selmon->sel->oldy, selmon->sel->oldw, selmon->sel->oldh, True); + if(!selmon->sel->wasfloating) + togglefloating(NULL); + selmon->sel->ismax = False; + } + drawbar(selmon); + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + +void +togglemaximize(const Arg *arg) { + maximize(selmon->wx, selmon->wy, selmon->ww - 2 * borderpx, selmon->wh - 2 * borderpx); +} + +void +toggleverticalmax(const Arg *arg) { + maximize(selmon->sel->x, selmon->wy, selmon->sel->w, selmon->wh - 2 * borderpx); +} + +void +togglehorizontalmax(const Arg *arg) { + maximize(selmon->wx, selmon->sel->y, selmon->ww - 2 * borderpx, selmon->sel->h); +} \ No newline at end of file diff --git a/patch/maximize.h b/patch/maximize.h new file mode 100644 index 0000000..a71226a --- /dev/null +++ b/patch/maximize.h @@ -0,0 +1,4 @@ +static void maximize(int x, int y, int w, int h); +static void togglemaximize(const Arg *arg); +static void toggleverticalmax(const Arg *arg); +static void togglehorizontalmax(const Arg *arg); \ No newline at end of file diff --git a/patches.h b/patches.h index b978781..2d31b3e 100644 --- a/patches.h +++ b/patches.h @@ -189,6 +189,12 @@ */ #define LOSEFULLSCREEN_PATCH 0 +/* This patch adds helper functions for maximizing, horizontally and vertically, floating + * windows using keybindings. + * https://dwm.suckless.org/patches/maximize/ + */ +#define MAXIMIZE_PATCH 0 + /* Adds rules per monitor, e.g. have default layouts per monitor. * The use case for this is if the second monitor is vertical (i.e. rotated) then * you may want to use a different default layout for this monitor than what is