diff --git a/Menu.C b/Menu.C index e89aeb7..0f6e8cf 100644 --- a/Menu.C +++ b/Menu.C @@ -307,13 +307,11 @@ init(Fl_Menu_Item& m, const char* data) #if WMX_MENU_ITEMS -// wmxlist is an array of char* pointers (for efficient sorting purposes), -// which are stored in wmxbuffer (for memory efficiency and to avoid -// freeing and fragmentation) -static char** wmxlist = NULL; -static int wmxlistsize = 0; // wmx commands are read from ~/.wmx, -// they are stored null-separated here: +// and stored null-separated here by scan_wmx_dir: +// The strings are kept in this single buffer for memory efficiency and +// to avoid freeing and fragmentation as the scan is done many times: +// Each string has a leading character for the nesting level. static char* wmxbuffer = NULL; static int wmxbufsize = 0; static int num_wmx = 0; @@ -334,22 +332,30 @@ scan_wmx_dir (char *path, int bufindex, int nest) strcpy(path+pathlen, ent->d_name); if (stat(path, &st) < 0) continue; int len = pathlen+strlen(ent->d_name); - // worst-case alloc needs - if (bufindex+len+nest+1 > wmxbufsize) - wmxbuffer = (char*)realloc(wmxbuffer, (wmxbufsize+=1024)); - for (int i=0; i wmxbufsize) { // worst-case alloc needs + wmxbufsize = wmxbufsize ? 2*wmxbufsize : 1024; + wmxbuffer = (char*)realloc(wmxbuffer, wmxbufsize); + } + int start = bufindex; // remember where it started so we can delete it + wmxbuffer[bufindex++] = nest; // remember nesting level + strcpy(wmxbuffer+bufindex, path); + bufindex += len+1; + num_wmx++; + if (S_ISDIR(st.st_mode) && (st.st_mode & 0555) && nestnextlev; level--) init(menu[++n], 0); } else if (nextlev > level) { @@ -629,8 +636,6 @@ ShowTabMenu(int tab) pathlen[++level] = strlen(cmd)+1; // extra for next trailing / menu[n].flags = FL_SUBMENU; menu[n].callback((Fl_Callback*)0); - } else { - menu[n].callback(spawn_cb, cmd); } n++; }