dmenu-center-20250407-b1e217b.diff (4000B)
1 From 95a444534c230de79000348b0e12f8644aac8b15 Mon Sep 17 00:00:00 2001 2 From: leliel <mail.leliel@proton.me> 3 Date: Mon, 7 Apr 2025 01:00:01 +0000 4 Subject: [PATCH] Increased speed for long files with emojis. 5 6 --- 7 config.def.h | 3 +++ 8 dmenu.1 | 3 +++ 9 dmenu.c | 40 ++++++++++++++++++++++++++++++++++------ 10 3 files changed, 40 insertions(+), 6 deletions(-) 11 12 diff --git a/config.def.h b/config.def.h 13 index 1edb647..832896f 100644 14 --- a/config.def.h 15 +++ b/config.def.h 16 @@ -2,6 +2,9 @@ 17 /* Default settings; can be overriden by command line. */ 18 19 static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ 20 +static int centered = 1; /* -c option; centers dmenu on screen */ 21 +static int min_width = 500; /* minimum width when centered */ 22 +static const float menu_height_ratio = 4.0f; /* This is the ratio used in the original calculation */ 23 /* -fn option overrides fonts[0]; default X11 font or font set */ 24 static const char *fonts[] = { 25 "monospace:size=10" 26 diff --git a/dmenu.1 b/dmenu.1 27 index 323f93c..c036baa 100644 28 --- a/dmenu.1 29 +++ b/dmenu.1 30 @@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. 31 .B \-b 32 dmenu appears at the bottom of the screen. 33 .TP 34 +.B \-c 35 +dmenu appears centered on the screen. 36 +.TP 37 .B \-f 38 dmenu grabs the keyboard before reading stdin if not reading from a tty. This 39 is faster, but will lock up X until stdin reaches end\-of\-file. 40 diff --git a/dmenu.c b/dmenu.c 41 index fd49549..ceb52c7 100644 42 --- a/dmenu.c 43 +++ b/dmenu.c 44 @@ -29,6 +29,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ 45 46 struct item { 47 char *text; 48 + unsigned int width; 49 struct item *left, *right; 50 int out; 51 }; 52 @@ -95,6 +96,15 @@ calcoffsets(void) 53 break; 54 } 55 56 +static int 57 +max_textw(void) 58 +{ 59 + int len = 0; 60 + for (struct item *item = items; item && item->text; item++) 61 + len = MAX(item->width, len); 62 + return len; 63 +} 64 + 65 static void 66 cleanup(void) 67 { 68 @@ -563,6 +573,7 @@ readstdin(void) 69 line[len - 1] = '\0'; 70 if (!(items[i].text = strdup(line))) 71 die("strdup:"); 72 + items[i].width = TEXTW(line); 73 74 items[i].out = 0; 75 } 76 @@ -636,6 +647,7 @@ setup(void) 77 bh = drw->fonts->h + 2; 78 lines = MAX(lines, 0); 79 mh = (lines + 1) * bh; 80 + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; 81 #ifdef XINERAMA 82 i = 0; 83 if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { 84 @@ -662,9 +674,16 @@ setup(void) 85 if (INTERSECT(x, y, 1, 1, info[i]) != 0) 86 break; 87 88 - x = info[i].x_org; 89 - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); 90 - mw = info[i].width; 91 + if (centered) { 92 + mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); 93 + x = info[i].x_org + ((info[i].width - mw) / 2); 94 + y = info[i].y_org + ((info[i].height - mh) / menu_height_ratio); 95 + } else { 96 + x = info[i].x_org; 97 + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); 98 + mw = info[i].width; 99 + } 100 + 101 XFree(info); 102 } else 103 #endif 104 @@ -672,9 +691,16 @@ setup(void) 105 if (!XGetWindowAttributes(dpy, parentwin, &wa)) 106 die("could not get embedding window attributes: 0x%lx", 107 parentwin); 108 - x = 0; 109 - y = topbar ? 0 : wa.height - mh; 110 - mw = wa.width; 111 + 112 + if (centered) { 113 + mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); 114 + x = (wa.width - mw) / 2; 115 + y = (wa.height - mh) / 2; 116 + } else { 117 + x = 0; 118 + y = topbar ? 0 : wa.height - mh; 119 + mw = wa.width; 120 + } 121 } 122 promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; 123 inputw = mw / 3; /* input width: ~33% of monitor width */ 124 @@ -733,6 +759,8 @@ main(int argc, char *argv[]) 125 topbar = 0; 126 else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ 127 fast = 1; 128 + else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ 129 + centered = 1; 130 else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ 131 fstrncmp = strncasecmp; 132 fstrstr = cistrstr; 133 -- 134 2.49.0 135