8f5836c283e93f1e8307f65700b95e26cd994bcb
galt
  Mon Dec 14 15:54:19 2015 -0800
Earlier, the only way to turn on EM mode was via config dialog box. But with the new "e v" hotkeys, it can come in with no default emGeneTrack defined yet.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index fbff0e1..6ca5c8f 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -7199,42 +7199,42 @@
     if (emGeneTrack)
 	{
 	emGeneTable = table;
 	cartSetString(cart, "emGeneTable", emGeneTable);
 	break;
 	}
     }
 }
 
 void setEMGeneTrack()
 /* Find the track for the gene table to use for exonMostly and geneMostly. */
 {
 if (emGeneTable) // we already have it!
     return;
 emGeneTable = cloneString(cartOptionalString(cart, "emGeneTable"));
-if (!emGeneTable)
+if (emGeneTable)
     {
-    cartRemove(cart, "emGeneTable");
-    return;
-    }
     struct track *myTrackList = getTrackListForOneTrack(emGeneTable);
     emGeneTrack = rFindTrackWithTable(emGeneTable, myTrackList);
-// note that we cannot easily call findBestEMGeneTable because we do not have a complete track list early on.
-if (!emGeneTrack) 
+    }
+if (!emGeneTable || !emGeneTrack) 
     {
     cartRemove(cart, "emGeneTable");
-    return;
+    // It is preferable not to create a complete track list early on,
+    //  but now we need one to find the best default emGeneTable and track.
+    initTrackList(); 
+    findBestEMGeneTable(trackList);
     }
 }
 
 
 void doTrackForm(char *psOutput, struct tempName *ideoTn)
 /* Make the tracks display form with the zoom/scroll buttons and the active
  * image.  If the ideoTn parameter is not NULL, it is filled in if the
  * ideogram is created.  */
 {
 struct group *group;
 struct track *track;
 char *freezeName = NULL;
 boolean hideAll = cgiVarExists("hgt.hideAll");
 boolean defaultTracks = cgiVarExists("hgt.reset");
 boolean showedRuler = FALSE;
@@ -8626,57 +8626,59 @@
     {
     // In case user manually edits the browser location as described in #13009,
     // revert the position.  If they instead choose from the list as we expect,
     // that will set the position to their choice.
     char *lastPosition = cartUsualString(cart, "lastPosition", hDefaultPos(database));
     cartSetString(cart, "position", lastPosition);
     return;
     }
 
 // TODO NOTE lastPosition gets set in cart.c
 
 
 gotVirtPos:
 
 virtMode = cartUsualBoolean(cart, "virtMode", FALSE);
+//warn("virtMode=%d\n", virtMode); // DEBUG REMOVE
 
 /* Figure out basic dimensions of display.  This
  * needs to be done early for the sake of the
  * zooming and dinking routines. */
 setLayoutGlobals();
 //warn("after setLayoutGlobals() fullInsideX=%d fullInsideWidth=%d tl.picWidth=%d gfxBorder=%d\n", 
     //fullInsideX, fullInsideWidth, tl.picWidth, gfxBorder); // DEBUG REMOVE
 
 virtModeType = cartUsualString(cart, "virtModeType", virtModeType);
 //warn("virtModeType=%s\n", virtModeType); // DEBUG REMOVE
 
 if (positionIsVirt && virtualSingleChrom())
     {
     // we need chromName to be set before initRegionList() gets called.
     position = cartUsualString(cart, "nonVirtPosition", "");
     //warn("positionIsVirt && virtualSingleChrom(), going to nonVirtPosition %s", position);  // DEBUG REMOVE
     if (!sameString(position,""))
 	parseNonVirtPosition(position);
     }
 //warn("chromName=%s", chromName); // DEBUG REMOVE
 
 // TODO GALT do we need to add in other types that now depend on emGeneTable too? maybe singleTrans?
 if (sameString(virtModeType, "exonMostly") || sameString(virtModeType, "geneMostly")) 
     {
     setEMGeneTrack();
     if (!emGeneTable) // there is no available gene table, undo exonMostly or geneMostly
 	{
+	//warn("setEMGeneTrack unable to find default gene track");
 	virtModeType = "default";
 	cartSetString(cart, "virtModeType", virtModeType); 
 	}
     }
 
 lastVirtModeType = cartUsualString(cart, "lastVirtModeType", lastVirtModeType); 
 
 again:
 //warn("virtModeType=%s lastVirtModeType=%s\n", virtModeType, lastVirtModeType); // DEBUG REMOVE
 if (sameString(virtModeType, "default") && !(sameString(lastVirtModeType, "default")))
     { // RETURNING TO DEFAULT virtModeType
     virtModeType = "default";
     cartSetString(cart, "virtModeType", virtModeType); 
     findNearest = TRUE;
     if (positionIsVirt)
@@ -9472,33 +9474,33 @@
 hPrintf("Mousetrap.bind('t h', function() { document.trackHubForm.submit();return false; }); \n");
 hPrintf("Mousetrap.bind('r s', function() { $('input[name=\"hgt.setWidth\"]').click() }); \n");
 hPrintf("Mousetrap.bind('r f', function() { $('input[name=\"hgt.refresh\"]').click() }); \n");
 hPrintf("Mousetrap.bind('r v', function() { $('input[name=\"hgt.toggleRevCmplDisp\"]').click() }); \n");
 hPrintf("Mousetrap.bind('v d', gotoGetDnaPage); \n");
 
 // focus
 hPrintf("Mousetrap.bind('/', function() { $('input[name=\"hgt.positionInput\"]').focus(); return false; }, 'keydown'); \n");
 hPrintf("Mousetrap.bind('?', function() { $( \"#hotkeyHelp\" ).dialog({width:'600'});}); \n");
 
 // menu
 if (gotExtTools)
     hPrintf("Mousetrap.bind('s t', showExtToolDialog); \n");
 
 // multi-region views
-hPrintf("Mousetrap.bind('e v', function() { window.location.href='%s?%s=%s&virtModeType=exonMostly'; return false; });  \n",
+hPrintf("Mousetrap.bind('e v', function() { window.location.href='%s?%s=%s&virtModeType=exonMostly'; });  \n",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart));
-hPrintf("Mousetrap.bind('d v', function() { window.location.href='%s?%s=%s&virtModeType=default'; return false; });  \n",
+hPrintf("Mousetrap.bind('d v', function() { window.location.href='%s?%s=%s&virtModeType=default'; });  \n",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart));
 
 
 hPrintf("</script>\n");
 
 // help dialog
 hPrintf("<div style=\"display:none\" id=\"hotkeyHelp\" title=\"Keyboard shortcuts\">\n");
 hPrintf("<table style=\"width:580px; border-color:#666666; border-collapse:collapse\">\n");
 hPrintf("<tr><td style=\"width:18ch\">left 10&#37;</td><td width=\"auto\" class=\"hotkey\">ctrl+j</td>  <td style=\"width:24ch\"> track search</td><td class=\"hotkey\">t then s</td>               </tr>\n"); // percent sign
 hPrintf("<tr><td> left 1/2 screen</td><td class=\"hotkey\">j</td>   <td> default tracks</td><td class=\"hotkey\">d then t</td>             </tr>\n");
 hPrintf("<tr><td> left one screen</td><td class=\"hotkey\">J</td>   <td> default order</td><td class=\"hotkey\">d then o</td>              </tr>\n");
 hPrintf("<tr><td> right 10&#37;</td><td class=\"hotkey\">ctrl+l</td><td> hide all</td><td class=\"hotkey\">h then a</td>                   </tr>\n"); // percent sign
 hPrintf("<tr><td> right 1/2 screen</td><td class=\"hotkey\">l</td>  <td> custom tracks</td><td class=\"hotkey\">c then t</td>              </tr>\n");
 hPrintf("<tr><td> right one screen</td><td class=\"hotkey\">L</td>  <td> track hubs</td><td class=\"hotkey\">t then h</td>                 </tr>\n");
 hPrintf("<tr><td> zoom in 1.5x</td><td class=\"hotkey\">ctrl+i</td> <td> configure</td><td class=\"hotkey\">c then f</td>                  </tr>\n");