commit 10095f4

wf  ·  2026-06-08 11:05:33 +0000 UTC
parent 9bfbbe3
Add proper module positioning
1 files changed,  +105, -27
+105, -27
  1@@ -21,7 +21,7 @@
  2 #include "xdg-shell-protocol.h"
  3 #include "wlr-layer-shell-unstable-v1.h"
  4 
  5-#define MAXMOD 4
  6+#define MAXMOD 6
  7 
  8 #define LOG(...) fprintf(stderr, "panko: " __VA_ARGS__)
  9 #define ERRNUM(elem) \
 10@@ -29,11 +29,13 @@
 11 #define ERRINC(elem) \
 12 	LOG("at line %d: incorrect value for option `%s`\n", elem.lineno, elem.name); return false
 13 
 14-enum { SIDE_LEFT, SIDE_MIDDLE, SIDE_RIGHT };
 15+enum side { SIDE_LEFT, SIDE_MIDDLE, SIDE_RIGHT };
 16+enum edge { EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_LEFT };
 17+
 18 struct module {
 19 	char *name, *command;
 20 	uint32_t interval;
 21-	uint32_t margins[4], padding[4];
 22+	int32_t margins[4], padding[4];
 23 	uint32_t width, height;
 24 	struct {
 25 		uint32_t foreground, background;
 26@@ -52,7 +54,7 @@ struct module {
 27 struct config {
 28 	uint32_t width, height;
 29 	enum zwlr_layer_surface_v1_anchor anchor;
 30-	uint32_t margins[4], padding[4];
 31+	int32_t margins[4];
 32 	bool exclusive;
 33 	struct {
 34 		uint32_t foreground, background;
 35@@ -144,7 +146,7 @@ now_ms(void) {
 36 }
 37 
 38 static void
 39-module_add(struct app *app, struct module *m, int side) {
 40+module_add(struct app *app, struct module *m, enum side side) {
 41 	for (size_t i = 0; i < MAXMOD; i++) {
 42 		if (app->panel.modules[side][i] == NULL) {
 43 			app->panel.modules[side][i] = m;
 44@@ -173,7 +175,6 @@ module_run(struct module *m) {
 45 
 46 	if (pid == 0) {
 47 		dup2(fds[1], STDOUT_FILENO);
 48-		dup2(fds[1], STDERR_FILENO);
 49 		close(fds[0]);
 50 		close(fds[1]);
 51 		execl("/bin/sh", "sh", "-c", m->command, NULL);
 52@@ -286,13 +287,12 @@ parse_config(const char *path, struct app *app) {
 53 			}
 54 		}
 55 
 56-		else if (strcmp(d.name, "margins") == 0 || strcmp(d.name, "padding") == 0) {
 57+		else if (strcmp(d.name, "margins") == 0) {
 58 			if (d.params_len != 4) {
 59 				ERRNUM(d);
 60 			}
 61-			uint32_t *k = d.name[0] == 'm' ? app->config.margins : app->config.padding;
 62 			for (int j = 0; j < 4; j++)
 63-				k[j] = strtoul(d.params[j], NULL, 0);
 64+				app->config.margins[j] = strtol(d.params[j], NULL, 0);
 65 		}
 66 
 67 		else if (strcmp(d.name, "exclusive") == 0) {
 68@@ -367,9 +367,9 @@ parse_config(const char *path, struct app *app) {
 69 					if (s.params_len != 4) {
 70 						ERRNUM(s);
 71 					}
 72-					uint32_t *k = s.name[0] == 'm' ? m.margins : m.padding;
 73+					int32_t *k = s.name[0] == 'm' ? m.margins : m.padding;
 74 					for (int y = 0; y < 4; y++)
 75-						k[y] = strtoul(s.params[y], NULL, 0);
 76+						k[y] = strtol(s.params[y], NULL, 0);
 77 				}
 78 
 79 				else if (strcmp(s.name, "width") == 0 || strcmp(s.name, "height") == 0) {
 80@@ -451,7 +451,7 @@ parse_config(const char *path, struct app *app) {
 81 			if (d.params_len < 0) {
 82 				ERRNUM(d);
 83 			}
 84-			int side = (d.name[8] == 'l') ? SIDE_LEFT : (d.name[8] == 'm') ? SIDE_MIDDLE : SIDE_RIGHT;
 85+			enum side side = (d.name[8] == 'l') ? SIDE_LEFT : (d.name[8] == 'm') ? SIDE_MIDDLE : SIDE_RIGHT;
 86 			for (size_t p = 0; p < d.params_len; p++) {
 87 				const char *name = d.params[p];
 88 				if (name[0] == '\0')
 89@@ -616,7 +616,7 @@ setup(struct app *app) {
 90 		struct module *m = app->panel.parsed[i];
 91 		m->fd = -1;
 92 		m->pid = 0;
 93-		m->buf = NULL;
 94+		m->buf = strdup("");
 95 		m->buflen = 0;
 96 		m->next = 0;
 97 
 98@@ -628,26 +628,104 @@ setup(struct app *app) {
 99 }
100 
101 static void
102-draw(struct app *app) {
103-	uint32_t start_x[3] = {0, app->config.width / 2, app->config.width};
104+module_draw(struct app *app, struct module *m, uint32_t x) {
105+	struct wld_extents ext;
106+	wld_font_text_extents(app->wld_font, m->buf, &ext);
107+
108+	uint32_t tw = (uint32_t)ext.advance;
109+	uint32_t th = app->wld_font->height;
110+
111+	uint32_t mw = m->width ? m->width : tw + m->padding[1] + m->padding[3];
112+	uint32_t mh = m->height ? m->height : th + m->padding[0] + m->padding[2];
113+	int32_t mx = x + m->margins[3];
114+	int32_t my = app->config.height / 2 + m->margins[0] - (int32_t)mh / 2;
115+
116+	int32_t cw = mw - m->padding[1] - m->padding[3];
117+	int32_t ch = mh - m->padding[0] - m->padding[2];
118+	int32_t cx = mx + m->padding[3];
119+	int32_t cy = my + m->padding[0];
120+
121+	uint32_t tx = cx + (cw - tw) / 2;
122+	int32_t ty = cy + ch / 2 + th / 2 - app->wld_font->descent;
123+
124+	wld_fill_rectangle(app->wld_ren, m->style.background,
125+		mx, my, mw, mh);
126+	wld_draw_text(app->wld_ren, app->wld_font, m->style.foreground,
127+		tx, ty, m->buf, m->buflen, NULL);
128+}
129 
130+static void
131+draw(struct app *app) {
132 	wld_set_target_surface(app->wld_ren, app->wld_surface);
133-	wld_fill_rectangle(app->wld_ren, app->config.style.background, 0, 0,
134-		app->config.width, app->config.height);
135+	wld_fill_rectangle(app->wld_ren, app->config.style.background,
136+		0, 0, app->config.width, app->config.height);
137+
138+	/* left */
139+	{
140+		int32_t x = 0;
141 
142-	for (int s = 0; s < 3; s++) {
143 		for (size_t i = 0; i < MAXMOD; i++) {
144-			if (app->panel.modules[s][i] != NULL) {
145-				struct module *m = app->panel.modules[s][i];
146+			struct module *m = app->panel.modules[SIDE_LEFT][i];
147+			if (!m || m->buflen == 0)
148+				continue;
149+			module_draw(app, m, x);
150 
151-				struct wld_extents ext;
152-				wld_font_text_extents(app->wld_font, m->buf, &ext);
153-				int y = app->config.height / 2 + app->wld_font->height / 2 - app->wld_font->descent
154-					+ app->config.padding[0] - app->config.padding[2];
155+			struct wld_extents ext;
156+			wld_font_text_extents(app->wld_font, m->buf, &ext);
157+			uint32_t w = m->width ? m->width : ext.advance + m->padding[1] + m->padding[3];
158 
159-				wld_draw_text(app->wld_ren, app->wld_font, app->config.style.foreground,
160-					app->config.padding[3], y, m->buf, m->buflen, NULL);
161-			}
162+			x += w;
163+		}
164+	}
165+
166+	/* middle
167+	 * I would love to have a better way to do this, but I don't know how */
168+	{
169+		uint32_t tw = 0;
170+
171+		for (size_t i = 0; i < MAXMOD; i++) {
172+			struct module *m = app->panel.modules[SIDE_MIDDLE][i];
173+			if (!m || m->buflen == 0)
174+				continue;
175+
176+			struct wld_extents ext;
177+			wld_font_text_extents(app->wld_font, m->buf, &ext);
178+			uint32_t w = m->width ? m->width : ext.advance + m->padding[1] + m->padding[3];
179+
180+			tw += w;
181+		}
182+
183+		int32_t x = app->config.width / 2 - tw / 2;
184+
185+		for (size_t i = 0; i < MAXMOD; i++) {
186+			struct module *m = app->panel.modules[SIDE_MIDDLE][i];
187+			if (!m || m->buflen == 0)
188+				continue;
189+			module_draw(app, m, x);
190+
191+			struct wld_extents ext;
192+			wld_font_text_extents(app->wld_font, m->buf, &ext);
193+			uint32_t w = m->width ? m->width : ext.advance + m->padding[1] + m->padding[3];
194+
195+			x += w;
196+		}
197+	}
198+
199+	/* right */
200+	{
201+		int32_t x = app->config.width;
202+
203+		for (size_t i = MAXMOD; i > 0; --i) {
204+			struct module *m = app->panel.modules[SIDE_RIGHT][i - 1];
205+			if (!m || m->buflen == 0)
206+				continue;
207+
208+			struct wld_extents ext;
209+			wld_font_text_extents(app->wld_font, m->buf, &ext);
210+			uint32_t w = m->width ? m->width : ext.advance + m->padding[1] + m->padding[3];
211+
212+			x -= w + m->margins[1];
213+			module_draw(app, m, x);
214 		}
215 	}
216