dwm-extrabar-6.2-20210930-a786211.diff (8817B)
1 diff --git a/config.def.h b/config.def.h 2 --- a/config.def.h 3 +++ b/config.def.h 4 @@ -3,8 +3,10 @@ 5 /* appearance */ 6 static const unsigned int borderpx = 1; /* border pixel of windows */ 7 static const unsigned int snap = 32; /* snap pixel */ 8 -static const int showbar = 1; /* 0 means no bar */ 9 -static const int topbar = 1; /* 0 means bottom bar */ 10 +static const int showbar = 1; /* 0 means no standard bar */ 11 +static const int topbar = 1; /* 0 means standard bar at bottom */ 12 +static const int extrabar = 1; /* 0 means no extra bar */ 13 +static const char statussep = ';'; /* separator between statuses */ 14 static const char *fonts[] = { "monospace:size=10" }; 15 static const char dmenufont[] = "monospace:size=10"; 16 static const char col_gray1[] = "#222222"; 17 @@ -65,6 +67,7 @@ static Key keys[] = { 18 { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 19 { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, 20 { MODKEY, XK_b, togglebar, {0} }, 21 + { MODKEY|ShiftMask, XK_b, toggleextrabar, {0} }, 22 { MODKEY, XK_j, focusstack, {.i = +1 } }, 23 { MODKEY, XK_k, focusstack, {.i = -1 } }, 24 { MODKEY, XK_i, incnmaster, {.i = +1 } }, 25 @@ -105,6 +108,9 @@ static Button buttons[] = { 26 { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 27 { ClkWinTitle, 0, Button2, zoom, {0} }, 28 { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 29 + { ClkExBarLeftStatus, 0, Button2, spawn, {.v = termcmd } }, 30 + { ClkExBarMiddle, 0, Button2, spawn, {.v = termcmd } }, 31 + { ClkExBarRightStatus, 0, Button2, spawn, {.v = termcmd } }, 32 { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 33 { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 34 { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 35 diff --git a/dwm.c b/dwm.c 36 --- a/dwm.c 37 +++ b/dwm.c 38 @@ -65,6 +65,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 39 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 40 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 41 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 42 + ClkExBarLeftStatus, ClkExBarMiddle, ClkExBarRightStatus, 43 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 44 45 typedef union { 46 @@ -117,6 +118,7 @@ struct Monitor { 47 int nmaster; 48 int num; 49 int by; /* bar geometry */ 50 + int eby; /* extra bar geometry */ 51 int mx, my, mw, mh; /* screen size */ 52 int wx, wy, ww, wh; /* window area */ 53 unsigned int seltags; 54 @@ -124,11 +126,13 @@ struct Monitor { 55 unsigned int tagset[2]; 56 int showbar; 57 int topbar; 58 + int extrabar; 59 Client *clients; 60 Client *sel; 61 Client *stack; 62 Monitor *next; 63 Window barwin; 64 + Window extrabarwin; 65 const Layout *lt[2]; 66 }; 67 68 @@ -211,6 +215,7 @@ static void tag(const Arg *arg); 69 static void tagmon(const Arg *arg); 70 static void tile(Monitor *); 71 static void togglebar(const Arg *arg); 72 +static void toggleextrabar(const Arg *arg); 73 static void togglefloating(const Arg *arg); 74 static void toggletag(const Arg *arg); 75 static void toggleview(const Arg *arg); 76 @@ -238,6 +243,8 @@ static void zoom(const Arg *arg); 77 /* variables */ 78 static const char broken[] = "broken"; 79 static char stext[256]; 80 +static char estextl[256]; 81 +static char estextr[256]; 82 static int screen; 83 static int sw, sh; /* X display screen geometry width, height */ 84 static int bh, blw = 0; /* bar geometry */ 85 @@ -444,6 +451,13 @@ buttonpress(XEvent *e) 86 click = ClkStatusText; 87 else 88 click = ClkWinTitle; 89 + } else if (ev->window == selmon->extrabarwin) { 90 + if (ev->x < (int)TEXTW(estextl)) 91 + click = ClkExBarLeftStatus; 92 + else if (ev->x > selmon->ww - (int)TEXTW(estextr)) 93 + click = ClkExBarRightStatus; 94 + else 95 + click = ClkExBarMiddle; 96 } else if ((c = wintoclient(ev->window))) { 97 focus(c); 98 restack(selmon); 99 @@ -506,7 +520,9 @@ cleanupmon(Monitor *mon) 100 m->next = mon->next; 101 } 102 XUnmapWindow(dpy, mon->barwin); 103 + XUnmapWindow(dpy, mon->extrabarwin); 104 XDestroyWindow(dpy, mon->barwin); 105 + XDestroyWindow(dpy, mon->extrabarwin); 106 free(mon); 107 } 108 109 @@ -569,6 +585,7 @@ configurenotify(XEvent *e) 110 if (c->isfullscreen) 111 resizeclient(c, m->mx, m->my, m->mw, m->mh); 112 XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); 113 + XMoveResizeWindow(dpy, m->extrabarwin, m->wx, m->eby, m->ww, bh); 114 } 115 focus(NULL); 116 arrange(NULL); 117 @@ -639,6 +656,7 @@ createmon(void) 118 m->nmaster = nmaster; 119 m->showbar = showbar; 120 m->topbar = topbar; 121 + m->extrabar = extrabar; 122 m->lt[0] = &layouts[0]; 123 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 124 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 125 @@ -696,7 +714,7 @@ dirtomon(int dir) 126 void 127 drawbar(Monitor *m) 128 { 129 - int x, w, tw = 0; 130 + int x, w, tw = 0, etwl = 0, etwr = 0; 131 int boxs = drw->fonts->h / 9; 132 int boxw = drw->fonts->h / 6 + 2; 133 unsigned int i, occ = 0, urg = 0; 134 @@ -741,6 +759,17 @@ drawbar(Monitor *m) 135 } 136 } 137 drw_map(drw, m->barwin, 0, 0, m->ww, bh); 138 + 139 + if (m == selmon) { /* extra status is only drawn on selected monitor */ 140 + drw_setscheme(drw, scheme[SchemeNorm]); 141 + /* clear default bar draw buffer by drawing a blank rectangle */ 142 + drw_rect(drw, 0, 0, m->ww, bh, 1, 1); 143 + etwr = TEXTW(estextr) - lrpad + 2; /* 2px right padding */ 144 + drw_text(drw, m->ww - etwr, 0, etwr, bh, 0, estextr, 0); 145 + etwl = TEXTW(estextl); 146 + drw_text(drw, 0, 0, etwl, bh, 0, estextl, 0); 147 + drw_map(drw, m->extrabarwin, 0, 0, m->ww, bh); 148 + } 149 } 150 151 void 152 @@ -1708,6 +1737,15 @@ togglebar(const Arg *arg) 153 arrange(selmon); 154 } 155 156 +void 157 +toggleextrabar(const Arg *arg) 158 +{ 159 + selmon->extrabar = !selmon->extrabar; 160 + updatebarpos(selmon); 161 + XMoveResizeWindow(dpy, selmon->extrabarwin, selmon->wx, selmon->eby, selmon->ww, bh); 162 + arrange(selmon); 163 +} 164 + 165 void 166 togglefloating(const Arg *arg) 167 { 168 @@ -1812,14 +1850,22 @@ updatebars(void) 169 }; 170 XClassHint ch = {"dwm", "dwm"}; 171 for (m = mons; m; m = m->next) { 172 - if (m->barwin) 173 - continue; 174 - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), 175 - CopyFromParent, DefaultVisual(dpy, screen), 176 - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 177 - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 178 - XMapRaised(dpy, m->barwin); 179 - XSetClassHint(dpy, m->barwin, &ch); 180 + if (!m->barwin) { 181 + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), 182 + CopyFromParent, DefaultVisual(dpy, screen), 183 + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 184 + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 185 + XMapRaised(dpy, m->barwin); 186 + XSetClassHint(dpy, m->barwin, &ch); 187 + } 188 + if (!m->extrabarwin) { 189 + m->extrabarwin = XCreateWindow(dpy, root, m->wx, m->eby, m->ww, bh, 0, DefaultDepth(dpy, screen), 190 + CopyFromParent, DefaultVisual(dpy, screen), 191 + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); 192 + XDefineCursor(dpy, m->extrabarwin, cursor[CurNormal]->cursor); 193 + XMapRaised(dpy, m->extrabarwin); 194 + XSetClassHint(dpy, m->extrabarwin, &ch); 195 + } 196 } 197 } 198 199 @@ -1834,6 +1880,12 @@ updatebarpos(Monitor *m) 200 m->wy = m->topbar ? m->wy + bh : m->wy; 201 } else 202 m->by = -bh; 203 + if (m->extrabar) { 204 + m->wh -= bh; 205 + m->eby = !m->topbar ? m->wy : m->wy + m->wh; 206 + m->wy = !m->topbar ? m->wy + bh : m->wy; 207 + } else 208 + m->eby = -bh; 209 } 210 211 void 212 @@ -1990,8 +2042,26 @@ updatesizehints(Client *c) 213 void 214 updatestatus(void) 215 { 216 - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 217 + char text[768]; 218 + if (!gettextprop(root, XA_WM_NAME, text, sizeof(text))) { 219 strcpy(stext, "dwm-"VERSION); 220 + estextl[0] = '\0'; 221 + estextr[0] = '\0'; 222 + } else { 223 + char *l = strchr(text, statussep); 224 + if (l) { 225 + *l = '\0'; l++; 226 + strncpy(estextl, l, sizeof(estextl) - 1); 227 + } else 228 + estextl[0] = '\0'; 229 + char *r = strchr(estextl, statussep); 230 + if (r) { 231 + *r = '\0'; r++; 232 + strncpy(estextr, r, sizeof(estextr) - 1); 233 + } else 234 + estextr[0] = '\0'; 235 + strncpy(stext, text, sizeof(stext) - 1); 236 + } 237 drawbar(selmon); 238 } 239 240 @@ -2070,7 +2140,7 @@ wintomon(Window w) 241 if (w == root && getrootptr(&x, &y)) 242 return recttomon(x, y, 1, 1); 243 for (m = mons; m; m = m->next) 244 - if (w == m->barwin) 245 + if (w == m->barwin || w == m->extrabarwin) 246 return m; 247 if ((c = wintoclient(w))) 248 return c->mon;