Compare commits

...

3 Commits

Author SHA1 Message Date
Dhruva Sambrani
6882f753c5 fix extrabar again 2026-03-11 19:17:12 +01:00
Dhruva Sambrani
585f636ea1 fix the extrabar patch 2026-03-11 19:15:26 +01:00
Dhruva Sambrani
f46616216f add extrabar 2026-03-11 19:11:52 +01:00
2 changed files with 210 additions and 0 deletions

View File

@ -0,0 +1,17 @@
### extrabar
Add an extra bar on the other side of the primary bar, shows additional status sections.
_Requires_ `bar` patch to be applied first. Heavily inspired by `dwm`'s extrabar patch.
### Status
The status text on the extra bar is set using the stdin as usual, with the text being split by `;`
For example, if `status1;status2;status3` was set,
then `status1` is set as the status of the primary bar,
`status2` is set as the left status of extrabar,
`status3` is set as the right status of extrabar.
### Author
[dhruva_sambrani](/dhruva_sambrani)

View File

@ -0,0 +1,193 @@
diff --git a/dwl.c b/dwl.c
index 7fe9468..4e3272e 100644
--- a/dwl.c
+++ b/dwl.c
@@ -205,6 +205,7 @@ struct Monitor {
struct wlr_output *wlr_output;
struct wlr_scene_output *scene_output;
struct wlr_scene_buffer *scene_buffer; /* bar buffer */
+ struct wlr_scene_buffer *extra_scene_buffer; /* bar buffer */
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
struct wl_listener frame;
struct wl_listener destroy;
@@ -230,6 +231,7 @@ struct Monitor {
int asleep;
Drwl *drw;
Buffer *pool[2];
+ Buffer *extra_pool[2];
int lrpad;
};
@@ -278,7 +280,7 @@ static void bufdestroy(struct wlr_buffer *buffer);
static bool bufdatabegin(struct wlr_buffer *buffer, uint32_t flags,
void **data, uint32_t *format, size_t *stride);
static void bufdataend(struct wlr_buffer *buffer);
-static Buffer *bufmon(Monitor *m);
+static Buffer *bufmon(Monitor *m, Buffer **pool);
static void bufrelease(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -444,6 +446,8 @@ static struct wl_list mons;
static Monitor *selmon;
static char stext[256];
+static char stext2[256];
+static char stext3[256];
static struct wl_event_source *status_event_source;
static const struct wlr_buffer_impl buffer_impl = {
@@ -627,6 +631,11 @@ arrangelayers(Monitor *m)
usable_area.y += topbar ? m->b.real_height : 0;
}
+ if (m->extra_scene_buffer->node.enabled) {
+ usable_area.height -= m->b.real_height;
+ usable_area.y += topbar ? 0 : m->b.real_height;
+ }
+
/* Arrange exclusive surfaces from top->bottom */
for (i = 3; i >= 0; i--)
arrangelayer(m, &m->layers[i], &usable_area, 1);
@@ -706,23 +715,23 @@ bufdataend(struct wlr_buffer *wlr_buffer)
}
Buffer *
-bufmon(Monitor *m)
+bufmon(Monitor *m, Buffer **pool)
{
size_t i;
Buffer *buf = NULL;
for (i = 0; i < LENGTH(m->pool); i++) {
- if (m->pool[i]) {
- if (m->pool[i]->busy)
+ if (pool[i]) {
+ if (pool[i]->busy)
continue;
- buf = m->pool[i];
+ buf = pool[i];
break;
}
buf = ecalloc(1, sizeof(Buffer) + (m->b.width * 4 * m->b.height));
buf->image = drwl_image_create(NULL, m->b.width, m->b.height, buf->data);
wlr_buffer_init(&buf->base, &buffer_impl, m->b.width, m->b.height);
- m->pool[i] = buf;
+ pool[i] = buf;
break;
}
if (!buf)
@@ -1255,6 +1264,8 @@ createmon(struct wl_listener *listener, void *data)
m->scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL);
m->scene_buffer->point_accepts_input = baracceptsinput;
+ m->extra_scene_buffer = wlr_scene_buffer_create(layers[LyrBottom], NULL);
+ m->extra_scene_buffer->point_accepts_input = baracceptsinput;
updatebar(m);
wl_list_insert(&mons, &m->link);
@@ -1580,7 +1591,7 @@ drawbar(Monitor *m)
if (!m->scene_buffer->node.enabled)
return;
- if (!(buf = bufmon(m)))
+ if (!(buf = bufmon(m, m->pool)))
return;
/* draw status first so it can be overdrawn by tags later */
@@ -1633,13 +1644,52 @@ drawbar(Monitor *m)
wlr_buffer_unlock(&buf->base);
}
+void
+extrabar(Monitor *m)
+{
+ int tw = 0;
+ Buffer *buf = NULL;
+
+ /* Skip if the extra bar scene buffer is not initialized/enabled */
+ if (!m->extra_scene_buffer || !m->extra_scene_buffer->node.enabled)
+ return;
+
+ /* Inline bufmon logic for the extra pool to keep changes contained */
+ if (!(buf = bufmon(m, m->extra_pool)))
+ return;
+
+ buf->busy = true;
+ LISTEN(&buf->base.events.release, &buf->release, bufrelease);
+ wlr_buffer_lock(&buf->base);
+ drwl_setimage(m->drw, buf->image);
+
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
+ drwl_rect(m->drw, 0, 0, m->b.width, m->b.height, 1, 1);
+
+ drwl_setscheme(m->drw, colors[SchemeNorm]);
+ tw = TEXTW(m, stext2) - m->lrpad + 2; /* 2px right padding */
+ drwl_text(m->drw, 2, 0, tw, m->b.height, 0, stext2, 0);
+
+ tw = TEXTW(m, stext3) - m->lrpad + 2; /* 2px right padding */
+ drwl_text(m->drw, m->b.width - tw - 4, 0, tw, m->b.height, 0, stext3, 0);
+
+ wlr_scene_buffer_set_dest_size(m->extra_scene_buffer, m->b.real_width, m->b.real_height);
+ wlr_scene_node_set_position(&m->extra_scene_buffer->node, m->m.x,
+ m->m.y + (topbar ? m->m.height - m->b.real_height : 0));
+
+ wlr_scene_buffer_set_buffer(m->extra_scene_buffer, &buf->base);
+ wlr_buffer_unlock(&buf->base);
+}
+
void
drawbars(void)
{
Monitor *m = NULL;
- wl_list_for_each(m, &mons, link)
+ wl_list_for_each(m, &mons, link) {
drawbar(m);
+ extrabar(m);
+ }
}
void
@@ -2896,7 +2946,7 @@ startdrag(struct wl_listener *listener, void *data)
int
statusin(int fd, unsigned int mask, void *data)
{
- char status[256];
+ char status[3*256];
ssize_t n;
if (mask & WL_EVENT_ERROR)
@@ -2911,7 +2961,18 @@ statusin(int fd, unsigned int mask, void *data)
status[n] = '\0';
status[strcspn(status, "\n")] = '\0';
- strncpy(stext, status, sizeof(stext));
+ char *l1 = strchr(status, ';');
+ if (l1) {
+ *l1 = '\0';
+ char *l2 = strchr(++l1, ';');
+ if (l2) {
+ *l2 = '\0';
+ strncpy(stext3, ++l2, sizeof(stext3));
+ }
+ strncpy(stext2, l1, sizeof(stext2));
+ }
+ strncpy(stext, status, sizeof(stext));
+
drawbars();
return 0;
@@ -3206,6 +3267,12 @@ updatebar(Monitor *m)
m->pool[i] = NULL;
}
+ for (i = 0; i < LENGTH(m->extra_pool); i++)
+ if (m->extra_pool[i]) {
+ wlr_buffer_drop(&m->extra_pool[i]->base);
+ m->extra_pool[i] = NULL;
+ }
+
if (m->b.scale == m->wlr_output->scale && m->drw)
return;