commit - 715dc48d96e849954524bc47757a69649abac0ac
commit + 95eeecbe5f3f4edfeb5f5e93b4bebd14744f30b2
blob - e0ba0644373ae3e4f5aa93ddb249556b5c63a046
blob + e3561d389654adb32ec21d28b3a67a9d0893e0c4
--- bxnotify.c
+++ bxnotify.c
#define _POSIX_C_SOURCE 200809L
#include <fcntl.h>
-#include <getopts.h>
+#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
for (int i = 0; i < tb.count; i++) {
char *line = tb.lines[i];
-
+
while (measure_text(line) > cfg_width) {
- /* Find break point */
+ /* Try to find a space that produces a fitting prefix */
char *p = line + strlen(line);
- while (p > line && measure_text(line) > cfg_width) {
- while (p > line && *p != ' ') p--;
- if (p == line) break; /* Cannot wrap, forced break */
+ while (p > line && *p != ' ') p--;
+ char *chunk;
+
+ if (p > line) {
+ /* Word break found: split at the space */
*p = '\0';
+ chunk = strdup(line);
+ line = p + 1;
+ } else {
+ /* No space: hard-break on the largest fitting prefix.
+ * Reserve cfg_padding on the right for visual breathing room. */
+ int lo = 1, hi = (int)strlen(line);
+ int effective_width = cfg_width - cfg_padding;
+ while (lo < hi) {
+ int mid = lo + (hi - lo + 1) / 2;
+ char saved = line[mid];
+ line[mid] = '\0';
+ if (measure_text(line) <= effective_width)
+ lo = mid;
+ else
+ hi = mid - 1;
+ line[mid] = saved;
+ }
+ char saved = line[lo];
+ line[lo] = '\0';
+ chunk = strdup(line);
+ line[lo] = saved;
+ line = line + lo;
}
- /* Add chunk */
+
wrapped = realloc(wrapped, (++wrapped_count) * sizeof(char *));
- wrapped[wrapped_count - 1] = strdup(line);
- line = p + 1;
+ if (!wrapped) die("bxnotify: realloc failed\n");
+ wrapped[wrapped_count - 1] = chunk;
}
- /* Add remainder */
+ /* Add remainder (always fits) */
wrapped = realloc(wrapped, (++wrapped_count) * sizeof(char *));
+ if (!wrapped) die("bxnotify: realloc failed\n");
wrapped[wrapped_count - 1] = strdup(line);
}