d7dd4f55e28699bb783563b8bece5bf23f392995
chmalee
  Wed May 13 11:07:57 2026 -0700
Adds hg.conf myVariantsDataDir for writing ctfiles outside trash/, per-db short/long label rename on hgTrackUi, and a shared removal helper so the hgTrackUi remove button, hgTracks trash icon, and hgCustom checkbox all function the same, refs #33808

diff --git src/hg/hgCustom/hgCustom.c src/hg/hgCustom/hgCustom.c
index 4fdef74fa99..17a20d0acd8 100644
--- src/hg/hgCustom/hgCustom.c
+++ src/hg/hgCustom/hgCustom.c
@@ -1070,50 +1070,35 @@
     dyStringAppend(dsWarn, ct->tdb->shortLabel);
     }
 return dyStringCannibalize(&dsWarn);
 }
 
 void doDeleteCustom()
 /* remove custom tracks from list based on cart variables */
 {
 struct customTrack *ct;
 for (ct = ctList; ct != NULL; ct = ct->next)
     {
     char var[256];
     safef(var, sizeof var, "%s_%s", hgCtDeletePrefix, ct->tdb->track);
     if (!cartUsualBoolean(cart, var, FALSE))
         continue;
-    /* myVariants tracks are backed by a per-user SQL table, not the CT file,
-     * so just dropping them from ctList isn't enough -- the next page load
-     * regenerates the CT entry from the database.  Delete the underlying
-     * data (own track) or revoke the accepted share (shared track) so the
-     * removal sticks. */
-    char *trackName = ct->tdb->track;
-    if (startsWith("myVariants_shared_", trackName))
-        {
-        char *token = trackName + strlen("myVariants_shared_");
-        char shareCartVar[256];
-        safef(shareCartVar, sizeof shareCartVar,
-            MYVAR_SHARED_CART_PREFIX "%s", token);
-        cartRemove(cart, shareCartVar);
-        }
-    else if (startsWith("myVariants_", trackName))
-        {
-        char *userName = wikiLinkUserName();
-        if (isNotEmpty(userName))
-            myVariantsDeleteForDb(userName, database);
-        }
+    /* myVariants tracks are backed by a per-user SQL table, not the CT
+     * file, so dropping them from ctList alone isn't enough -- the next
+     * page load regenerates the CT entry from the database.  Delegate
+     * the type-specific cleanup. */
+    myVariantsHandleCtRemoval(ct, cart, database);
     slRemoveEl(&ctList, ct);
     }
 }
 
 void doRefreshCustom(char **warnMsg)
 /* reparse custom tracks from URLs based on cart variables */
 {
 struct customTrack *ct;
 struct customTrack *replacedCts = NULL;
 struct customTrack *refreshCts = NULL;
 
 for (ct = ctList; ct != NULL; ct = ct->next)
     {
     char var[256];
     safef(var, sizeof var, "%s_%s", hgCtRefreshPrefix, ct->tdb->track);