From 507895940574e77386d53f81df541e3903bf1ba3 Mon Sep 17 00:00:00 2001 From: espro1 Date: Tue, 20 Feb 2024 16:11:05 -0500 Subject: [PATCH] Essentially a layout for a special class of floating windows. When a window is foregrounded, it is floated, resized, and moved to a predictable location --- config.def.h | 3 ++ dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 9efa774..718e7c3 100644 --- a/config.def.h +++ b/config.def.h @@ -37,6 +37,8 @@ static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +static const float fgw = .6,fgh = .6; + static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ @@ -78,6 +80,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/dwm.c b/dwm.c index f1d86b2..12b037d 100644 --- a/dwm.c +++ b/dwm.c @@ -92,9 +92,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; }; @@ -127,6 +128,7 @@ struct Monitor { Client *clients; Client *sel; Client *stack; + Client *foregrounded; Monitor *next; Window barwin; const Layout *lt[2]; @@ -210,6 +212,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); @@ -415,6 +418,21 @@ attachstack(Client *c) c->mon->stack = 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) { @@ -1209,6 +1227,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,0); + } +} + void pop(Client *c) { @@ -1721,6 +1772,24 @@ togglebar(const Arg *arg) arrange(selmon); } +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) { @@ -1732,6 +1801,11 @@ togglefloating(const Arg *arg) if (selmon->sel->isfloating) resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h, 0); + if (selmon->sel->isforegrounded) { + selmon->sel->isforegrounded = 0; + detachforegrounded(selmon->sel); + arrangeforegrounded(selmon); + } arrange(selmon); } @@ -1783,6 +1857,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 */ -- 2.43.0