floatingstatus-20250408-cfb8627.diff (10006B)
1 From 74a90e7f249961c6d5d8f430a404d70628d6e3ea Mon Sep 17 00:00:00 2001 2 From: uint23 <abhinav.prsai@gmail.com> 3 Date: Tue, 8 Apr 2025 17:33:20 +0100 4 Subject: [PATCH] floating status bar patch 5 6 --- 7 config.def.h | 6 ++ 8 dwm.c | 182 ++++++++++++++++++++++++++++----------------------- 9 2 files changed, 106 insertions(+), 82 deletions(-) 10 11 diff --git a/config.def.h b/config.def.h 12 index 9efa774..4febd22 100644 13 --- a/config.def.h 14 +++ b/config.def.h 15 @@ -2,6 +2,11 @@ 16 17 /* appearance */ 18 static const unsigned int borderpx = 1; /* border pixel of windows */ 19 +static const unsigned int barpadv = 10; /* bar vertical padding (from top)*/ 20 +static const unsigned int barpadh = 200; /* bar vertical padding (from top)*/ 21 +static const unsigned int barheight = 2; /* bar vertical padding (from top)*/ 22 +static const unsigned int barborder = 2; /* bar vertical padding (from top)*/ 23 +static const unsigned int floatbar = 1; /* 0 means bar won't float; float or dock the bar */ 24 static const unsigned int snap = 32; /* snap pixel */ 25 static const int showbar = 1; /* 0 means no bar */ 26 static const int topbar = 1; /* 0 means bottom bar */ 27 @@ -16,6 +21,7 @@ static const char *colors[][3] = { 28 /* fg bg border */ 29 [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 30 [SchemeSel] = { col_gray4, col_cyan, col_cyan }, 31 + [SchemeBar] = { NULL, NULL, col_cyan }, 32 }; 33 34 /* tagging */ 35 diff --git a/dwm.c b/dwm.c 36 index 1443802..10fa1e8 100644 37 --- a/dwm.c 38 +++ b/dwm.c 39 @@ -58,7 +58,7 @@ 40 41 /* enums */ 42 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 43 -enum { SchemeNorm, SchemeSel }; /* color schemes */ 44 +enum { SchemeNorm, SchemeSel, SchemeBar }; /* color schemes */ 45 enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 46 NetWMFullscreen, NetActiveWindow, NetWMWindowType, 47 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 48 @@ -338,10 +338,10 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) 49 if (*y + *h + 2 * c->bw <= m->wy) 50 *y = m->wy; 51 } 52 - if (*h < bh) 53 - *h = bh; 54 - if (*w < bh) 55 - *w = bh; 56 + if (*h < bh + barheight) 57 + *h = bh + barheight; 58 + if (*w < bh + barheight) 59 + *w = bh + barheight; 60 if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { 61 if (!c->hintsvalid) 62 updatesizehints(c); 63 @@ -563,13 +563,13 @@ configurenotify(XEvent *e) 64 sw = ev->width; 65 sh = ev->height; 66 if (updategeom() || dirty) { 67 - drw_resize(drw, sw, bh); 68 + drw_resize(drw, sw, bh + barheight); 69 updatebars(); 70 for (m = mons; m; m = m->next) { 71 for (c = m->clients; c; c = c->next) 72 if (c->isfullscreen) 73 resizeclient(c, m->mx, m->my, m->mw, m->mh); 74 - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); 75 + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh + barheight); 76 } 77 focus(NULL); 78 arrange(NULL); 79 @@ -697,54 +697,57 @@ dirtomon(int dir) 80 void 81 drawbar(Monitor *m) 82 { 83 - int x, w, tw = 0; 84 - int boxs = drw->fonts->h / 9; 85 - int boxw = drw->fonts->h / 6 + 2; 86 - unsigned int i, occ = 0, urg = 0; 87 - Client *c; 88 - 89 - if (!m->showbar) 90 - return; 91 - 92 - /* draw status first so it can be overdrawn by tags later */ 93 - if (m == selmon) { /* status is only drawn on selected monitor */ 94 - drw_setscheme(drw, scheme[SchemeNorm]); 95 - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 96 - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); 97 - } 98 - 99 - for (c = m->clients; c; c = c->next) { 100 - occ |= c->tags; 101 - if (c->isurgent) 102 - urg |= c->tags; 103 - } 104 - x = 0; 105 - for (i = 0; i < LENGTH(tags); i++) { 106 - w = TEXTW(tags[i]); 107 - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 108 - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); 109 - if (occ & 1 << i) 110 - drw_rect(drw, x + boxs, boxs, boxw, boxw, 111 - m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 112 - urg & 1 << i); 113 - x += w; 114 - } 115 - w = TEXTW(m->ltsymbol); 116 - drw_setscheme(drw, scheme[SchemeNorm]); 117 - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); 118 - 119 - if ((w = m->ww - tw - x) > bh) { 120 - if (m->sel) { 121 - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 122 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); 123 - if (m->sel->isfloating) 124 - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); 125 - } else { 126 - drw_setscheme(drw, scheme[SchemeNorm]); 127 - drw_rect(drw, x, 0, w, bh, 1, 1); 128 - } 129 - } 130 - drw_map(drw, m->barwin, 0, 0, m->ww, bh); 131 + int x, w, tw = 0; 132 + int boxs = drw->fonts->h / 9; 133 + int boxw = drw->fonts->h / 6 + 2; 134 + unsigned int i, occ = 0, urg = 0; 135 + Client *c; 136 + 137 + // Calculate the actual bar width depending on if it's floating 138 + int barwidth = floatbar ? (m->ww - 2 * barpadh) : m->ww; 139 + 140 + if (!m->showbar) 141 + return; 142 + 143 + /* draw status first so it can be overdrawn by tags later */ 144 + if (m == selmon) { /* status is only drawn on selected monitor */ 145 + drw_setscheme(drw, scheme[SchemeNorm]); 146 + tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ 147 + drw_text(drw, barwidth - tw, 0, tw, bh + barheight, 0, stext, 0); 148 + } 149 + 150 + for (c = m->clients; c; c = c->next) { 151 + occ |= c->tags; 152 + if (c->isurgent) 153 + urg |= c->tags; 154 + } 155 + x = 0; 156 + for (i = 0; i < LENGTH(tags); i++) { 157 + w = TEXTW(tags[i]); 158 + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 159 + drw_text(drw, x, 0, w, bh + barheight, lrpad / 2, tags[i], urg & 1 << i); 160 + if (occ & 1 << i) 161 + drw_rect(drw, x + boxs, boxs, boxw, boxw, 162 + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 163 + urg & 1 << i); 164 + x += w; 165 + } 166 + w = TEXTW(m->ltsymbol); 167 + drw_setscheme(drw, scheme[SchemeNorm]); 168 + x = drw_text(drw, x, 0, w, bh + barheight, lrpad / 2, m->ltsymbol, 0); 169 + 170 + if ((w = barwidth - tw - x) > bh + barheight) { 171 + if (m->sel) { 172 + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 173 + drw_text(drw, x, 0, w, bh + barheight, lrpad / 2, m->sel->name, 0); 174 + if (m->sel->isfloating) 175 + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); 176 + } else { 177 + drw_setscheme(drw, scheme[SchemeNorm]); 178 + drw_rect(drw, x, 0, w, bh + barheight, 1, 1); 179 + } 180 + } 181 + drw_map(drw, m->barwin, 0, 0, barwidth, bh + barheight); 182 } 183 184 void 185 @@ -1561,7 +1564,7 @@ setup(void) 186 if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) 187 die("no fonts could be loaded."); 188 lrpad = drw->fonts->h; 189 - bh = drw->fonts->h + 2; 190 + bh = drw->fonts->h + 2 + barheight; 191 updategeom(); 192 /* init atoms */ 193 utf8string = XInternAtom(dpy, "UTF8_STRING", False); 194 @@ -1716,7 +1719,7 @@ togglebar(const Arg *arg) 195 { 196 selmon->showbar = !selmon->showbar; 197 updatebarpos(selmon); 198 - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 199 + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh + barheight); 200 arrange(selmon); 201 } 202 203 @@ -1817,36 +1820,51 @@ unmapnotify(XEvent *e) 204 void 205 updatebars(void) 206 { 207 - Monitor *m; 208 - XSetWindowAttributes wa = { 209 - .override_redirect = True, 210 - .background_pixmap = ParentRelative, 211 - .event_mask = ButtonPressMask|ExposureMask 212 - }; 213 - XClassHint ch = {"dwm", "dwm"}; 214 - for (m = mons; m; m = m->next) { 215 - if (m->barwin) 216 - continue; 217 - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), 218 - CopyFromParent, DefaultVisual(dpy, screen), 219 - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 220 - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 221 - XMapRaised(dpy, m->barwin); 222 - XSetClassHint(dpy, m->barwin, &ch); 223 - } 224 + Monitor *m; 225 + XSetWindowAttributes wa = { 226 + .override_redirect = True, 227 + .background_pixmap = ParentRelative, 228 + .event_mask = ButtonPressMask|ExposureMask 229 + }; 230 + XClassHint ch = {"dwm", "dwm"}; 231 + for (m = mons; m; m = m->next) { 232 + if (m->barwin) 233 + continue; 234 + if (floatbar) { 235 + m->barwin = XCreateWindow(dpy, root, barpadh, barpadv, m->ww - 2 * barpadh, bh + barheight, 0, DefaultDepth(dpy, screen), 236 + CopyFromParent, DefaultVisual(dpy, screen), 237 + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 238 + XSetWindowBorder(dpy, m->barwin, scheme[SchemeBar][ColBorder].pixel); 239 + XSetWindowBorderWidth(dpy, m->barwin, barborder); 240 + } else { 241 + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh + barheight, 0, DefaultDepth(dpy, screen), 242 + CopyFromParent, DefaultVisual(dpy, screen), 243 + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 244 + } 245 + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 246 + XMapRaised(dpy, m->barwin); 247 + XSetClassHint(dpy, m->barwin, &ch); 248 + } 249 } 250 251 void 252 updatebarpos(Monitor *m) 253 { 254 - m->wy = m->my; 255 - m->wh = m->mh; 256 - if (m->showbar) { 257 - m->wh -= bh; 258 - m->by = m->topbar ? m->wy : m->wy + m->wh; 259 - m->wy = m->topbar ? m->wy + bh : m->wy; 260 - } else 261 - m->by = -bh; 262 + if (floatbar) { 263 + /* IF YOU ARE USING GAPS, PLEASE ADD BARBORDER TO THE END */ 264 + m->wy = m->my + (barheight + bh + barpadv * 2 + barborder); /* Start window area below the bar */ 265 + m->wh = m->mh - (barheight + bh + barpadv * 2 + barborder); /* Reduce window height to account for bar */ 266 + m->by = barpadv; /* Position bar at vertical padding from top */ 267 + } else { 268 + m->wy = m->my; 269 + m->wh = m->mh; 270 + if (m->showbar) { 271 + m->wh -= bh + barheight; 272 + m->by = m->topbar ? m->wy : m->wy + m->wh; 273 + m->wy = m->topbar ? m->wy + bh : m->wy; 274 + } else 275 + m->by = -bh + barheight; 276 + } 277 } 278 279 void 280 -- 281 2.49.0 282