d0d3ac9414a163b759edf2b028a4b50f4057dbc3
braney
  Fri Jun 12 09:02:21 2026 -0700
hgTracks quickLift: use trash-can icon for per-track remove

QA asked for the per-track remove control in a QuickLift group to match the
trash-can icon already used to delete custom tracks, instead of the red 'x',
so the two behave consistently. Factor the trash-can SVG into a shared
printTrashIcon() helper used by both the custom-track delete and the
quickLift remove, and drop the red tint so the quickLift icon matches.

refs #37535

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index c861e4c7ebc..231a4c3912a 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -8743,52 +8743,65 @@
 }
 
 static void printMultiRegionButton()
 /* Print button that launches multi-region configuration pop-up */
 {
 boolean isPressed = FALSE;
 if (differentString(virtModeType, "default"))
     isPressed = TRUE;
 char buf[256];
 safef(buf, sizeof buf, "Configure %s multi-region display mode", 
                         isPressed ? "or exit" : "");
 hButtonNoSubmitMaybePressed("hgTracksConfigMultiRegionPage", "Multi-region", buf,
             "popUpHgt.hgTracks('multi-region config'); return false;", isPressed);
 }
 
+static void printTrashIcon(char *title, char *cssClass, char *dataAttrs)
+/* Print a trash-can icon as a clickable <div>.  title is the hover text,
+ * cssClass selects the click behavior/styling, and dataAttrs holds any
+ * preformatted data-* attributes that the click handler reads.
+ * Github uses SVG elements for all icons, apparently that is faster.
+ * We probably should have a library with all the icons, at least for the <svg> part. */
+{
+hPrintf("<div title='%s' %s class='%s'>"
+        "<svg xmlns='http://www.w3.org/2000/svg' height='0.8em' viewBox='0 0 448 512'>"
+        "<!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License "
+        "- https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->"
+        "<path d='M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 "
+        "0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 "
+        "35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 "
+        "16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 "
+        "16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 "
+        "16-16V208c0-8.8-7.2-16-16-16z'/></svg></div>",
+        title, dataAttrs, cssClass);
+}
+
 static void printTrackDelIcon(struct track *track)
-/* little track icon after track name. Github uses SVG elements for all icons, apparently that is faster */
-/* we probably should have a library with all the icons, at least for the <svg> part */
+/* Trash-can icon after a custom track's name; clicking it deletes the track. */
 {
-    hPrintf("<div title='Delete this custom track' data-track='%s' class='trackDeleteIcon'><svg xmlns='http://www.w3.org/2000/svg' height='0.8em' viewBox='0 0 448 512'><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d='M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16z'/></svg></div>", track->track);
-
+char dataAttrs[512];
+safef(dataAttrs, sizeof dataAttrs, "data-track='%s'", track->track);
+printTrashIcon("Delete this custom track", "trackDeleteIcon", dataAttrs);
 }
 
 static void printQuickLiftDelIcon(struct track *track, char *sourceDb)
-/* little 'x' icon next to a track in a quickLift group; clicking it removes
+/* Trash-can icon next to a track in a quickLift group; clicking it removes
  * the track from the quickLift hub. */
 {
-    hPrintf("<div title='Remove this track from the QuickLift group' "
-            "data-track='%s' data-sourcedb='%s' class='quickLiftDelIcon'>"
-            "<svg xmlns='http://www.w3.org/2000/svg' height='0.8em' viewBox='0 0 384 512'>"
-            "<!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License "
-            "- https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->"
-            "<path d='M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 "
-            "86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4"
-            "c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 "
-            "32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z'/></svg></div>",
-            track->track, sourceDb);
+char dataAttrs[1024];
+safef(dataAttrs, sizeof dataAttrs, "data-track='%s' data-sourcedb='%s'", track->track, sourceDb);
+printTrashIcon("Remove this track from the QuickLift group", "quickLiftDelIcon", dataAttrs);
 }
 
 static void printTrackLink(struct track *track)
 /* print a link hgTrackUi with shortLabel and various icons and mouseOvers */
 {
 if (sameOk(track->groupName, "user"))
     printTrackDelIcon(track);
 
 char *quickLiftSourceDb = (track->tdb != NULL) ?
         trackDbSetting(track->tdb, "quickLiftDb") : NULL;
 /* skip the synthetic "Alignment Differences" track -- it's added at runtime
  * by hubConnect, not from the hub file, so removing it from the file is a
  * no-op and it would reappear on the next page load. */
 if (quickLiftSourceDb != NULL &&
     (track->tdb->type == NULL || !startsWith("bigQuickLiftChain", track->tdb->type)))