439ef9d391753cc4b83f9719ae1ccfed6e439f72
max
  Sat Apr 15 09:44:15 2017 -0700
two drag-select bugfixes: escape-during-drag did not reset the mouse cursor. Also fixing right-clicks being shifted three pixels towards the left, refs #19214 and refs #19118

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index c8f3b13..85b984f 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -1244,37 +1244,37 @@
         });
         $(dragSelectDialog).dialog('open');
         
         // put the cursor into the input field
         // we are not doing this for now - default behavior was to zoom when enter was pressed
         // so people may still expect that "enter" on the dialog will zoom.
         //var el = $("#hlColorInput")[0];
         //el.selectionStart = 0;
         //el.selectionEnd = el.value.length;
         //el.focus();
 
     },
 
     selectEnd: function (img, selection, event)
     {
-        if (dragSelect.escPressed)
-            return false;
         var now = new Date();
         var doIt = false;
         var rulerClicked = selection.y1 <= hgTracks.rulerClickHeight; // = drag on base position track (no shift)
         if (dragSelect.originalCursor)
             jQuery('body').css('cursor', dragSelect.originalCursor);
+        if (dragSelect.escPressed)
+            return false;
         // ignore releases outside of the image rectangle (allowing a 10 pixel slop)
         if (genomePos.check(img, selection)) {
             // ignore single clicks that aren't in the top of the image
             // (this happens b/c the clickClipHeight test in dragSelect.selectStart
             // doesn't occur when the user single clicks).
             doIt = (dragSelect.startTime !== null || rulerClicked);
         }
 
         if (doIt) {
             // dragSelect.startTime is null if mouse has never been moved
             var singleClick = (  (selection.x2 === selection.x1)
                               || dragSelect.startTime === null
                               || (now.getTime() - dragSelect.startTime) < 100);
             var newPosition = genomePos.update(img, selection, singleClick);
             if (newPosition) {
@@ -3190,32 +3190,34 @@
             // Add view image at end
             o = {};
             o[rightClick.makeImgTag("eye.png") + " View image"] = {
                 onclick: function(menuItemClicked, menuObject) {
                     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);
-                // some right-click functions need to know the clicked chrom position
-                var xDiff = e.clientX - imageV2.imgTbl[0].getBoundingClientRect().left; // current position - position of table
+                
+                // 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);
                 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;
     }
@@ -3762,30 +3764,33 @@
 };
 
   ///////////////////////////////
  //// imageV2  (aka imgTbl) ////
 ///////////////////////////////
 var imageV2 = {
 
     enabled:        false,  // Will be set to true unless advancedJavascriptFeatures
                             // is turned off OR if track search of config page
     imgTbl:         null,   // formerly "trackImgTbl"  The imgTbl or null if non-imageV2.
     inPlaceUpdate:  false,  // modified based on value of hgTracks.inPlaceUpdate & mapIsUpdateable
     mapIsUpdateable:true,
     lastTrack:      null,   // formerly (lastMapItem) this is used to try to keep what the
                             // last track the cursor passed.
 
+    LEFTADD: 3,             // when going from pixels to chrom coords, these 3 pixels
+                            // are somehow used for "borders or cgi item calc ?" (original comment)
+
     markAsDirtyPage: function ()
     {   // Page is marked as dirty so that the back-button knows page doesn't match cart
         var dirty = normed($('#dirty'));
         if (dirty)
             $(dirty).val('true');
     },
 
     markAsCleanPage: function ()
     {   // Clears signal that history may be out of sync with cart.
         var dirty = normed($('#dirty'));
         if (dirty)
             $(dirty).val('false');
     },
 
     isDirtyPage: function ()
@@ -4389,31 +4394,31 @@
             for (var i = 0; i < hlArray.length; i++) {
                 hlString = hlArray[i];
                 pos = parsePositionWithDb(hlString);
                 // UN-DISGUISE
                 imageV2.undisguiseHighlight(pos);
                 if (pos) {
                     pos.start--;  // make start 0-based to match hgTracks.winStart
                     if (pos.color)
                         hexColor = pos.color;
                 }
 
                 if (pos && pos.chrom === hgTracks.chromName && pos.db === getDb() 
                 &&  pos.start <= hgTracks.imgBoxPortalEnd && pos.end >= hgTracks.imgBoxPortalStart) {
                     var portalWidthBases = hgTracks.imgBoxPortalEnd - hgTracks.imgBoxPortalStart;
                     var portal = $('#imgTbl td.tdData')[0];
-                    var leftPixels = $(portal).offset().left + 3; // 3 for borders and cgi item calcs ??
+                    var leftPixels = $(portal).offset().left + imageV2.LEFTADD;
                     var pixelsPerBase = ($(portal).width() - 2) / portalWidthBases;
                     var clippedStartBases = Math.max(pos.start, hgTracks.imgBoxPortalStart);
                     var clippedEndBases = Math.min(pos.end, hgTracks.imgBoxPortalEnd);
                     var widthPixels = (clippedEndBases - clippedStartBases) * pixelsPerBase;
                     if (hgTracks.revCmplDisp)
                         leftPixels += (hgTracks.imgBoxPortalEnd - clippedEndBases) * pixelsPerBase - 1;
                     else
                         leftPixels += (clippedStartBases - hgTracks.imgBoxPortalStart) * pixelsPerBase;
                     // Impossible to get perfect... Okay to overrun by a pixel on each side
                     leftPixels  = Math.floor(leftPixels);
                     widthPixels = Math.ceil(widthPixels);
                     if (widthPixels < 2) {
                         widthPixels = 3;
                         leftPixels -= 1;
                     }