You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
patches/dwm/dwm-barmodules-awesomebar-6...

1079 lines
29 KiB
Diff

From 2433e0499e4607d39a3f511449f9466886055914 Mon Sep 17 00:00:00 2001
From: Bakkeby <bakkeby@gmail.com>
Date: Mon, 10 Jan 2022 14:06:10 +0100
Subject: [PATCH 1/2] Bar Modules - splits the bar functionality into
individual segments that can be re-arranged
---
config.def.h | 20 +++
dwm.c | 393 ++++++++++++++++++++++++++++++++-----------
patch/bar_ltsymbol.c | 17 ++
patch/bar_ltsymbol.h | 3 +
patch/bar_status.c | 19 +++
patch/bar_status.h | 3 +
patch/bar_tags.c | 55 ++++++
patch/bar_tags.h | 3 +
patch/bar_wintitle.c | 31 ++++
patch/bar_wintitle.h | 3 +
patch/include.c | 5 +
patch/include.h | 5 +
12 files changed, 458 insertions(+), 99 deletions(-)
create mode 100644 patch/bar_ltsymbol.c
create mode 100644 patch/bar_ltsymbol.h
create mode 100644 patch/bar_status.c
create mode 100644 patch/bar_status.h
create mode 100644 patch/bar_tags.c
create mode 100644 patch/bar_tags.h
create mode 100644 patch/bar_wintitle.c
create mode 100644 patch/bar_wintitle.h
create mode 100644 patch/include.c
create mode 100644 patch/include.h
diff --git a/config.def.h b/config.def.h
index a2ac963..f870c41 100644
--- a/config.def.h
+++ b/config.def.h
@@ -31,6 +31,26 @@ static const Rule rules[] = {
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
+/* Bar rules allow you to configure what is shown where on the bar, as well as
+ * introducing your own bar modules.
+ *
+ * monitor:
+ * -1 show on all monitors
+ * 0 show on monitor 0
+ * 'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
+ * bar - bar index, 0 is default, 1 is extrabar
+ * alignment - how the module is aligned compared to other modules
+ * widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
+ * name - does nothing, intended for visual clue and for logging / debugging
+ */
+static const BarRule barrules[] = {
+ /* monitor bar alignment widthfunc drawfunc clickfunc name */
+ { -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" },
+ { -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" },
+ { 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" },
+ { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" },
+};
+
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
diff --git a/dwm.c b/dwm.c
index a96f33c..86763d8 100644
--- a/dwm.c
+++ b/dwm.c
@@ -45,6 +45,7 @@
#include "util.h"
/* macros */
+#define BARRULES 20
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
@@ -66,6 +67,19 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+enum {
+ BAR_ALIGN_LEFT,
+ BAR_ALIGN_CENTER,
+ BAR_ALIGN_RIGHT,
+ BAR_ALIGN_LEFT_LEFT,
+ BAR_ALIGN_LEFT_RIGHT,
+ BAR_ALIGN_LEFT_CENTER,
+ BAR_ALIGN_NONE,
+ BAR_ALIGN_RIGHT_LEFT,
+ BAR_ALIGN_RIGHT_RIGHT,
+ BAR_ALIGN_RIGHT_CENTER,
+ BAR_ALIGN_LAST
+}; /* bar alignment */
typedef union {
int i;
@@ -74,6 +88,46 @@ typedef union {
const void *v;
} Arg;
+typedef struct Monitor Monitor;
+typedef struct Bar Bar;
+struct Bar {
+ Window win;
+ Monitor *mon;
+ Bar *next;
+ int idx;
+ int topbar;
+ int bx, by, bw, bh; /* bar geometry */
+ int w[BARRULES]; // module width
+ int x[BARRULES]; // module position
+};
+
+typedef struct {
+ int max_width;
+} BarWidthArg;
+
+typedef struct {
+ int x;
+ int w;
+} BarDrawArg;
+
+typedef struct {
+ int rel_x;
+ int rel_y;
+ int rel_w;
+ int rel_h;
+} BarClickArg;
+
+typedef struct {
+ int monitor;
+ int bar;
+ int alignment; // see bar alignment enum
+ int (*widthfunc)(Bar *bar, BarWidthArg *a);
+ int (*drawfunc)(Bar *bar, BarDrawArg *a);
+ int (*clickfunc)(Bar *bar, Arg *arg, BarClickArg *a);
+ char *name; // for debugging
+ int x, w; // position, width for internal use
+} BarRule;
+
typedef struct {
unsigned int click;
unsigned int mask;
@@ -82,7 +136,6 @@ typedef struct {
const Arg arg;
} Button;
-typedef struct Monitor Monitor;
typedef struct Client Client;
struct Client {
char name[256];
@@ -116,19 +169,17 @@ struct Monitor {
float mfact;
int nmaster;
int num;
- int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
int showbar;
- int topbar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
- Window barwin;
+ Bar *bar;
const Layout *lt[2];
};
@@ -163,6 +214,7 @@ static void detachstack(Client *c);
static Monitor *dirtomon(int dir);
static void drawbar(Monitor *m);
static void drawbars(void);
+static void drawbarwin(Bar *bar);
static void enternotify(XEvent *e);
static void expose(XEvent *e);
static void focus(Client *c);
@@ -235,12 +287,13 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+#include "patch/include.h"
/* variables */
static const char broken[] = "broken";
static char stext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
-static int bh, blw = 0; /* bar geometry */
+static int bh; /* bar geometry */
static int lrpad; /* sum of left and right padding for text */
static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0;
@@ -272,6 +325,8 @@ static Window root, wmcheckwin;
/* configuration, allows nested code to access above variables */
#include "config.h"
+#include "patch/include.c"
+
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
@@ -417,43 +472,61 @@ attachstack(Client *c)
void
buttonpress(XEvent *e)
{
- unsigned int i, x, click;
+ int click, i, r, mi;
Arg arg = {0};
Client *c;
Monitor *m;
+ Bar *bar;
XButtonPressedEvent *ev = &e->xbutton;
+ const BarRule *br;
+ BarClickArg carg = { 0, 0, 0, 0 };
click = ClkRootWin;
/* focus monitor if necessary */
- if ((m = wintomon(ev->window)) && m != selmon) {
+ if ((m = wintomon(ev->window)) && m != selmon
+ ) {
unfocus(selmon->sel, 1);
selmon = m;
focus(NULL);
}
- if (ev->window == selmon->barwin) {
- i = x = 0;
- do
- x += TEXTW(tags[i]);
- while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
+
+ for (mi = 0, m = mons; m && m != selmon; m = m->next, mi++); // get the monitor index
+ for (bar = selmon->bar; bar; bar = bar->next) {
+ if (ev->window == bar->win) {
+ for (r = 0; r < LENGTH(barrules); r++) {
+ br = &barrules[r];
+ if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->clickfunc == NULL)
+ continue;
+ if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi)
+ continue;
+ if (bar->x[r] <= ev->x && ev->x <= bar->x[r] + bar->w[r]) {
+ carg.rel_x = ev->x - bar->x[r];
+ carg.rel_y = ev->y;
+ carg.rel_w = bar->w[r];
+ carg.rel_h = bar->bh;
+ click = br->clickfunc(bar, &arg, &carg);
+ if (click < 0)
+ return;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (click == ClkRootWin && (c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
XAllowEvents(dpy, ReplayPointer, CurrentTime);
click = ClkClientWin;
}
- for (i = 0; i < LENGTH(buttons); i++)
+
+ for (i = 0; i < LENGTH(buttons); i++) {
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
+ }
+ }
}
void
@@ -498,6 +571,7 @@ void
cleanupmon(Monitor *mon)
{
Monitor *m;
+ Bar *bar;
if (mon == mons)
mons = mons->next;
@@ -505,8 +579,12 @@ cleanupmon(Monitor *mon)
for (m = mons; m && m->next != mon; m = m->next);
m->next = mon->next;
}
- XUnmapWindow(dpy, mon->barwin);
- XDestroyWindow(dpy, mon->barwin);
+ for (bar = mon->bar; bar; bar = mon->bar) {
+ XUnmapWindow(dpy, bar->win);
+ XDestroyWindow(dpy, bar->win);
+ mon->bar = bar->next;
+ free(bar);
+ }
free(mon);
}
@@ -552,6 +630,7 @@ void
configurenotify(XEvent *e)
{
Monitor *m;
+ Bar *bar;
Client *c;
XConfigureEvent *ev = &e->xconfigure;
int dirty;
@@ -568,7 +647,8 @@ configurenotify(XEvent *e)
for (c = m->clients; c; c = c->next)
if (c->isfullscreen)
resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+ for (bar = m->bar; bar; bar = bar->next)
+ XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
}
focus(NULL);
arrange(NULL);
@@ -631,17 +711,40 @@ configurerequest(XEvent *e)
Monitor *
createmon(void)
{
- Monitor *m;
+ Monitor *m, *mon;
+ int i, n, mi, max_bars = 2, istopbar = topbar;
+
+ const BarRule *br;
+ Bar *bar;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->nmaster = nmaster;
m->showbar = showbar;
- m->topbar = topbar;
+
+ for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+
+ /* Derive the number of bars for this monitor based on bar rules */
+ for (n = -1, i = 0; i < LENGTH(barrules); i++) {
+ br = &barrules[i];
+ if (br->monitor == 'A' || br->monitor == -1 || br->monitor == mi)
+ n = MAX(br->bar, n);
+ }
+
+ for (i = 0; i <= n && i < max_bars; i++) {
+ bar = ecalloc(1, sizeof(Bar));
+ bar->mon = m;
+ bar->idx = i;
+ bar->next = m->bar;
+ bar->topbar = istopbar;
+ m->bar = bar;
+ istopbar = !istopbar;
+ }
+
return m;
}
@@ -696,65 +799,117 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, tw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
- if (!m->showbar)
- return;
-
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
- }
-
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
- w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
- x += w;
- }
- w = blw = TEXTW(m->ltsymbol);
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-
- if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+ Bar *bar;
+ for (bar = m->bar; bar; bar = bar->next)
+ drawbarwin(bar);
}
void
drawbars(void)
{
Monitor *m;
-
for (m = mons; m; m = m->next)
drawbar(m);
}
+void
+drawbarwin(Bar *bar)
+{
+ if (!bar->win)
+ return;
+ Monitor *mon;
+ int r, w, mi;
+ int rx, lx, rw, lw; // bar size, split between left and right if a center module is added
+ const BarRule *br;
+ BarWidthArg warg = { 0 };
+ BarDrawArg darg = { 0, 0 };
+
+ for (mi = 0, mon = mons; mon && mon != bar->mon; mon = mon->next, mi++); // get the monitor index
+ rw = lw = bar->bw;
+ rx = lx = 0;
+
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, lx, 0, lw, bh, 1, 1);
+ for (r = 0; r < LENGTH(barrules); r++) {
+ br = &barrules[r];
+ if (br->bar != bar->idx || br->drawfunc == NULL || (br->monitor == 'A' && bar->mon != selmon))
+ continue;
+ if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi)
+ continue;
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ warg.max_width = (br->alignment < BAR_ALIGN_RIGHT_LEFT ? lw : rw);
+ w = br->widthfunc(bar, &warg);
+ w = MIN(warg.max_width, w);
+
+ if (lw <= 0) { // if left is exhausted then switch to right side, and vice versa
+ lw = rw;
+ lx = rx;
+ } else if (rw <= 0) {
+ rw = lw;
+ rx = lx;
+ }
+
+ switch(br->alignment) {
+ default:
+ case BAR_ALIGN_NONE:
+ case BAR_ALIGN_LEFT_LEFT:
+ case BAR_ALIGN_LEFT:
+ bar->x[r] = lx;
+ if (lx == rx) {
+ rx += w;
+ rw -= w;
+ }
+ lx += w;
+ lw -= w;
+ break;
+ case BAR_ALIGN_LEFT_RIGHT:
+ case BAR_ALIGN_RIGHT:
+ bar->x[r] = lx + lw - w;
+ if (lx == rx)
+ rw -= w;
+ lw -= w;
+ break;
+ case BAR_ALIGN_LEFT_CENTER:
+ case BAR_ALIGN_CENTER:
+ bar->x[r] = lx + lw / 2 - w / 2;
+ if (lx == rx) {
+ rw = rx + rw - bar->x[r] - w;
+ rx = bar->x[r] + w;
+ }
+ lw = bar->x[r] - lx;
+ break;
+ case BAR_ALIGN_RIGHT_LEFT:
+ bar->x[r] = rx;
+ if (lx == rx) {
+ lx += w;
+ lw -= w;
+ }
+ rx += w;
+ rw -= w;
+ break;
+ case BAR_ALIGN_RIGHT_RIGHT:
+ bar->x[r] = rx + rw - w;
+ if (lx == rx)
+ lw -= w;
+ rw -= w;
+ break;
+ case BAR_ALIGN_RIGHT_CENTER:
+ bar->x[r] = rx + rw / 2 - w / 2;
+ if (lx == rx) {
+ lw = lx + lw - bar->x[r] + w;
+ lx = bar->x[r] + w;
+ }
+ rw = bar->x[r] - rx;
+ break;
+ }
+ bar->w[r] = w;
+ darg.x = bar->x[r];
+ darg.w = bar->w[r];
+ br->drawfunc(bar, &darg);
+ }
+ drw_map(drw, bar->win, 0, 0, bar->bw, bar->bh);
+}
+
void
enternotify(XEvent *e)
{
@@ -1049,7 +1204,7 @@ manage(Window w, XWindowAttributes *wa)
c->y = c->mon->my + c->mon->mh - HEIGHT(c);
c->x = MAX(c->x, c->mon->mx);
/* only fix client y-offset, if the client center might cover the bar */
- c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
+ c->y = MAX(c->y, ((c->mon->bar->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
c->bw = borderpx;
@@ -1236,7 +1391,8 @@ propertynotify(XEvent *e)
break;
case XA_WM_HINTS:
updatewmhints(c);
- drawbars();
+ if (c->isurgent)
+ drawbars();
break;
}
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
@@ -1362,7 +1518,7 @@ restack(Monitor *m)
XRaiseWindow(dpy, m->sel->win);
if (m->lt[m->sellt]->arrange) {
wc.stack_mode = Below;
- wc.sibling = m->barwin;
+ wc.sibling = m->bar->win;
for (c = m->stack; c; c = c->snext)
if (!c->isfloating && ISVISIBLE(c)) {
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
@@ -1705,9 +1861,11 @@ tile(Monitor *m)
void
togglebar(const Arg *arg)
{
+ Bar *bar;
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ for (bar = selmon->bar; bar; bar = bar->next)
+ XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
arrange(selmon);
}
@@ -1807,22 +1965,37 @@ unmapnotify(XEvent *e)
void
updatebars(void)
{
+ Bar *bar;
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
+ #if BAR_ALPHA_PATCH
+ .background_pixel = 0,
+ .border_pixel = 0,
+ .colormap = cmap,
+ #else
.background_pixmap = ParentRelative,
+ #endif // BAR_ALPHA_PATCH
.event_mask = ButtonPressMask|ExposureMask
};
XClassHint ch = {"dwm", "dwm"};
for (m = mons; m; m = m->next) {
- if (m->barwin)
- continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
+ for (bar = m->bar; bar; bar = bar->next) {
+ if (!bar->win) {
+ #if BAR_ALPHA_PATCH
+ bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, depth,
+ InputOutput, visual,
+ CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
+ #else
+ bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ #endif // BAR_ALPHA_PATCH
+ XDefineCursor(dpy, bar->win, cursor[CurNormal]->cursor);
+ XMapRaised(dpy, bar->win);
+ XSetClassHint(dpy, bar->win, &ch);
+ }
+ }
}
}
@@ -1831,12 +2004,30 @@ updatebarpos(Monitor *m)
{
m->wy = m->my;
m->wh = m->mh;
- if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
- } else
- m->by = -bh;
+ int num_bars;
+ Bar *bar;
+ int y_pad = 0;
+ int x_pad = 0;
+
+ for (bar = m->bar; bar; bar = bar->next) {
+ bar->bx = m->mx + x_pad;
+ bar->bw = m->ww - 2 * x_pad;
+ bar->bh = bh;
+ }
+
+ if (!m->showbar) {
+ for (bar = m->bar; bar; bar = bar->next)
+ bar->by = -bh - y_pad;
+ return;
+ }
+
+ for (num_bars = 0, bar = m->bar; bar; bar = bar->next, num_bars++)
+ if (bar->topbar)
+ m->wy = m->my + bh + y_pad;
+ m->wh = m->wh - y_pad * num_bars - bh * num_bars;
+
+ for (bar = m->bar; bar; bar = bar->next)
+ bar->by = (bar->topbar ? m->wy - bh : m->wy + m->wh);
}
void
@@ -1993,9 +2184,11 @@ updatesizehints(Client *c)
void
updatestatus(void)
{
+ Monitor *m;
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
+ for (m = mons; m; m = m->next)
+ drawbar(m);
}
void
@@ -2069,12 +2262,14 @@ wintomon(Window w)
int x, y;
Client *c;
Monitor *m;
+ Bar *bar;
if (w == root && getrootptr(&x, &y))
return recttomon(x, y, 1, 1);
for (m = mons; m; m = m->next)
- if (w == m->barwin)
- return m;
+ for (bar = m->bar; bar; bar = bar->next)
+ if (w == bar->win)
+ return m;
if ((c = wintoclient(w)))
return c->mon;
return selmon;
diff --git a/patch/bar_ltsymbol.c b/patch/bar_ltsymbol.c
new file mode 100644
index 0000000..6676a2a
--- /dev/null
+++ b/patch/bar_ltsymbol.c
@@ -0,0 +1,17 @@
+int
+width_ltsymbol(Bar *bar, BarWidthArg *a)
+{
+ return TEXTW(bar->mon->ltsymbol);
+}
+
+int
+draw_ltsymbol(Bar *bar, BarDrawArg *a)
+{
+ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, bar->mon->ltsymbol, 0);
+}
+
+int
+click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a)
+{
+ return ClkLtSymbol;
+}
diff --git a/patch/bar_ltsymbol.h b/patch/bar_ltsymbol.h
new file mode 100644
index 0000000..d9c79bf
--- /dev/null
+++ b/patch/bar_ltsymbol.h
@@ -0,0 +1,3 @@
+static int width_ltsymbol(Bar *bar, BarWidthArg *a);
+static int draw_ltsymbol(Bar *bar, BarDrawArg *a);
+static int click_ltsymbol(Bar *bar, Arg *arg, BarClickArg *a);
diff --git a/patch/bar_status.c b/patch/bar_status.c
new file mode 100644
index 0000000..7d27282
--- /dev/null
+++ b/patch/bar_status.c
@@ -0,0 +1,19 @@
+int
+width_status(Bar *bar, BarWidthArg *a)
+{
+ return TEXTW(stext);
+}
+
+
+int
+draw_status(Bar *bar, BarDrawArg *a)
+{
+ return drw_text(drw, a->x, 0, a->w, bh, lrpad / 2, stext, 0);
+}
+
+
+int
+click_status(Bar *bar, Arg *arg, BarClickArg *a)
+{
+ return ClkStatusText;
+}
diff --git a/patch/bar_status.h b/patch/bar_status.h
new file mode 100644
index 0000000..b02a4b8
--- /dev/null
+++ b/patch/bar_status.h
@@ -0,0 +1,3 @@
+static int width_status(Bar *bar, BarWidthArg *a);
+static int draw_status(Bar *bar, BarDrawArg *a);
+static int click_status(Bar *bar, Arg *arg, BarClickArg *a);
diff --git a/patch/bar_tags.c b/patch/bar_tags.c
new file mode 100644
index 0000000..680e1fe
--- /dev/null
+++ b/patch/bar_tags.c
@@ -0,0 +1,55 @@
+int
+width_tags(Bar *bar, BarWidthArg *a)
+{
+ int w, i;
+
+ for (w = 0, i = 0; i < LENGTH(tags); i++) {
+ w += TEXTW(tags[i]);
+ }
+ return w;
+}
+
+int
+draw_tags(Bar *bar, BarDrawArg *a)
+{
+ int invert;
+ int w, x = a->x;
+ int boxs = drw->fonts->h / 9;
+ int boxw = drw->fonts->h / 6 + 2;
+ unsigned int i, occ = 0, urg = 0;
+ Client *c;
+ Monitor *m = bar->mon;
+
+ for (c = m->clients; c; c = c->next) {
+ occ |= c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+ }
+
+ for (i = 0; i < LENGTH(tags); i++) {
+ invert = urg & 1 << i;
+ w = TEXTW(tags[i]);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], invert);
+ if (occ & 1 << i)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+ m == selmon && selmon->sel && selmon->sel->tags & 1 << i, invert);
+ x += w;
+ }
+
+ return x;
+}
+
+int
+click_tags(Bar *bar, Arg *arg, BarClickArg *a)
+{
+ int i = 0, x = lrpad / 2;
+
+ do {
+ x += TEXTW(tags[i]);
+ } while (a->rel_x >= x && ++i < LENGTH(tags));
+ if (i < LENGTH(tags)) {
+ arg->ui = 1 << i;
+ }
+ return ClkTagBar;
+}
diff --git a/patch/bar_tags.h b/patch/bar_tags.h
new file mode 100644
index 0000000..7ac04d8
--- /dev/null
+++ b/patch/bar_tags.h
@@ -0,0 +1,3 @@
+static int width_tags(Bar *bar, BarWidthArg *a);
+static int draw_tags(Bar *bar, BarDrawArg *a);
+static int click_tags(Bar *bar, Arg *arg, BarClickArg *a);
diff --git a/patch/bar_wintitle.c b/patch/bar_wintitle.c
new file mode 100644
index 0000000..3c11b75
--- /dev/null
+++ b/patch/bar_wintitle.c
@@ -0,0 +1,31 @@
+int
+width_wintitle(Bar *bar, BarWidthArg *a)
+{
+ return a->max_width;
+}
+
+int
+draw_wintitle(Bar *bar, BarDrawArg *a)
+{
+ int boxs = drw->fonts->h / 9;
+ int boxw = drw->fonts->h / 6 + 2;
+ int x = a->x, w = a->w;
+ Monitor *m = bar->mon;
+
+ if (m->sel) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+ } else {
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+ }
+ return x + w;
+}
+
+int
+click_wintitle(Bar *bar, Arg *arg, BarClickArg *a)
+{
+ return ClkWinTitle;
+}
diff --git a/patch/bar_wintitle.h b/patch/bar_wintitle.h
new file mode 100644
index 0000000..266404c
--- /dev/null
+++ b/patch/bar_wintitle.h
@@ -0,0 +1,3 @@
+static int width_wintitle(Bar *bar, BarWidthArg *a);
+static int draw_wintitle(Bar *bar, BarDrawArg *a);
+static int click_wintitle(Bar *bar, Arg *arg, BarClickArg *a);
diff --git a/patch/include.c b/patch/include.c
new file mode 100644
index 0000000..d422f56
--- /dev/null
+++ b/patch/include.c
@@ -0,0 +1,5 @@
+/* Bar functionality */
+#include "bar_ltsymbol.c"
+#include "bar_status.c"
+#include "bar_tags.c"
+#include "bar_wintitle.c"
\ No newline at end of file
diff --git a/patch/include.h b/patch/include.h
new file mode 100644
index 0000000..5f9a3fe
--- /dev/null
+++ b/patch/include.h
@@ -0,0 +1,5 @@
+/* Bar functionality */
+#include "bar_ltsymbol.h"
+#include "bar_status.h"
+#include "bar_tags.h"
+#include "bar_wintitle.h"
\ No newline at end of file
--
2.19.1
From bef83ecfe66bb83a8420239f8c068cf60d2c3e0c Mon Sep 17 00:00:00 2001
From: Bakkeby <bakkeby@gmail.com>
Date: Mon, 10 Jan 2022 14:07:02 +0100
Subject: [PATCH 2/2] Adding awesomebar barmodules patch.
Note that this patch does not come with bound ClkWinTitle button click
actions for extra behaviour when clicking on the window name in the bar.
The original bartabgroups patch included hardcoded focus on click which
has been replaced with a generic click for barmodules.
The intention here is that this is combined with the wintitleactions
patch that allow clients to be focused, zoomed and hidden - functionality
that has been separated from the original awesomebar patch.
In other words, all this patch does is showing all window titles in the
title bar with an even split between them.
---
config.def.h | 2 +-
patch/bar_awesomebar.c | 94 ++++++++++++++++++++++++++++++++++++++++++
patch/bar_awesomebar.h | 3 ++
patch/include.c | 3 +-
patch/include.h | 3 +-
5 files changed, 102 insertions(+), 3 deletions(-)
create mode 100644 patch/bar_awesomebar.c
create mode 100644 patch/bar_awesomebar.h
diff --git a/config.def.h b/config.def.h
index f870c41..74ad870 100644
--- a/config.def.h
+++ b/config.def.h
@@ -48,7 +48,7 @@ static const BarRule barrules[] = {
{ -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, "tags" },
{ -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, "layout" },
{ 'A', 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, "status" },
- { -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, "wintitle" },
+ { -1, 0, BAR_ALIGN_NONE, width_awesomebar, draw_awesomebar, click_awesomebar, "awesomebar" },
};
/* layout(s) */
diff --git a/patch/bar_awesomebar.c b/patch/bar_awesomebar.c
new file mode 100644
index 0000000..aa2e2e5
--- /dev/null
+++ b/patch/bar_awesomebar.c
@@ -0,0 +1,94 @@
+int
+width_awesomebar(Bar *bar, BarWidthArg *a)
+{
+ return a->max_width;
+}
+
+int
+draw_awesomebar(Bar *bar, BarDrawArg *a)
+{
+ int n = 0, scm, remainder = 0, tabw, pad;
+ unsigned int i;
+ #if BAR_TITLE_LEFT_PAD && BAR_TITLE_RIGHT_PAD
+ int x = a->x + lrpad / 2, w = a->w - lrpad;
+ #elif BAR_TITLE_LEFT_PAD
+ int x = a->x + lrpad / 2, w = a->w - lrpad / 2;
+ #elif BAR_TITLE_RIGHT_PAD
+ int x = a->x, w = a->w - lrpad / 2;
+ #else
+ int x = a->x, w = a->w;
+ #endif // BAR_TITLE_LEFT_PAD | BAR_TITLE_RIGHT_PAD
+
+ Client *c;
+ for (c = bar->mon->clients; c; c = c->next)
+ if (ISVISIBLE(c))
+ n++;
+
+ if (n > 0) {
+ remainder = w % n;
+ tabw = w / n;
+ for (i = 0, c = bar->mon->clients; c; c = c->next, i++) {
+ if (!ISVISIBLE(c))
+ continue;
+ if (bar->mon->sel == c)
+ #if BAR_VTCOLORS_PATCH
+ scm = SchemeTitleSel;
+ #elif BAR_TITLECOLOR_PATCH
+ scm = SchemeTitle;
+ #else
+ scm = SchemeSel;
+ #endif // BAR_VTCOLORS_PATCH / BAR_TITLECOLOR_PATCH
+ #ifdef HIDDEN
+ else if (HIDDEN(c))
+ scm = SchemeHid;
+ #endif
+ else
+ #if BAR_VTCOLORS_PATCH
+ scm = SchemeTitleNorm;
+ #else
+ scm = SchemeNorm;
+ #endif // BAR_VTCOLORS_PATCH
+
+ pad = lrpad / 2;
+ #if BAR_CENTEREDWINDOWNAME_PATCH
+ if (TEXTW(c->name) < tabw)
+ pad = (tabw - TEXTW(c->name) + lrpad) / 2;
+ #endif // BAR_CENTEREDWINDOWNAME_PATCH
+
+ drw_setscheme(drw, scheme[scm]);
+ #if BAR_PANGO_PATCH
+ drw_text(drw, x, 0, tabw + (i < remainder ? 1 : 0), bh, pad, c->name, 0, False);
+ #else
+ drw_text(drw, x, 0, tabw + (i < remainder ? 1 : 0), bh, pad, c->name, 0);
+ #endif // BAR_PANGO_PATCH
+ x += tabw + (i < remainder ? 1 : 0);
+ }
+ }
+ return a->x + a->w;
+}
+
+int
+click_awesomebar(Bar *bar, Arg *arg, BarClickArg *a)
+{
+ int x = 0, n = 0;
+ Client *c;
+
+ for (c = bar->mon->clients; c; c = c->next)
+ if (ISVISIBLE(c))
+ n++;
+
+ c = bar->mon->clients;
+
+ do {
+ if (!c || !ISVISIBLE(c))
+ continue;
+ else
+ x += (1.0 / (double)n) * a->rel_w;
+ } while (c && a->rel_x > x && (c = c->next));
+
+ if (c) {
+ arg->v = c;
+ return ClkWinTitle;
+ }
+ return -1;
+}
\ No newline at end of file
diff --git a/patch/bar_awesomebar.h b/patch/bar_awesomebar.h
new file mode 100644
index 0000000..3269954
--- /dev/null
+++ b/patch/bar_awesomebar.h
@@ -0,0 +1,3 @@
+static int width_awesomebar(Bar *bar, BarWidthArg *a);
+static int draw_awesomebar(Bar *bar, BarDrawArg *a);
+static int click_awesomebar(Bar *bar, Arg *arg, BarClickArg *a);
\ No newline at end of file
diff --git a/patch/include.c b/patch/include.c
index d422f56..6ae83ed 100644
--- a/patch/include.c
+++ b/patch/include.c
@@ -2,4 +2,5 @@
#include "bar_ltsymbol.c"
#include "bar_status.c"
#include "bar_tags.c"
-#include "bar_wintitle.c"
\ No newline at end of file
+//#include "bar_wintitle.c"
+#include "bar_awesomebar.c"
\ No newline at end of file
diff --git a/patch/include.h b/patch/include.h
index 5f9a3fe..de77a11 100644
--- a/patch/include.h
+++ b/patch/include.h
@@ -2,4 +2,5 @@
#include "bar_ltsymbol.h"
#include "bar_status.h"
#include "bar_tags.h"
-#include "bar_wintitle.h"
\ No newline at end of file
+//#include "bar_wintitle.h"
+#include "bar_awesomebar.h"
\ No newline at end of file
--
2.19.1