From 0dd287df28bc05f989dda3c05bedc6eff64b73ee Mon Sep 17 00:00:00 2001
From: Henri Beauchamp <sldev@free.fr>
Date: Wed, 7 Dec 2022 00:01:34 +0100
Subject: Fix failures to update the TP states while the viewer is minimized.

This is a fix for: https://jira.secondlife.com/browse/BUG-230616
---
 indra/newview/llviewerdisplay.cpp | 263 ++++++++++++++++++++++----------------
 1 file changed, 153 insertions(+), 110 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index bc0fafb29f..031f9f6c52 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -236,6 +236,148 @@ void display_stats()
     }
 }
 
+static void update_tp_display(bool minimized)
+{
+	static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay");
+	static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");
+
+	S32 attach_count = 0;
+	if (isAgentAvatarValid())
+	{
+		attach_count = gAgentAvatarp->getAttachmentCount();
+	}
+	F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
+	F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
+	F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
+	if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f)
+	{
+		// Give up.  Don't keep the UI locked forever.
+		LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
+		gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+		gAgent.setTeleportMessage(std::string());
+	}
+
+	// Make sure the TP progress panel gets hidden in case the viewer window
+	// is minimized *during* a TP. HB
+	if (minimized)
+	{
+		gViewerWindow->setShowProgress(FALSE);
+	}
+
+	const std::string& message = gAgent.getTeleportMessage();
+	switch (gAgent.getTeleportState())
+	{
+		case LLAgent::TELEPORT_PENDING:
+		{
+			gTeleportDisplayTimer.reset();
+			const std::string& msg = LLAgent::sTeleportProgressMessages["pending"];
+			if (!minimized)
+			{
+				gViewerWindow->setShowProgress(TRUE);
+				gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+				gViewerWindow->setProgressString(msg);
+			}
+			gAgent.setTeleportMessage(msg);
+			break;
+		}
+
+		case LLAgent::TELEPORT_START:
+		{
+			// Transition to REQUESTED.  Viewer has sent some kind
+			// of TeleportRequest to the source simulator
+			gTeleportDisplayTimer.reset();
+			const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"];
+			LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
+			gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
+			gAgent.setTeleportMessage(msg);
+			if (!minimized)
+			{
+				gViewerWindow->setShowProgress(TRUE);
+				gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+				gViewerWindow->setProgressString(msg);
+				gViewerWindow->setProgressMessage(gAgent.mMOTD);
+			}
+			break;
+		}
+
+		case LLAgent::TELEPORT_REQUESTED:
+			// Waiting for source simulator to respond
+			if (!minimized)
+			{
+				gViewerWindow->setProgressPercent(llmin(teleport_percent, 37.5f));
+				gViewerWindow->setProgressString(message);
+			}
+			break;
+
+		case LLAgent::TELEPORT_MOVING:
+			// Viewer has received destination location from source simulator
+			if (!minimized)
+			{
+				gViewerWindow->setProgressPercent(llmin(teleport_percent, 75.f));
+				gViewerWindow->setProgressString(message);
+			}
+			break;
+
+		case LLAgent::TELEPORT_START_ARRIVAL:
+			// Transition to ARRIVING.  Viewer has received avatar update, etc.,
+			// from destination simulator
+			gTeleportArrivalTimer.reset();
+			LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
+			gAgent.setTeleportState(LLAgent::TELEPORT_ARRIVING);
+			gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["arriving"]);
+			gAgent.sheduleTeleportIM();
+			gTextureList.mForceResetTextureStats = TRUE;
+			gAgentCamera.resetView(TRUE, TRUE);			
+			if (!minimized)
+			{
+				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
+				gViewerWindow->setProgressPercent(75.f);
+			}
+			break;
+
+		case LLAgent::TELEPORT_ARRIVING:
+		// Make the user wait while content "pre-caches"
+		{
+			F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());
+			if (arrival_fraction > 1.f)
+			{
+				arrival_fraction = 1.f;
+				//LLFirstUse::useTeleport();
+				LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
+				gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+			}
+			if (!minimized)
+			{
+				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
+				gViewerWindow->setProgressPercent(arrival_fraction * 25.f + 75.f);
+				gViewerWindow->setProgressString(message);
+			}
+			break;
+		}
+
+		case LLAgent::TELEPORT_LOCAL:
+		// Short delay when teleporting in the same sim (progress screen active but not shown - did not
+		// fall-through from TELEPORT_START)
+		{
+			if (gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay())
+			{
+				//LLFirstUse::useTeleport();
+				LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
+									 << " exceeds teleport_local_delete " << teleport_local_delay
+									 << "; setting state to TELEPORT_NONE"
+									 << LL_ENDL;
+				gAgent.setTeleportState(LLAgent::TELEPORT_NONE);
+			}
+			break;
+		}
+
+		case LLAgent::TELEPORT_NONE:
+			// No teleport in progress
+			gViewerWindow->setShowProgress(FALSE);
+			gTeleportDisplay = FALSE;
+	}
+}
+
 static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
 static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
 static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD");
@@ -326,6 +468,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		stop_glerror();
 		gViewerWindow->returnEmptyPicks();
 		stop_glerror();
+
+		// We still need to update the teleport progress (to get changes done
+		// in TP states, else the sim does not get the messages signaling the
+		// agent's arrival). This fixes BUG-230616. HB
+		if (gTeleportDisplay)
+		{
+			// true = minimized, do not show/update the TP screen. HB
+			update_tp_display(true);
+		}
 		return; 
 	}
 
@@ -413,116 +564,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	{
 		LL_RECORD_BLOCK_TIME(FTM_TELEPORT_DISPLAY);
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
-		static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay");
-		static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");
-
-		S32 attach_count = 0;
-		if (isAgentAvatarValid())
-		{
-			attach_count = gAgentAvatarp->getAttachmentCount();
-		}
-		F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
-		F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
-		F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
-		if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
-		{
-			// Give up.  Don't keep the UI locked forever.
-			LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
-			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-			gAgent.setTeleportMessage(std::string());
-		}
-
-		const std::string& message = gAgent.getTeleportMessage();
-		switch( gAgent.getTeleportState() )
-		{
-		case LLAgent::TELEPORT_PENDING:
-			gTeleportDisplayTimer.reset();
-			gViewerWindow->setShowProgress(TRUE);
-			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
-			gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]);
-			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]);
-			break;
-
-		case LLAgent::TELEPORT_START:
-			// Transition to REQUESTED.  Viewer has sent some kind
-			// of TeleportRequest to the source simulator
-			gTeleportDisplayTimer.reset();
-			gViewerWindow->setShowProgress(TRUE);
-			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
-			LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
-			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
-			gAgent.setTeleportMessage(
-				LLAgent::sTeleportProgressMessages["requesting"]);
-			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]);
-			gViewerWindow->setProgressMessage(gAgent.mMOTD);
-			break;
-
-		case LLAgent::TELEPORT_REQUESTED:
-			// Waiting for source simulator to respond
-			gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
-			gViewerWindow->setProgressString(message);
-			break;
-
-		case LLAgent::TELEPORT_MOVING:
-			// Viewer has received destination location from source simulator
-			gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
-			gViewerWindow->setProgressString(message);
-			break;
-
-		case LLAgent::TELEPORT_START_ARRIVAL:
-			// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
-			gTeleportArrivalTimer.reset();
-				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
-			gViewerWindow->setProgressPercent(75.f);
-			LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
-			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
-			gAgent.setTeleportMessage(
-				LLAgent::sTeleportProgressMessages["arriving"]);
-			gAgent.sheduleTeleportIM();
-			gTextureList.mForceResetTextureStats = TRUE;
-			gAgentCamera.resetView(TRUE, TRUE);
-			
-			break;
-
-		case LLAgent::TELEPORT_ARRIVING:
-			// Make the user wait while content "pre-caches"
-			{
-				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());
-				if( arrival_fraction > 1.f )
-				{
-					arrival_fraction = 1.f;
-					//LLFirstUse::useTeleport();
-					LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
-					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-				}
-				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
-				gViewerWindow->setProgressPercent(  arrival_fraction * 25.f + 75.f);
-				gViewerWindow->setProgressString(message);
-			}
-			break;
-
-		case LLAgent::TELEPORT_LOCAL:
-			// Short delay when teleporting in the same sim (progress screen active but not shown - did not
-			// fall-through from TELEPORT_START)
-			{
-				if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() )
-				{
-					//LLFirstUse::useTeleport();
-					LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
-										 << " exceeds teleport_local_delete " << teleport_local_delay
-										 << "; setting state to TELEPORT_NONE"
-										 << LL_ENDL;
-					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-				}
-			}
-			break;
-
-		case LLAgent::TELEPORT_NONE:
-			// No teleport in progress
-			gViewerWindow->setShowProgress(FALSE);
-			gTeleportDisplay = FALSE;
-			break;
-		}
+		// Note: false = not minimized, do update the TP screen. HB
+		update_tp_display(false);
 	}
     else if(LLAppViewer::instance()->logoutRequestSent())
 	{
-- 
cgit v1.2.3