Commit Diff


commit - c2ca3402b92d106af09010320b729704fb5c379b
commit + f04a5f5c2efc8b90ca3004c28f534b3cee737c2c
blob - 7e4e035b5bc8a122de59be66afa1586aa74232c2
blob + e148a4ee2d2e5c52dda8a64e7bf4698776d74e51
--- bxnotify.c
+++ bxnotify.c
@@ -39,6 +39,18 @@ static TextBlock tb; 
 static int total_height;
 static time_t start_time;
 static char reg_path[256];
+/* Global runtime configuration (defaults from config.h) */
+static int cfg_width = WIN_WIDTH;
+static int cfg_win_x = WIN_X;
+static int cfg_win_y = WIN_Y;
+static int cfg_padding = PADDING;
+static int cfg_border_width = BORDER_WIDTH;
+static int cfg_align = ALIGN;
+static int cfg_duration = DURATION;
+static const char *cfg_fg = FG_COLOR;
+static const char *cfg_bg = BG_COLOR;
+static const char *cfg_border = BORDER_COLOR;
+static const char *cfg_font = FONT;
 
 /* Forward Declarations */
 static void die(const char *fmt, ...);
@@ -60,10 +72,23 @@ static void run(void);
 int
 main(int argc, char *argv[])
 {
+    int opt;
+    while ((opt = getopt(argc, argv, "d:f:F:B:C:a:")) != -1) {
+        switch (opt) {
+        case 'd': cfg_duration = atoi(optarg); break;
+        case 'f': cfg_font = optarg;           break;
+        case 'F': cfg_fg = optarg;             break;
+        case 'B': cfg_bg = optarg;             break;
+        case 'C': cfg_border = optarg;         break;
+        case 'a': cfg_align = atoi(optarg);    break;
+        default:
+            die("usage: bxnotify [-d duration] [-f font] [-F fg] [-B bg] [-a align]\n");
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
     signal(SIGUSR1, sigusr1);
-
-    /* TODO: parse cli flags, override config.h */
-
     readstdin();
     init_display();
 	calc_layout();
@@ -168,7 +193,7 @@ init_display(void)
 
     screen = DefaultScreen(dpy);
 
-    if (!(font = XftFontOpenName(dpy, screen, FONT)))
+    if (!(font = XftFontOpenName(dpy, screen, cfg_font)))
         die("bxnotify: cannot load font\n");
 }
 
@@ -182,10 +207,10 @@ calc_layout(void)
     for (int i = 0; i < tb.count; i++) {
         char *line = tb.lines[i];
         
-        while (measure_text(line) > WIN_WIDTH) {
+        while (measure_text(line) > cfg_width) {
             /* Find break point */
             char *p = line + strlen(line);
-            while (p > line && measure_text(line) > WIN_WIDTH) {
+            while (p > line && measure_text(line) > cfg_width) {
                 while (p > line && *p != ' ') p--;
                 if (p == line) break; /* Cannot wrap, forced break */
                 *p = '\0';
@@ -205,7 +230,7 @@ calc_layout(void)
     free(tb.lines);
     tb.lines = wrapped;
     tb.count = wrapped_count;
-    total_height = (tb.count * line_h) + ((tb.count + 1) * PADDING) + (2 * BORDER_WIDTH);
+    total_height = (tb.count * line_h) + ((tb.count + 1) * cfg_padding) + (2 * cfg_border_width);
 }
 
 static void
@@ -220,12 +245,12 @@ static int
 get_and_register_stack_y(int my_h)
 {
     int fd = open(reg_path, O_RDWR | O_CREAT, 0644);
-    if (fd == -1) return WIN_Y; /* Fallback if file fails to open */
+    if (fd == -1) return cfg_win_y; /* Fallback if file fails to open */
 
     /* Wait for exclusive lock - blocks until no other bxnotify is reading/writing */
     flock(fd, LOCK_EX);
 
-    int my_y = WIN_Y;
+    int my_y = cfg_win_y;
     int lowest_y = 0;
     
     /* Store valid PIDs so we can rewrite the file cleanly */
@@ -250,7 +275,7 @@ get_and_register_stack_y(int my_h)
         }
 
         /* 2. Calculate our Y position */
-        my_y = (lowest_y > 0) ? lowest_y + 16 : WIN_Y;
+        my_y = (lowest_y > 0) ? lowest_y + 16 : cfg_win_y;
 
         /* 3. Clear file and rewrite with valid PIDs + our new one */
         ftruncate(fd, 0); /* Erase file contents */
@@ -344,8 +369,8 @@ static void
 setup(int y, int win_h)
 {
     XSetWindowAttributes swa;
-    int win_w = WIN_WIDTH + 2 * BORDER_WIDTH;
-    int x = DisplayWidth(dpy, screen) - win_w - WIN_X;
+    int win_w = cfg_width + 2 * cfg_border_width;
+    int x = DisplayWidth(dpy, screen) - win_w - cfg_win_x;
     
     swa.override_redirect = True;
     swa.background_pixel = bg.pixel;
@@ -359,11 +384,11 @@ setup(int y, int win_h)
                         &swa);
 
     /* Allocate colors and draw context... */
-    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), FG_COLOR, &fg))
+    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), cfg_fg, &fg))
         die("bxnotify: cannot allocate fg color\n");
-    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), BG_COLOR, &bg))
+    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), cfg_bg, &bg))
         die("bxnotify: cannot allocate bg color\n");
-    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), BORDER_COLOR, &border))
+    if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), cfg_border, &border))
         die("bxnotify: cannot allocate border color\n");
 
     xft_draw = XftDrawCreate(dpy, win, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
@@ -382,21 +407,21 @@ draw(void)
 {
     int line_h = font->ascent + font->descent;
     /* Redraw background... */
-    XftDrawRect(xft_draw, &border, 0, 0, WIN_WIDTH + 2 * BORDER_WIDTH, total_height);
-    XftDrawRect(xft_draw, &bg, BORDER_WIDTH, BORDER_WIDTH, WIN_WIDTH, total_height - 2 * BORDER_WIDTH);
+    XftDrawRect(xft_draw, &border, 0, 0, cfg_width + 2 * cfg_border_width, total_height);
+    XftDrawRect(xft_draw, &bg, cfg_border_width, cfg_border_width, cfg_width, total_height - 2 * cfg_border_width);
 
     for (int i = 0; i < tb.count; i++) {
         /* Calculate Y for this specific line */
-        int y = PADDING + BORDER_WIDTH + (i * line_h) + font->ascent;
+        int y = cfg_padding + cfg_border_width + (i * line_h) + font->ascent;
         int x;
         XGlyphInfo ext;
         XftTextExtentsUtf8(dpy, font, (XftChar8 *)tb.lines[i], strlen(tb.lines[i]), &ext);
         
-        switch (ALIGN) {
-            case 0: x = BORDER_WIDTH + PADDING; break;
-            case 1: x = BORDER_WIDTH + (WIN_WIDTH - ext.width) / 2; break;
-            case 2: x = BORDER_WIDTH + (WIN_WIDTH - ext.width - PADDING); break;
-            default: x = BORDER_WIDTH + PADDING; break;
+        switch (cfg_align) {
+            case 0: x = cfg_border_width + cfg_padding; break;
+            case 1: x = cfg_border_width + (cfg_width - ext.width) / 2; break;
+            case 2: x = cfg_border_width + (cfg_width - ext.width - cfg_padding); break;
+            default: x = cfg_border_width + cfg_padding; break;
         }
         XftDrawStringUtf8(xft_draw, &fg, font, x, y, (XftChar8 *)tb.lines[i], strlen(tb.lines[i]));
     }
@@ -426,7 +451,7 @@ run(void)
             }
         }
         /* Check duration timeout */
-        if (DURATION > 0 && (time(NULL) - start_time) >= DURATION)
+        if (cfg_duration > 0 && (time(NULL) - start_time) >= cfg_duration)
             running = 0;
 
         struct timespec ts = {0, 10000000};  /* 10 milliseconds */