a08ccd7dd4930bff5bcf0a32bd35ec22db71215f markd Sat Aug 22 06:14:41 2026 -0700 Fix the browser.theme drop down, which has never applied a theme, and retire browser.background and browser.bgcolor from the example configs. refs #38158 themeDropDown built the menu label from the hg.conf key and posted that label back, while setThemeFromCart looks a theme up by key, so no entry carrying a sort prefix or an underscore could ever resolve. Broken since af6898753ba (2023) introduced that key format and changed the menu side without the lookup side. themeDropDown now passes the key suffix as the option value and the prettified label as the display text, using cgiMakeDropListWithVals. setThemeFromCart compared the generated link against "<>" instead of the config value, so the "no theme file" marker never fired. It also let an empty link from a missing CSS file overwrite browser.style with nothing. Both now test the right string and leave browser.style alone when there is no theme to apply. browser.background has not been read by any CGI since hBackgroundImage() and its callers were removed in 2012 (8e6fcda9f58), and browser.bgcolor has never been read at all, yet ex.hg.conf presented browser.background as a working setting. Commented both out with a note, in ex.hg.conf and the three browserbox configs. ex.hg.conf also documented two conflicting browser.theme formats in two places. The comma form stopped working in 2023. Consolidated to a single block that describes what the code actually does. diff --git src/hg/hgTracks/config.c src/hg/hgTracks/config.c index 407cddd2ae0..3320a3d5549 100644 --- src/hg/hgTracks/config.c +++ src/hg/hgTracks/config.c @@ -1,1200 +1,1212 @@ /* config - put up track and display configuration page. */ /* Copyright (C) 2014 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "dystring.h" #include "cheapcgi.h" #include "htmshell.h" #include "hdb.h" #include "hCommon.h" #include "cart.h" #include "web.h" #include "customTrack.h" #include "hgTracks.h" #include "trashDir.h" #include "hgConfig.h" #include "jsHelper.h" #include "imageV2.h" #include "search.h" #include "hubConnect.h" #include "fileUi.h" #include "trackHub.h" #include "versionInfo.h" +static void themeMenuEntry(char *cfgName, char **retLabel, char **retValue) +/* Split an hg.conf browser.theme.* key into the menu label and the option value. + * The value is everything after "browser.theme.", which is what setThemeFromCart + * looks the theme up by, so it must survive the round trip through the form + * untouched. The label is only the part after the last '.', with underscores as + * spaces, so a sort prefix like browser.theme.2.Sans_Serif shows as "Sans Serif". + * The first letter is upper cased, which the plain hDropList used to do for us. */ +{ +char *value = cloneString(cfgName + strlen("browser.theme.")); +char *label = cloneString(findTail(value, '.')); +replaceChar(label, '_', ' '); +label[0] = toupper((unsigned char)label[0]); +*retLabel = label; +*retValue = value; +} + static void themeDropDown(struct cart* cart) /* Create drop down for UI themes. - * specfied in hg.conf like this - * browser.theme.modern=background.png,HGStyle + * specified in hg.conf like this + * browser.theme.modern=theme-modern.css + * optionally with a sort prefix + * browser.theme.3.Sans_Serif=theme-modern.css * */ { struct slName* themes = cfgNamesWithPrefix("browser.theme."); if (themes==NULL) return; slNameSort(&themes); hPrintf("
| "); hPrintf(" | ||
|---|---|---|
| "); hPrintf("", hgTrackUiName(), cartSessionVarName(), cartSessionId(cart), database, chromName, RULER_TRACK_NAME); hPrintf("%s", RULER_TRACK_LABEL); hPrintf(" | "); hTvDropDownClassVisOnlyWithLabel("ruler", rulerMode, FALSE, rulerMode ? "normalText trackVis" : "hiddenText trackVis", NULL, RULER_TRACK_LABEL); hPrintf(" | "); hPrintf("Chromosome position in bases. (Clicks here zoom in 3x)"); hPrintf(" |
| "); if (tdbIsSuperTrackChild(tdb)) /* indent members of a supertrack */ hPrintf(" "); hPrintIcons(tdb); if (track->hasUi) // the labels come from trackDb, which a track hub controls, escape them hPrintf("", tdb->parent ? "Part of super track: " : "Configure ", htmlEncode(tdb->parent ? tdb->parent->shortLabel : tdb->shortLabel), hTrackUiForTrack(tdb->track), cartSessionVarName(), cartSessionId(cart), database, track->track); hPrintf(" %s", htmlEncode(tdb->shortLabel)); if (track->hasUi) hPrintf(""); hPrintf(" | "); if (tdbIsSuperTrackChild(tdb)) /* indent members of a supertrack */ hPrintf(" "); /* If track is not on this chrom print an informational message for the user. */ if (tdbIsDownloadsOnly(tdb)) // No vis display for downloadsOnly hPrintf("Downloads", hgFileUiName(),cartSessionVarName(), cartSessionId(cart), tdb->track); else if (hTrackOnChrom(track->tdb, chromName)) { if (tdbIsSuper(track->tdb)) { /* supertrack dropdown is hide/show */ superTrackDropDown(cart, track->tdb, 1); } else { /* check for option of limiting visibility to one mode */ hTvDropDownClassVisOnlyWithLabel(track->track, track->visibility, rTdbTreeCanPack(track->tdb), (track->visibility == tvHide) ? "hiddenText trackVis" : "normalText trackVis", trackDbSetting(track->tdb, "onlyVisibility"), tdb->shortLabel); } } else hPrintf("[No data-%s]", chromName); hPrintf(" | "); hPrintf("%s", htmlEncode(tdb->longLabel)); hPrintf(" |
| "); cgiDown(0.9); hPrintf(" | ||