96a903979dbe723e4f20a700dfc12881063b2c46
max
  Tue Sep 8 00:26:18 2026 -0700
hgTracks: support mouseOver on bigNarrowPeak tracks, and register the peak filter tags

bigNarrowPeakLoadItems() had its own load loop and never looked at the
mouseOver setting, so a bigNarrowPeak track silently ignored it. It now uses
the mouseOverSetupForBbi() / mouseOverGetBbiText() helpers in mouseOver.c, which
also gets mouseOverField support for free. As with every other bigBed-like
track, the text only shows in pack or full, since dense makes no per-item map
boxes.

tagTypes.tab did not list bigNarrowPeak for mouseOver, scoreFilter,
scoreFilterLimits, scoreMin, scoreMax, signalFilter or signalFilterLimits, so
tdbQuery -strict rejected all of them even though the code reads them.
pValueFilter and qValueFilter, with their Limits, were not registered for any
type at all, although encodePeakCfgUi() in hui.c has always drawn them and
bigNarrowPeakLoadItems() has always applied them. Added.

refs #36210

diff --git src/hg/hgTracks/encode.c src/hg/hgTracks/encode.c
index a35c45573f4..9e6c81997ef 100644
--- src/hg/hgTracks/encode.c
+++ src/hg/hgTracks/encode.c
@@ -1,30 +1,31 @@
 /* encode.c - hgTracks routines that are specific to the ENCODE project */
 
 /* Copyright (C) 2012 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #include "common.h"
 #include "hCommon.h"
 #include "hdb.h"
 #include "hui.h"
 #include "hgTracks.h"
 #include "customTrack.h"
 #include "encode.h"
 #include "encode/encodeRna.h"
 #include "encode/encodePeak.h"
 #include "bigBedFilter.h"
+#include "mouseOver.h"
 #include "quickLift.h"
 
 extern struct trackLayout tl;
 
 
 char *encodeErgeName(struct track *tg, void *item)
 /* return the actual data name, in form xx/yyyy cut off xx/ return yyyy */
 {
 char *name;
 struct linkedFeatures *lf = item;
 name = strstr(lf->name, "/");
 if (name != NULL)
     name ++;
 if (name != NULL)
     return name;
@@ -193,41 +194,50 @@
 char startBuf[16], endBuf[16];
 struct bigBedFilter *filters = NULL;
 struct bigBedFilter *filter;
 
 if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SCORE_FILTER, "0:1000", "score", FALSE)) != NULL)
     slAddHead(&filters, filter);
 if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SIGNAL_FILTER, NULL, "signalValue", FALSE)) != NULL)
     slAddHead(&filters, filter);
 if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, PVALUE_FILTER, NULL, "pValue", FALSE)) != NULL)
     slAddHead(&filters, filter);
 if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, QVALUE_FILTER, NULL, "qValue", FALSE)) != NULL)
     slAddHead(&filters, filter);
 if (compositeChildHideEmptySubtracks(cart, tg->tdb, NULL, NULL))
    labelTrackAsFiltered(tg);
 
+// Support the mouseOver and mouseOverField settings, the way the bigBed-like
+// tracks do.  Both forms are handled by mouseOverSetupForBbi(), which returns a
+// scheme with nothing set when neither setting is present.
+struct mouseOverScheme *mouseScheme = mouseOverSetupForBbi(tg->tdb, bbi);
+
 unsigned filtered = 0;
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow));
     if (bigBedFilterInterval(bbi, bedRow, filters))
         {
         struct encodePeak *peak = encodePeakGeneralLoad(bedRow, pt);
         struct linkedFeatures *lf = lfFromEncodePeak((struct slList *)peak, tg->tdb, scoreMin, scoreMax);
 
         if (lf)
+            {
+            if (mouseScheme->mouseOverIdx > 0 || mouseScheme->mouseOverPattern)
+                lf->mouseOver = mouseOverGetBbiText(mouseScheme, bb, chromName);
             slAddHead(&lfList, lf);
+            }
         else
             filtered++;
         }
     else
         filtered++;
     }
 if (filtered)
    labelTrackAsFilteredNumber(tg, filtered);
 
 slReverse(&lfList);
 slSort(&lfList, linkedFeaturesCmp);
 tg->items = lfList;
 }
 
 static void encodePeakLoadItemsBoth(struct track *tg, struct customTrack *ct)