c65238ee792df4c552cb0716c4717a7b2ffbc3cf
max
  Wed Jul 27 05:27:24 2022 -0700
fixing right-click problem onto highlights when the user clicks onto the left half of a bp, refs #29783

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 66ab378..c74aed6 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -375,36 +375,45 @@
 
         // We ignore clicks in the gray tab and track title column
         // (we really should suppress all drag activity there,
         // but I don't know how to do that with imgAreaSelect).
         var leftX = hgTracks.revCmplDisp ?  imgOfs.left - slop :
                                             imgOfs.left + hgTracks.insideX - slop;
         var rightX = hgTracks.revCmplDisp ? imgOfs.left + imgWidth - hgTracks.insideX + slop :
                                             imgOfs.left + imgWidth + slop;
 
         return (   (selection.event.pageX >= leftX)
                 && (selection.event.pageX < rightX)
                 && (selection.event.pageY >= (imgOfs.top - slop))
                 && (selection.event.pageY <  (imgOfs.top + imgHeight + slop)));
     },
 
-    pixelsToBases: function (img, selStart, selEnd, winStart, winEnd)
+    pixelsToBases: function (img, selStart, selEnd, winStart, winEnd, addHalfBp)
     {   // Convert image coordinates to chromosome coordinates
         var imgWidth = jQuery(img).width() - hgTracks.insideX;
         var width = hgTracks.winEnd - hgTracks.winStart;
         var mult = width / imgWidth;   // mult is bp/pixel multiplier
-        var halfBpWidth = (imgWidth / width) / 2; // how many pixels does one bp take up;
+ 
+        // where does a bp position start on the screen?
+        // For things like drag-select, if the user ends just before the nucleotide itself, do not count
+        // the nucleotide itself as selected. But for things like clicks onto
+        // a selection, if the user right-clicks just before the middle of the
+        // nucleotide, we certainly want to use this position.
+        var halfBpWidth = 0;
+        if (addHalfBp)
+            halfBpWidth = (imgWidth / width) / 2; // how many pixels does one bp take up;
+
         var startDelta;   // startDelta is how many bp's to the right/left
         var x1;
 
         // The magic number three appear at another place in the code 
         // as LEFTADD. It was originally annotated as "borders or cgi item calc
         // ?" by Larry. It has to be used when going any time when converting 
         // between pixels and coordinates.
         selStart -= 3;
         selEnd -= 3;
 
         if (hgTracks.revCmplDisp) {
             x1 = Math.min(imgWidth, selStart);
             startDelta = Math.floor(mult * (imgWidth - x1 - halfBpWidth));
         } else {
             x1 = Math.max(hgTracks.insideX, selStart);
@@ -459,37 +468,37 @@
                     // while they continue to overlap, extend
                     e = Math.min(chromEnd, w.winEnd);
                     virtEnd   = w.virtStart + (e - w.winStart);
                 } else {
                     // when they do not overlap anymore, stop
                     break;
                 }
             }
         }
         return {chromStart : virtStart, chromEnd : virtEnd};
     },
 
     selectionPixelsToBases: function (img, selection)
     {   // Convert selection x1/x2 coordinates to chromStart/chromEnd.
         return genomePos.pixelsToBases(img, selection.x1, selection.x2,
-                                        hgTracks.winStart, hgTracks.winEnd);
+                                        hgTracks.winStart, hgTracks.winEnd, true);
     },
 
     update: function (img, selection, singleClick)
     {
         var pos = genomePos.pixelsToBases(img, selection.x1, selection.x2,
-                                            hgTracks.winStart, hgTracks.winEnd);
+                                            hgTracks.winStart, hgTracks.winEnd, true);
         // singleClick is true when the mouse hasn't moved (or has only moved a small amount).
         if (singleClick) {
             var center = (pos.chromStart + pos.chromEnd)/2;
             pos.chromStart = Math.floor(center - hgTracks.newWinWidth/2);
             pos.chromEnd = pos.chromStart + hgTracks.newWinWidth;
             // clip
             if (pos.chromStart < hgTracks.chromStart)
                 pos.chromStart = hgTracks.chromStart; // usually  1
             if (pos.chromEnd > hgTracks.chromEnd)
                 pos.chromEnd = hgTracks.chromEnd; // usually virt chrom size
 
             // save current position so that that it may be restored after highlight or cancel.
             genomePos.original = genomePos.getOriginalPos();
             genomePos.originalSize = $('#size').text().replace(/,/g, ""); // strip out any commas
 
@@ -3060,31 +3069,31 @@
                     rightClick.hit(menuItemClicked, menuObject, "viewImg");
                     return true; }
             };
             menu.push(o);
 
             return menu;
         },
         {
             beforeShow: function(e) {
                 // console.log(mapItems[rightClick.selectedMenuItem]);
                 rightClick.selectedMenuItem = rightClick.findMapItem(e);
                 
                 // find the highlight that was clicked
                 var imageX = (imageV2.imgTbl[0].getBoundingClientRect().left) + imageV2.LEFTADD;
                 var xDiff = (e.clientX) - imageX;
-                var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd);
+                var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd, false);
                 rightClick.clickedHighlightIdx = dragSelect.findHighlightIdxForPos(clickPos);
 
                 // XXXX? posting.blockUseMap = true;
                 return true;
             },
             hideTransition:'hide', // hideCallback fails if these are not defined.
             hideSpeed:10,
             hideCallback: function() {
                 $('p.btn.blueButtons').removeClass('blueButtons');
                 $('tr.trDraggable.greenRows').removeClass('greenRows');
             }
         });
         return;
     }
 };