diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 10bd3cbb9127929bfb630a5e095f667d98835064..99af16110289c47d38327994d0a095fc91b0e80f 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -110,9 +110,9 @@ void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
 unsigned long getVramSize(GLViewRef view);
 float getDeviceUnitSize(GLViewRef view);
-const CGPoint getContentViewBoundsPosition(NSWindowRef window);
-const CGSize getContentViewBoundsSize(NSWindowRef window);
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
+CGPoint getContentViewBoundsPosition(NSWindowRef window);
+CGSize getContentViewBoundsSize(NSWindowRef window);
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
 void getCursorPos(NSWindowRef window, float* pos);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 8fece7c5c7cc6c61e324b9ead36d8007c8166ee2..f895c1764396b862aa4adf246c3f22e9b7816559 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -258,17 +258,17 @@ float getDeviceUnitSize(GLViewRef view)
 	return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
 }
 
-const CGPoint getContentViewBoundsPosition(NSWindowRef window)
+CGPoint getContentViewBoundsPosition(NSWindowRef window)
 {
 	return [[(LLNSWindow*)window contentView] bounds].origin;
 }
 
-const CGSize getContentViewBoundsSize(NSWindowRef window)
+CGSize getContentViewBoundsSize(NSWindowRef window)
 {
 	return [[(LLNSWindow*)window contentView] bounds].size;
 }
 
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
 {
     return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
 }
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 932a1ef46f9cb8c9670e3b0e8c799cc93d8c885d..c3663b12dda0499a65d3455d5702cca3c1d4411b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2439,9 +2439,9 @@ bool LLAppViewer::initConfiguration()
 	bool set_defaults = true;
 	if(!loadSettingsFromDirectory("Default", set_defaults))
 	{
-		std::ostringstream msg;
-		msg << "Unable to load default settings file. The installation may be corrupted.";
-		OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+		OSMessageBox(
+			"Unable to load default settings file. The installation may be corrupted.",
+			LLStringUtil::null,OSMB_OK);
 		return false;
 	}
 
@@ -2562,7 +2562,7 @@ bool LLAppViewer::initConfiguration()
 	if(gSavedSettings.getBOOL("DisableCrashLogger"))
 	{
 		LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
-		LLAppViewer::instance()->disableCrashlogger();
+		disableCrashlogger();
 	}
 
 	// Handle initialization from settings.
@@ -2579,7 +2579,7 @@ bool LLAppViewer::initConfiguration()
 		LL_INFOS()	<< msg.str() << LL_ENDL;
 
 		OSMessageBox(
-			msg.str().c_str(),
+			msg.str(),
 			LLStringUtil::null,
 			OSMB_OK);
 
@@ -2689,7 +2689,34 @@ bool LLAppViewer::initConfiguration()
 		ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
 	}
 
+	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+	{
+		// Examining "Language" may not suffice -- see LLUI::getLanguage()
+		// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+		// good because we haven't yet called LLUI::initClass().
+		gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+								 gSavedSettings.getString("Language"));
+	}
+
+	if (gSavedSettings.getBOOL("SpellCheck"))
+	{
+		std::list<std::string> dict_list;
+		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+		if (!dict_list.empty())
+		{
+			LLSpellChecker::setUseSpellCheck(dict_list.front());
+			dict_list.pop_front();
+			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+		}
+	}
+
 	// Handle slurl use. NOTE: Don't let SL-55321 reappear.
+	// This initial-SLURL logic, up through the call to
+	// sendURLToOtherInstance(), must precede LLSplashScreen::show() --
+	// because if sendURLToOtherInstance() succeeds, we take a fast exit,
+	// SKIPPING the splash screen and everything else.
 
     // *FIX: This init code should be made more robust to prevent
     // the issue SL-55321 from returning. One thought is to allow
@@ -2734,6 +2761,27 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
+	// NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
+	std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
+	if ( !nextLoginLocation.empty() )
+	{
+		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
+		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
+	}
+	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
+			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
+	{
+		// If automatic login from command line with --login switch
+		// init StartSLURL location.
+		std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
+		LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
+		LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
+	}
+	else
+	{
+		// the login location will be set by the login panel (see LLPanelLogin)
+	}
+
 	//RN: if we received a URL, hand it off to the existing instance.
 	// don't call anotherInstanceRunning() when doing URL handoff, as
 	// it relies on checking a marker file which will not work when running
@@ -2749,30 +2797,6 @@ bool LLAppViewer::initConfiguration()
 		}
     }
 
-	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
-	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
-	{
-		// Examining "Language" may not suffice -- see LLUI::getLanguage()
-		// logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
-		// good because we haven't yet called LLUI::initClass().
-		gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
-								 gSavedSettings.getString("Language"));
-	}
-
-	if (gSavedSettings.getBOOL("SpellCheck"))
-	{
-		std::list<std::string> dict_list;
-		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
-		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
-		if (!dict_list.empty())
-		{
-			LLSpellChecker::setUseSpellCheck(dict_list.front());
-			dict_list.pop_front();
-			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
-		}
-	}
-
-
 	// Display splash screen.  Must be after above check for previous
 	// crash as this dialog is always frontmost.
 	std::string splash_msg;
@@ -2804,30 +2828,15 @@ bool LLAppViewer::initConfiguration()
 	}
 	LLStringUtil::truncate(gWindowTitle, 255);
 
-	//RN: if we received a URL, hand it off to the existing instance.
-	// don't call anotherInstanceRunning() when doing URL handoff, as
-	// it relies on checking a marker file which will not work when running
-	// out of different directories
-
-	if (LLStartUp::getStartSLURL().isValid() &&
-		(gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
-	{
-		if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
-		{
-			// successfully handed off URL to existing instance, exit
-			return false;
-		}
-	}
-
 	//
 	// Check for another instance of the app running
+	// This happens AFTER LLSplashScreen::show(). That may or may not be
+	// important.
 	//
 	if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
 	{
-		std::ostringstream msg;
-		msg << LLTrans::getString("MBAlreadyRunning");
 		OSMessageBox(
-			msg.str(),
+			LLTrans::getString("MBAlreadyRunning"),
 			LLStringUtil::null,
 			OSMB_OK);
 		return false;
@@ -2845,27 +2854,6 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
-   	// NextLoginLocation is set from the command line option
-	std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
-	if ( !nextLoginLocation.empty() )
-	{
-		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
-		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
-	}
-	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
-			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
-	{
-		// If automatic login from command line with --login switch
-		// init StartSLURL location.
-		std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
-		LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
-		LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
-	}
-	else
-	{
-		// the login location will be set by the login panel (see LLPanelLogin)
-	}
-
 	gLastRunVersion = gSavedSettings.getString("LastRunVersion");
 
 	loadColorSettings();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 0637010b0b62cc9a848f210afa4e62ffbc87e91d..e253557797de8c149132fbffcde1d8a1fce24e05 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -178,7 +178,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	mPasswordModified = FALSE;
 
-	LLPanelLogin::sInstance = this;
+	sInstance = this;
 
 	LLView* login_holder = gViewerWindow->getLoginPanelHolder();
 	if (login_holder)
@@ -234,29 +234,44 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), 
 							 current_grid,
 							 ADD_TOP);	
-	server_choice_combo->selectFirstItem();		
+	server_choice_combo->selectFirstItem();
 
 	LLSLURL start_slurl(LLStartUp::getStartSLURL());
+	// The StartSLURL might have been set either by an explicit command-line
+	// argument (CmdLineLoginLocation) or by default.
+	// current_grid might have been set either by an explicit command-line
+	// argument (CmdLineGridChoice) or by default.
+	// If the grid specified by StartSLURL is the same as current_grid, the
+	// distinction is moot.
+	// If we have an explicit command-line SLURL, use that.
+	// If we DON'T have an explicit command-line SLURL but we DO have an
+	// explicit command-line grid, which is different from the default SLURL's
+	// -- do NOT override the explicit command-line grid with the grid from
+	// the default SLURL!
+	bool force_grid{ start_slurl.getGrid() != current_grid &&
+					 gSavedSettings.getString("CmdLineLoginLocation").empty() &&
+				   ! gSavedSettings.getString("CmdLineGridChoice").empty() };
 	if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ? 
 	{
 		// no, so get the preference setting
 		std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
 		LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL;
 		LLSLURL defaultStart(defaultStartLocation);
-		if ( defaultStart.isSpatial() )
+		if ( defaultStart.isSpatial() && ! force_grid )
 		{
 			LLStartUp::setStartSLURL(defaultStart);
 		}
 		else
 		{
-			LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL;
+			LL_INFOS("AppInit") << (force_grid? "--grid specified" : "no valid LoginLocation")
+								<< ", using home" << LL_ENDL;
 			LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME);
 			LLStartUp::setStartSLURL(homeStart);
 		}
 	}
-	else
+	else if (! force_grid)
 	{
-		LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
+		onUpdateStartSLURL(start_slurl); // updates grid if needed
 	}
 	
 	childSetAction("connect_btn", onClickConnect, this);
@@ -380,7 +395,7 @@ void LLPanelLogin::setFocus(BOOL b)
 	{
 		if(b)
 		{
-			LLPanelLogin::giveFocus();
+			giveFocus();
 		}
 		else
 		{