dwm

dynamic window manager

git clone https://9o.is/git/dwm.git

commit 355d67d850a51d7b6cad9472b73be74baae9df5a
parent ea8c34c2847ded9c917187a53c79f9118d1630cc
Author: Jul <jul@9o.is>
Date:   Sun,  1 Feb 2026 22:56:38 -0500

allow foregrounding windows

Diffstat:
Mconfig.def.h | 3+++
Mconfig.h | 5++++-
Mdwm.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -38,6 +38,8 @@ static const int resizehints = 1; /* 1 means respect size hints in tiled resi static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */ +static const float fgw = .6, fgh = .6; + static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ @@ -86,6 +88,7 @@ static const Key keys[] = { { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|Mod4Mask, XK_space, toggleforegrounded, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, diff --git a/config.h b/config.h @@ -32,6 +32,8 @@ static const int resizehints = 1; /* 1 means respect size hints in tiled resi static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */ +static const float fgw = .6, fgh = .6; + static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ @@ -78,7 +80,8 @@ static const Key keys[] = { { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|Mod1Mask, XK_space, togglefloating, {0} }, + { MODKEY|ControlMask, XK_space, togglefloating, {0} }, + { MODKEY|Mod1Mask, XK_space, toggleforegrounded, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|Mod1Mask, XK_0, tag, {.ui = ~0 } }, TAGKEYS( XK_1, 0) diff --git a/dwm.c b/dwm.c @@ -96,9 +96,10 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int bw, oldbw; unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isforegrounded; Client *next; Client *snext; + Client *tnext; Monitor *mon; Window win; }; @@ -131,6 +132,7 @@ struct Monitor { Client *clients; Client *sel; Client *stack; + Client *foregrounded; Monitor *next; Window barwin; const Layout *lt[2]; @@ -218,6 +220,7 @@ static void tag(const Arg *arg); //static void tagmon(const Arg *arg); static void tile(Monitor *m); static void togglebar(const Arg *arg); +static void toggleforegrounded(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); @@ -435,6 +438,21 @@ attachstack(Client *c) } void +attachforegrounded (Client *c) +{ + c->tnext = c->mon->foregrounded; + c->mon->foregrounded = c; +} + +void +detachforegrounded (Client *c) +{ + Client **tc; + for (tc = &c->mon->foregrounded; *tc && *tc != c; tc = &(*tc)->tnext); + *tc = c->tnext; +} + +void buttonpress(XEvent *e) { unsigned int i, x, click, occ; @@ -1303,6 +1321,39 @@ nexttiled(Client *c) return c; } +Client * +nextforegrounded(Client *c) +{ + for (; c && (!c->isforegrounded || !ISVISIBLE(c)); c = c->tnext); + return c; +} + +void +arrangeforegrounded (Monitor *m) +{ + unsigned int n,i,x,y,w,h; + Client *c; + + for (n = 0, c = nextforegrounded(m->foregrounded); c; c = nextforegrounded(c->tnext), n++); + if (n == 0) + return; + + for (i = 0, c = nextforegrounded(m->foregrounded); c; c = nextforegrounded(c->tnext), i++){ + if (n == 1) { + x = m->mx + (m->mw - m->mw * fgw) / 2; + y = m->my + (m->mh - m->mh * fgh) / 2; + w = (m->mw * fgw) - (2 * (m->foregrounded->bw)); + h = (m->mh * fgh) - (2 * (m->foregrounded->bw)); + } else { + x = (n - 1 - i) * (m->mw / n); + y = m->my + (m->mh - m->mh * fgh) / 2; + w = (m->mw * (1 / (float)n)) - (2 * (m->foregrounded->bw)); + h = (m->mh * fgh) - (2 * (m->foregrounded->bw)); + } + resize(c, x, y, w, h, c->bw, 0); + } +} + void pop(Client *c) { @@ -1864,6 +1915,24 @@ togglebar(const Arg *arg) } void +toggleforegrounded(const Arg *arg) +{ + if (!selmon->sel) + return; + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + + selmon->sel->isforegrounded || selmon->sel->isfloating ? + detachforegrounded(selmon->sel) : attachforegrounded(selmon->sel); + + selmon->sel->isforegrounded = selmon->sel->isfloating = + !selmon->sel->isfloating && !selmon->sel->isforegrounded; + + arrangeforegrounded(selmon); + arrange(selmon); +} + +void togglefloating(const Arg *arg) { if (!selmon->sel) @@ -1876,6 +1945,13 @@ togglefloating(const Arg *arg) selmon->sel->w - 2 * (borderpx - selmon->sel->bw), selmon->sel->h - 2 * (borderpx - selmon->sel->bw), borderpx, 0); + + if (selmon->sel->isforegrounded) { + selmon->sel->isforegrounded = 0; + detachforegrounded(selmon->sel); + arrangeforegrounded(selmon); + } + arrange(selmon); } @@ -1928,6 +2004,12 @@ unmanage(Client *c, int destroyed) detach(c); detachstack(c); + + if (c->isforegrounded){ + detachforegrounded(c); + arrangeforegrounded(m); + } + if (!destroyed) { wc.border_width = c->oldbw; XGrabServer(dpy); /* avoid race conditions */