inputw: improve correctness and startup performance
a massive amount of time inside readstdin() is spent trying to get the max input width and then put it into inputw, only for it to get clamped down to mw/3 inside setup(). it makes more sense to calculate inputw inside setup() once we have mw available. similar to the last patch, i see noticeable startup performance improvement: before -> after 160ms -> 60ms additionally this will take fallback fonts into account compared to the previous version, so it's not only more performant but also more correct.
This commit is contained in:
		
							
								
								
									
										19
									
								
								dmenu.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								dmenu.c
									
									
									
									
									
								
							@ -547,8 +547,7 @@ static void
 | 
				
			|||||||
readstdin(void)
 | 
					readstdin(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[sizeof text], *p;
 | 
						char buf[sizeof text], *p;
 | 
				
			||||||
	size_t i, imax = 0, size = 0;
 | 
						size_t i, size = 0;
 | 
				
			||||||
	unsigned int tmpmax = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* read each line from stdin and add it to the item list */
 | 
						/* read each line from stdin and add it to the item list */
 | 
				
			||||||
	for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
 | 
						for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
 | 
				
			||||||
@ -560,15 +559,9 @@ readstdin(void)
 | 
				
			|||||||
		if (!(items[i].text = strdup(buf)))
 | 
							if (!(items[i].text = strdup(buf)))
 | 
				
			||||||
			die("cannot strdup %u bytes:", strlen(buf) + 1);
 | 
								die("cannot strdup %u bytes:", strlen(buf) + 1);
 | 
				
			||||||
		items[i].out = 0;
 | 
							items[i].out = 0;
 | 
				
			||||||
		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
 | 
					 | 
				
			||||||
		if (tmpmax > inputw) {
 | 
					 | 
				
			||||||
			inputw = tmpmax;
 | 
					 | 
				
			||||||
			imax = i;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (items)
 | 
						if (items)
 | 
				
			||||||
		items[i].text = NULL;
 | 
							items[i].text = NULL;
 | 
				
			||||||
	inputw = items ? TEXTW(items[imax].text) : 0;
 | 
					 | 
				
			||||||
	lines = MIN(lines, i);
 | 
						lines = MIN(lines, i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -614,12 +607,13 @@ static void
 | 
				
			|||||||
setup(void)
 | 
					setup(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int x, y, i, j;
 | 
						int x, y, i, j;
 | 
				
			||||||
	unsigned int du;
 | 
						unsigned int du, tmp;
 | 
				
			||||||
	XSetWindowAttributes swa;
 | 
						XSetWindowAttributes swa;
 | 
				
			||||||
	XIM xim;
 | 
						XIM xim;
 | 
				
			||||||
	Window w, dw, *dws;
 | 
						Window w, dw, *dws;
 | 
				
			||||||
	XWindowAttributes wa;
 | 
						XWindowAttributes wa;
 | 
				
			||||||
	XClassHint ch = {"dmenu", "dmenu"};
 | 
						XClassHint ch = {"dmenu", "dmenu"};
 | 
				
			||||||
 | 
						struct item *item;
 | 
				
			||||||
#ifdef XINERAMA
 | 
					#ifdef XINERAMA
 | 
				
			||||||
	XineramaScreenInfo *info;
 | 
						XineramaScreenInfo *info;
 | 
				
			||||||
	Window pw;
 | 
						Window pw;
 | 
				
			||||||
@ -677,7 +671,12 @@ setup(void)
 | 
				
			|||||||
		mw = wa.width;
 | 
							mw = wa.width;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
 | 
						promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
 | 
				
			||||||
	inputw = MIN(inputw, mw/3);
 | 
						for (item = items; item && item->text; ++item) {
 | 
				
			||||||
 | 
							if ((tmp = textw_clamp(item->text, mw/3)) > inputw) {
 | 
				
			||||||
 | 
								if ((inputw = tmp) == mw/3)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	match();
 | 
						match();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* create menu window */
 | 
						/* create menu window */
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user