0edefc9983679d6bbee96ccc100f7d41921def00
braney
  Wed May 28 12:25:49 2025 -0700
working on track visibilities after quickLift

diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index 49a4758b099..d5f10976ee6 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -1543,128 +1543,140 @@
 
 if (!inited)
     {
     vettedHash = newHash(10);
 
     int ii;
     int len = sizeof(vettedTracks) / sizeof(char *);
 
     for(ii = 0; ii < len; ii++)
         hashStore(vettedHash, vettedTracks[ii]);
     }
 
 return hashLookup(vettedHash, track) != NULL;
 }
 
-static void dumpTdbAndChildren(struct dyString *dy, struct trackDb *tdb)
-/* Put a trackDb entry into a dyString, stepping up the tree for some variables. */
-{
-struct hashCookie cookie = hashFirst(tdb->settingsHash);
-struct hashEl *hel;
-while ((hel = hashNext(&cookie)) != NULL)
-    {   
-    if (differentString(hel->name, "track"))
+static bool isParentVisible(struct cart *cart, struct trackDb *tdb)
+// Are this track's parents visible?
 {
-        if (sameString(hel->name, "parent") || sameString(hel->name, "html"))
-            dyStringPrintf(dy, "%s %s\n", hel->name, trackHubSkipHubName((char *)hel->val));
+if (tdb->parent == NULL)
+    return TRUE;
+        
+if (!isParentVisible(cart, tdb->parent))
+    return FALSE;
+        
+char *cartVis = cartOptionalString(cart, tdb->parent->track);
+boolean vis;
+if (cartVis != NULL)
+    vis =  differentString(cartVis, "hide");
+else if (tdbIsSuperTrack(tdb->parent))
+    vis = tdb->parent->isShow;
 else
-            dyStringPrintf(dy, "%s %s\n", hel->name, ((char *)hel->val));
-        }
-    }
+    vis = tdb->parent->visibility != tvHide;
 
-if (tdb->subtracks)
-    {
-    for (tdb = tdb->subtracks; tdb; tdb = tdb->next)
-        {
-        char *track =  trackHubSkipHubName(tdb->track);
-        dyStringPrintf(dy, "\ntrack %s\nquickLifted on\n", track);
-        if (!isVetted(track))
-            dyStringPrintf(dy, "avoidHandler on\n");
-        dumpTdbAndChildren(dy, tdb);
-        }
-    }
+return vis;
 }
 
 static bool subtrackEnabledInTdb(struct trackDb *subTdb)
 /* Return TRUE unless the subtrack was declared with "subTrack ... off". */
 {
 bool enabled = TRUE;
 char *words[2];
 char *setting;
 if ((setting = trackDbLocalSetting(subTdb, "parent")) != NULL)
     {
     if (chopLine(cloneString(setting), words) >= 2)
         if (sameString(words[1], "off"))
             enabled = FALSE;
     }
 else
     return subTdb->visibility != tvHide;
 
 return enabled;
 }
-
 static bool isSubtrackVisible(struct cart *cart, struct trackDb *tdb)
 /* Has this subtrack not been deselected in hgTrackUi or declared with
  *  * "subTrack ... off"?  -- assumes composite track is visible. */
 {
 boolean overrideComposite = (NULL != cartOptionalString(cart, tdb->track));
 bool enabledInTdb = subtrackEnabledInTdb(tdb);
 char option[1024];
 safef(option, sizeof(option), "%s_sel", tdb->track);
 boolean enabled = cartUsualBoolean(cart, option, enabledInTdb);
 if (overrideComposite)
     enabled = TRUE;
 return enabled;
 }       
             
         
-static bool isParentVisible(struct cart *cart, struct trackDb *tdb)
-// Are this track's parents visible?
+static void dumpTdbAndChildren(struct cart *cart, struct dyString *dy, struct trackDb *tdb)
+/* Put a trackDb entry into a dyString, stepping up the tree for some variables. */
 {
-if (tdb->parent == NULL)
-    return TRUE;
-        
-if (!isParentVisible(cart, tdb->parent))
-    return FALSE;
+struct hashCookie cookie = hashFirst(tdb->settingsHash);
+struct hashEl *hel;
+dyStringPrintf(dy, "visibility %s\n", hStringFromTv(tdb->visibility));
+while ((hel = hashNext(&cookie)) != NULL)
+    {   
+    if (differentString(hel->name, "track") && differentString(hel->name, "visibility"))
+        {
+        if (sameString(hel->name, "parent") )
+            dyStringPrintf(dy, "parent %s on\n", tdb->parent->track);
+        else if (sameString(hel->name, "html"))
+            dyStringPrintf(dy, "%s %s\n", hel->name, trackHubSkipHubName((char *)hel->val));
+        else
+            dyStringPrintf(dy, "%s %s\n", hel->name, ((char *)hel->val));
+        }
+    }
 
+if (tdb->subtracks)
+    {
+    for (tdb = tdb->subtracks; tdb; tdb = tdb->next)
+        {
+        char *track =  trackHubSkipHubName(tdb->track);
+        dyStringPrintf(dy, "\ntrack %s\nquickLifted on\n", track);
+        if (!isVetted(track))
+            dyStringPrintf(dy, "avoidHandler on\n");
+        if (isParentVisible(cart, tdb) &&  isSubtrackVisible(cart, tdb)) // child of supertrack
+            {
             char *cartVis = cartOptionalString(cart, tdb->parent->track);
-boolean vis;
             if (cartVis != NULL)
-    vis =  differentString(cartVis, "hide");
-else if (tdbIsSuperTrack(tdb->parent))
-    vis = tdb->parent->isShow;
-else
-    vis = tdb->parent->visibility != tvHide;
-
-return vis;
+                tdb->visibility = hTvFromString(cartVis);
+            //else if (tdbIsSuperTrack(tdb->parent))
+             //   tdb->visibility = tdb->parent->isShow;
+            }
+        dumpTdbAndChildren(cart, dy, tdb);
         }
+    }
+}
+
+
 
-struct dyString *trackDbString(struct trackDb *tdb)
+struct dyString *trackDbString(struct cart *cart, struct trackDb *tdb)
 /* Convert a trackDb entry into a dyString. */
 {
 struct dyString *dy;
 
 // add a note that the name based handler shouldn't be used on this track
 // add a note that this is a quickLifted track so the browser will accept tracks that aren't big*
 dy = dyStringNew(200);
 char *track =  trackHubSkipHubName(tdb->track);
 dyStringPrintf(dy, "track %s\nquickLifted on\n", track);
 
 if (!isVetted(track))
     dyStringPrintf(dy, "avoidHandler on\n");
     
-dumpTdbAndChildren(dy, tdb);
+dumpTdbAndChildren(cart, dy, tdb);
 
 return dy;
 }
 
 static boolean validateOneTdb(char *db, struct trackDb *tdb, struct trackDb **badList)
 /* Make sure the tdb is a track type we grok. */
 {
 if (!( startsWith("bigBed", tdb->type) || \
        startsWith("bigWig", tdb->type) || \
        startsWith("bigDbSnp", tdb->type) || \
        startsWith("bigGenePred", tdb->type) || \
        startsWith("gvf", tdb->type) || \
        startsWith("genePred", tdb->type) || \
        startsWith("narrowPeak", tdb->type) || \
        startsWith("bigLolly", tdb->type) || \
@@ -1788,31 +1800,31 @@
             hashRemove(tdb->settingsHash, "group");
             hashRemove(tdb->settingsHash, "parent");
             }
 
         //hashReplace(tdb->settingsHash, "customized", "on");
 
         // is this a custom track?
         char *tdbType = trackDbSetting(tdb, "tdbType");
         if (tdbType != NULL)
             {
             hashReplace(tdb->settingsHash, "type", tdbType);
             hashReplace(tdb->settingsHash, "shortLabel", trackDbSetting(tdb, "name"));
             hashReplace(tdb->settingsHash, "longLabel", trackDbSetting(tdb, "description"));
             }
 
-        struct dyString *dy = trackDbString(tdb);
+        struct dyString *dy = trackDbString(cart, tdb);
 
         fprintf(f, "%s\n", dy->string);
         }
     }
 }
 
 char *trackHubBuild(char *db, struct cart *cart, struct dyString *visDy, struct trackDb **badList)
 /* Build a track hub using trackDb and the cart. */
 {
 struct  trackDb *tdbList;
 struct grp *grpList;
 cartTrackDbInit(cart, &tdbList, &grpList, FALSE);
 
 char *filename = getHubName(cart, db);