diff options
-rw-r--r-- | config.def.h | 6 | ||||
-rw-r--r-- | config.h | 6 | ||||
-rw-r--r-- | dmenu.c | 180 | ||||
-rw-r--r-- | patches/dmenu-center-20250407-b1e217b.diff | 135 | ||||
-rw-r--r-- | patches/dmenu-mousesupport-5.3.diff | 145 | ||||
-rw-r--r-- | patches/dmenu-mousesupport-motion-5.2.diff | 53 | ||||
-rw-r--r-- | patches/dmenu-xresources-4.9.diff | 126 |
7 files changed, 625 insertions, 26 deletions
diff --git a/config.def.h b/config.def.h index d27a5d8..3a36d3e 100644 --- a/config.def.h +++ b/config.def.h @@ -2,11 +2,12 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -static int centered = 0; /* -c option; centers dmenu on screen */ +static int centered = 1; /* -c option; centers dmenu on screen */ static int min_width = 500; /* minimum width when centered */ +static const float menu_height_ratio = 4.0f; /* This is the ratio used in the original calculation */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { - "JetBrainsMono Nerd Font Mono:size=11" + "JetBrainsMono Nerd Font Mono:size=11" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { @@ -14,7 +15,6 @@ static const char *colors[SchemeLast][2] = { [SchemeNorm] = { "#bbbbbb", "#222222" }, [SchemeSel] = { "#eeeeee", "#005577" }, [SchemeOut] = { "#000000", "#00ffff" }, - [SchemeBorder] = { "#cccccc", NULL }, }; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; @@ -2,11 +2,12 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -static int centered = 0; /* -c option; centers dmenu on screen */ +static int centered = 1; /* -c option; centers dmenu on screen */ static int min_width = 500; /* minimum width when centered */ +static const float menu_height_ratio = 4.0f; /* This is the ratio used in the original calculation */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { - "JetBrainsMono Nerd Font Mono:size=11" + "JetBrainsMono Nerd Font Mono:size=11" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { @@ -14,7 +15,6 @@ static const char *colors[SchemeLast][2] = { [SchemeNorm] = { "#bbbbbb", "#222222" }, [SchemeSel] = { "#eeeeee", "#005577" }, [SchemeOut] = { "#000000", "#00ffff" }, - [SchemeBorder] = { "#cccccc", NULL }, }; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; @@ -26,10 +26,11 @@ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ -enum { SchemeNorm, SchemeSel, SchemeOut, SchemeBorder, SchemeLast }; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ struct item { char *text; + unsigned int width; struct item *left, *right; int out; }; @@ -54,7 +55,7 @@ static Drw *drw; static Clr *scheme[SchemeLast]; /* Temporary arrays to allow overriding xresources values */ -static char *colortemp[5]; +static char *colortemp[4]; static char *tempfonts; #include "config.h" @@ -105,7 +106,7 @@ max_textw(void) { int len = 0; for (struct item *item = items; item && item->text; item++) - len = MAX(TEXTW(item->text), len); + len = MAX(item->width, len); return len; } @@ -542,6 +543,142 @@ draw: } static void +buttonpress(XEvent *e) +{ + struct item *item; + XButtonPressedEvent *ev = &e->xbutton; + int x = 0, y = 0, h = bh, w; + + if (ev->window != win) + return; + + /* right-click: exit */ + if (ev->button == Button3) + exit(1); + + if (prompt && *prompt) + x += promptw; + + /* input field */ + w = (lines > 0 || !matches) ? mw - x : inputw; + + /* left-click on input: clear input, + * NOTE: if there is no left-arrow the space for < is reserved so + * add that to the input width */ + if (ev->button == Button1 && + ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + + ((!prev || !curr->left) ? TEXTW("<") : 0)) || + (lines > 0 && ev->y >= y && ev->y <= y + h))) { + insert(NULL, -cursor); + drawmenu(); + return; + } + /* middle-mouse click: paste selection */ + if (ev->button == Button2) { + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + utf8, utf8, win, CurrentTime); + drawmenu(); + return; + } + /* scroll up */ + if (ev->button == Button4 && prev) { + sel = curr = prev; + calcoffsets(); + drawmenu(); + return; + } + /* scroll down */ + if (ev->button == Button5 && next) { + sel = curr = next; + calcoffsets(); + drawmenu(); + return; + } + if (ev->button != Button1) + return; + if (ev->state & ~ControlMask) + return; + if (lines > 0) { + /* vertical list: (ctrl)left-click on item */ + w = mw - x; + for (item = curr; item != next; item = item->right) { + y += h; + if (ev->y >= y && ev->y <= (y + h)) { + puts(item->text); + if (!(ev->state & ControlMask)) + exit(0); + sel = item; + if (sel) { + sel->out = 1; + drawmenu(); + } + return; + } + } + } else if (matches) { + /* left-click on left arrow */ + x += inputw; + w = TEXTW("<"); + if (prev && curr->left) { + if (ev->x >= x && ev->x <= x + w) { + sel = curr = prev; + calcoffsets(); + drawmenu(); + return; + } + } + /* horizontal list: (ctrl)left-click on item */ + for (item = curr; item != next; item = item->right) { + x += w; + w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); + if (ev->x >= x && ev->x <= x + w) { + puts(item->text); + if (!(ev->state & ControlMask)) + exit(0); + sel = item; + if (sel) { + sel->out = 1; + drawmenu(); + } + return; + } + } + /* left-click on right arrow */ + w = TEXTW(">"); + x = mw - w; + if (next && ev->x >= x && ev->x <= x + w) { + sel = curr = next; + calcoffsets(); + drawmenu(); + return; + } + } +} + +static void +motionevent(XButtonEvent *ev) +{ + struct item *it; + int xy, ev_xy; + + if (ev->window != win || matches == 0) + return; + + xy = lines > 0 ? bh : inputw + promptw + TEXTW("<"); + ev_xy = lines > 0 ? ev->y : ev->x; + for (it = curr; it && it != next; it = it->right) { + int wh = lines > 0 ? bh : textw_clamp(it->text, mw - xy - TEXTW(">")); + if (ev_xy >= xy && ev_xy < (xy + wh)) { + sel = it; + calcoffsets(); + drawmenu(); + break; + } + xy += wh; + } +} + +static void paste(void) { char *p, *q; @@ -577,6 +714,7 @@ readstdin(void) line[len - 1] = '\0'; if (!(items[i].text = strdup(line))) die("strdup:"); + items[i].width = TEXTW(line); items[i].out = 0; } @@ -600,6 +738,12 @@ run(void) break; cleanup(); exit(1); + case ButtonPress: + buttonpress(&ev); + break; + case MotionNotify: + motionevent(&ev.xbutton); + break; case Expose: if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); @@ -685,7 +829,7 @@ setup(void) if (centered) { mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); x = info[i].x_org + ((info[i].width - mw) / 2); - y = info[i].y_org + ((info[i].height - mh) / 2); + y = info[i].y_org + ((info[i].height - mh) / menu_height_ratio); } else { x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); @@ -708,21 +852,23 @@ setup(void) x = 0; y = topbar ? 0 : wa.height - mh; mw = wa.width; - } + } } - + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = mw / 3; /* input width: ~33% of monitor width */ match(); /* create menu window */ swa.override_redirect = True; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | + ButtonPressMask | PointerMotionMask; win = XCreateWindow(dpy, parentwin, x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); if (border_width) - XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColFg].pixel); + XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); + XSetClassHint(dpy, win, &ch); /* input methods */ @@ -784,10 +930,6 @@ readxresources(void) { colors[SchemeSel][ColFg] = strdup(xval.addr); else colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]); - if (XrmGetResource(xdb, "dmenu.border", "*", &type, &xval)) - colors[SchemeBorder][ColFg] = strdup(xval.addr); - else - colors[SchemeBorder][ColFg] = strdup(colors[SchemeBorder][ColFg]); XrmDestroyDatabase(xdb); } @@ -856,15 +998,13 @@ main(int argc, char *argv[]) if ( tempfonts ) fonts[0] = strdup(tempfonts); if ( colortemp[0]) - colors[SchemeNorm][ColBg] = strdup(colortemp[0]); + colors[SchemeNorm][ColBg] = strdup(colortemp[0]); if ( colortemp[1]) - colors[SchemeNorm][ColFg] = strdup(colortemp[1]); + colors[SchemeNorm][ColFg] = strdup(colortemp[1]); if ( colortemp[2]) - colors[SchemeSel][ColBg] = strdup(colortemp[2]); + colors[SchemeSel][ColBg] = strdup(colortemp[2]); if ( colortemp[3]) - colors[SchemeSel][ColFg] = strdup(colortemp[3]); - if ( colortemp[4]) - colors[SchemeBorder][ColFg] = strdup(colortemp[4]); + colors[SchemeSel][ColFg] = strdup(colortemp[3]); if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts))) die("no fonts could be loaded."); diff --git a/patches/dmenu-center-20250407-b1e217b.diff b/patches/dmenu-center-20250407-b1e217b.diff new file mode 100644 index 0000000..a28efdb --- /dev/null +++ b/patches/dmenu-center-20250407-b1e217b.diff @@ -0,0 +1,135 @@ +From 95a444534c230de79000348b0e12f8644aac8b15 Mon Sep 17 00:00:00 2001 +From: leliel <mail.leliel@proton.me> +Date: Mon, 7 Apr 2025 01:00:01 +0000 +Subject: [PATCH] Increased speed for long files with emojis. + +--- + config.def.h | 3 +++ + dmenu.1 | 3 +++ + dmenu.c | 40 ++++++++++++++++++++++++++++++++++------ + 3 files changed, 40 insertions(+), 6 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..832896f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,9 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int centered = 1; /* -c option; centers dmenu on screen */ ++static int min_width = 500; /* minimum width when centered */ ++static const float menu_height_ratio = 4.0f; /* This is the ratio used in the original calculation */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..c036baa 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. + .B \-b + dmenu appears at the bottom of the screen. + .TP ++.B \-c ++dmenu appears centered on the screen. ++.TP + .B \-f + dmenu grabs the keyboard before reading stdin if not reading from a tty. This + is faster, but will lock up X until stdin reaches end\-of\-file. +diff --git a/dmenu.c b/dmenu.c +index fd49549..ceb52c7 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -29,6 +29,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + + struct item { + char *text; ++ unsigned int width; + struct item *left, *right; + int out; + }; +@@ -95,6 +96,15 @@ calcoffsets(void) + break; + } + ++static int ++max_textw(void) ++{ ++ int len = 0; ++ for (struct item *item = items; item && item->text; item++) ++ len = MAX(item->width, len); ++ return len; ++} ++ + static void + cleanup(void) + { +@@ -563,6 +573,7 @@ readstdin(void) + line[len - 1] = '\0'; + if (!(items[i].text = strdup(line))) + die("strdup:"); ++ items[i].width = TEXTW(line); + + items[i].out = 0; + } +@@ -636,6 +647,7 @@ setup(void) + bh = drw->fonts->h + 2; + lines = MAX(lines, 0); + mh = (lines + 1) * bh; ++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + #ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { +@@ -662,9 +674,16 @@ setup(void) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) + break; + +- x = info[i].x_org; +- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); +- mw = info[i].width; ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); ++ x = info[i].x_org + ((info[i].width - mw) / 2); ++ y = info[i].y_org + ((info[i].height - mh) / menu_height_ratio); ++ } else { ++ x = info[i].x_org; ++ y = info[i].y_org + (topbar ? 0 : info[i].height - mh); ++ mw = info[i].width; ++ } ++ + XFree(info); + } else + #endif +@@ -672,9 +691,16 @@ setup(void) + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); +- x = 0; +- y = topbar ? 0 : wa.height - mh; +- mw = wa.width; ++ ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); ++ x = (wa.width - mw) / 2; ++ y = (wa.height - mh) / 2; ++ } else { ++ x = 0; ++ y = topbar ? 0 : wa.height - mh; ++ mw = wa.width; ++ } + } + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = mw / 3; /* input width: ~33% of monitor width */ +@@ -733,6 +759,8 @@ main(int argc, char *argv[]) + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; ++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ ++ centered = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +-- +2.49.0 + diff --git a/patches/dmenu-mousesupport-5.3.diff b/patches/dmenu-mousesupport-5.3.diff new file mode 100644 index 0000000..cf18e51 --- /dev/null +++ b/patches/dmenu-mousesupport-5.3.diff @@ -0,0 +1,145 @@ +diff --git a/dmenu.c b/dmenu.c +index 40f93e0..d194caf 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -527,6 +527,119 @@ draw: + drawmenu(); + } + ++static void ++buttonpress(XEvent *e) ++{ ++ struct item *item; ++ XButtonPressedEvent *ev = &e->xbutton; ++ int x = 0, y = 0, h = bh, w; ++ ++ if (ev->window != win) ++ return; ++ ++ /* right-click: exit */ ++ if (ev->button == Button3) ++ exit(1); ++ ++ if (prompt && *prompt) ++ x += promptw; ++ ++ /* input field */ ++ w = (lines > 0 || !matches) ? mw - x : inputw; ++ ++ /* left-click on input: clear input, ++ * NOTE: if there is no left-arrow the space for < is reserved so ++ * add that to the input width */ ++ if (ev->button == Button1 && ++ ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + ++ ((!prev || !curr->left) ? TEXTW("<") : 0)) || ++ (lines > 0 && ev->y >= y && ev->y <= y + h))) { ++ insert(NULL, -cursor); ++ drawmenu(); ++ return; ++ } ++ /* middle-mouse click: paste selection */ ++ if (ev->button == Button2) { ++ XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, ++ utf8, utf8, win, CurrentTime); ++ drawmenu(); ++ return; ++ } ++ /* scroll up */ ++ if (ev->button == Button4 && prev) { ++ sel = curr = prev; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ /* scroll down */ ++ if (ev->button == Button5 && next) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ if (ev->button != Button1) ++ return; ++ if (ev->state & ~ControlMask) ++ return; ++ if (lines > 0) { ++ /* vertical list: (ctrl)left-click on item */ ++ w = mw - x; ++ for (item = curr; item != next; item = item->right) { ++ y += h; ++ if (ev->y >= y && ev->y <= (y + h)) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ } else if (matches) { ++ /* left-click on left arrow */ ++ x += inputw; ++ w = TEXTW("<"); ++ if (prev && curr->left) { ++ if (ev->x >= x && ev->x <= x + w) { ++ sel = curr = prev; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++ /* horizontal list: (ctrl)left-click on item */ ++ for (item = curr; item != next; item = item->right) { ++ x += w; ++ w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); ++ if (ev->x >= x && ev->x <= x + w) { ++ puts(item->text); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ /* left-click on right arrow */ ++ w = TEXTW(">"); ++ x = mw - w; ++ if (next && ev->x >= x && ev->x <= x + w) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++} ++ + static void + paste(void) + { +@@ -586,6 +699,9 @@ run(void) + break; + cleanup(); + exit(1); ++ case ButtonPress: ++ buttonpress(&ev); ++ break; + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); +@@ -683,7 +799,9 @@ setup(void) + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; +- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; ++ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ++ ButtonPressMask; ++ + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); diff --git a/patches/dmenu-mousesupport-motion-5.2.diff b/patches/dmenu-mousesupport-motion-5.2.diff new file mode 100644 index 0000000..414201c --- /dev/null +++ b/patches/dmenu-mousesupport-motion-5.2.diff @@ -0,0 +1,53 @@ +diff --git a/dmenu.c b/dmenu.c +index 48d4980..7677401 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -641,6 +641,29 @@ buttonpress(XEvent *e) + } + } + ++static void ++motionevent(XButtonEvent *ev) ++{ ++ struct item *it; ++ int xy, ev_xy; ++ ++ if (ev->window != win || matches == 0) ++ return; ++ ++ xy = lines > 0 ? bh : inputw + promptw + TEXTW("<"); ++ ev_xy = lines > 0 ? ev->y : ev->x; ++ for (it = curr; it && it != next; it = it->right) { ++ int wh = lines > 0 ? bh : textw_clamp(it->text, mw - xy - TEXTW(">")); ++ if (ev_xy >= xy && ev_xy < (xy + wh)) { ++ sel = it; ++ calcoffsets(); ++ drawmenu(); ++ break; ++ } ++ xy += wh; ++ } ++} ++ + static void + paste(void) + { +@@ -702,6 +725,9 @@ run(void) + case ButtonPress: + buttonpress(&ev); + break; ++ case MotionNotify: ++ motionevent(&ev.xbutton); ++ break; + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); +@@ -800,7 +826,7 @@ setup(void) + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | +- ButtonPressMask; ++ ButtonPressMask | PointerMotionMask; + win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); diff --git a/patches/dmenu-xresources-4.9.diff b/patches/dmenu-xresources-4.9.diff new file mode 100644 index 0000000..267fb0a --- /dev/null +++ b/patches/dmenu-xresources-4.9.diff @@ -0,0 +1,126 @@ +diff '--color=auto' -up ../dmenu-4.9/dmenu.c ./dmenu.c +--- ../dmenu-4.9/dmenu.c 2019-02-02 13:55:02.000000000 +0100 ++++ ./dmenu.c 2020-05-24 00:27:58.038586112 +0200 +@@ -15,6 +15,7 @@ + #include <X11/extensions/Xinerama.h> + #endif + #include <X11/Xft/Xft.h> ++#include <X11/Xresource.h> + + #include "drw.h" + #include "util.h" +@@ -53,6 +54,10 @@ static XIC xic; + static Drw *drw; + static Clr *scheme[SchemeLast]; + ++/* Temporary arrays to allow overriding xresources values */ ++static char *colortemp[4]; ++static char *tempfonts; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +@@ -596,8 +601,13 @@ setup(void) + int a, di, n, area = 0; + #endif + /* init appearance */ +- for (j = 0; j < SchemeLast; j++) +- scheme[j] = drw_scm_create(drw, colors[j], 2); ++ for (j = 0; j < SchemeLast; j++) { ++ scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2); ++ } ++ for (j = 0; j < SchemeOut; ++j) { ++ for (i = 0; i < 2; ++i) ++ free(colors[j][i]); ++ } + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); +@@ -687,6 +697,41 @@ usage(void) + exit(1); + } + ++void ++readxresources(void) { ++ XrmInitialize(); ++ ++ char* xrm; ++ if ((xrm = XResourceManagerString(drw->dpy))) { ++ char *type; ++ XrmDatabase xdb = XrmGetStringDatabase(xrm); ++ XrmValue xval; ++ ++ if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval)) ++ fonts[0] = strdup(xval.addr); ++ else ++ fonts[0] = strdup(fonts[0]); ++ if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval)) ++ colors[SchemeNorm][ColBg] = strdup(xval.addr); ++ else ++ colors[SchemeNorm][ColBg] = strdup(colors[SchemeNorm][ColBg]); ++ if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval)) ++ colors[SchemeNorm][ColFg] = strdup(xval.addr); ++ else ++ colors[SchemeNorm][ColFg] = strdup(colors[SchemeNorm][ColFg]); ++ if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval)) ++ colors[SchemeSel][ColBg] = strdup(xval.addr); ++ else ++ colors[SchemeSel][ColBg] = strdup(colors[SchemeSel][ColBg]); ++ if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval)) ++ colors[SchemeSel][ColFg] = strdup(xval.addr); ++ else ++ colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]); ++ ++ XrmDestroyDatabase(xdb); ++ } ++} ++ + int + main(int argc, char *argv[]) + { +@@ -715,15 +760,15 @@ main(int argc, char *argv[]) + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ +- fonts[0] = argv[++i]; ++ tempfonts = argv[++i]; + else if (!strcmp(argv[i], "-nb")) /* normal background color */ +- colors[SchemeNorm][ColBg] = argv[++i]; ++ colortemp[0] = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ +- colors[SchemeNorm][ColFg] = argv[++i]; ++ colortemp[1] = argv[++i]; + else if (!strcmp(argv[i], "-sb")) /* selected background color */ +- colors[SchemeSel][ColBg] = argv[++i]; ++ colortemp[2] = argv[++i]; + else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ +- colors[SchemeSel][ColFg] = argv[++i]; ++ colortemp[3] = argv[++i]; + else if (!strcmp(argv[i], "-w")) /* embedding window id */ + embed = argv[++i]; + else +@@ -743,8 +788,23 @@ main(int argc, char *argv[]) + die("could not get embedding window attributes: 0x%lx", + parentwin); + drw = drw_create(dpy, screen, root, wa.width, wa.height); +- if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) ++ readxresources(); ++ /* Now we check whether to override xresources with commandline parameters */ ++ if ( tempfonts ) ++ fonts[0] = strdup(tempfonts); ++ if ( colortemp[0]) ++ colors[SchemeNorm][ColBg] = strdup(colortemp[0]); ++ if ( colortemp[1]) ++ colors[SchemeNorm][ColFg] = strdup(colortemp[1]); ++ if ( colortemp[2]) ++ colors[SchemeSel][ColBg] = strdup(colortemp[2]); ++ if ( colortemp[3]) ++ colors[SchemeSel][ColFg] = strdup(colortemp[3]); ++ ++ if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts))) + die("no fonts could be loaded."); ++ ++ free(fonts[0]); + lrpad = drw->fonts->h; + + #ifdef __OpenBSD__ |