From f6f52d327be5f03265d66a95df6fc0716f91ca07 Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Sun, 23 Oct 2022 16:35:44 +0200
Subject: Provide a way for a floater to remain the topmost floater, even when
 focus is given to a different floater

---
 indra/llui/llfloater.cpp | 24 +++++++++++++++++++++++-
 indra/llui/llfloater.h   |  4 ++++
 2 files changed, 27 insertions(+), 1 deletion(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 0e42922543..04f6b11b7c 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -3039,7 +3039,29 @@ void LLFloaterView::syncFloaterTabOrder()
 			LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
 			if (gFocusMgr.childHasKeyboardFocus(floaterp))
 			{
-				bringToFront(floaterp, FALSE);
+                if (mFrontChild != floaterp)
+                {
+                    // Grab a list of the top floaters that want to stay on top of the focused floater
+					std::list<LLView*> listTop;
+					if (mFrontChild && !mFrontChild->canFocusStealFrontmost())
+                    {
+                        for (LLView* childfloaterp : *getChildList())
+                        {
+                            if (static_cast<LLFloater*>(childfloaterp)->canFocusStealFrontmost())
+                                break;
+							listTop.push_back(childfloaterp);
+                        }
+                    }
+
+                    bringToFront(floaterp, FALSE);
+
+                    // Restore top floaters
+                    for (LLView* childp :listTop)
+                    {
+                        sendChildToFront(childp);
+                    }
+                }
+
 				break;
 			}
 		}
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 2672d600c6..1d4aff31eb 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -313,6 +313,9 @@ public:
 	/*virtual*/ void setVisible(BOOL visible); // do not override
 	/*virtual*/ void onVisibilityChange ( BOOL new_visibility ); // do not override
 	
+	bool            canFocusStealFrontmost() const { return mFocusStealsFrontmost; }
+	void            setFocusStealsFrontmost(bool wants_frontmost) { mFocusStealsFrontmost = wants_frontmost; }
+
 	void			setFrontmost(BOOL take_focus = TRUE, BOOL restore = TRUE);
      virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
 	
@@ -478,6 +481,7 @@ private:
 	BOOL			mCanTearOff;
 	BOOL			mCanMinimize;
 	BOOL			mCanClose;
+    bool            mFocusStealsFrontmost = true;	// FALSE if we don't want the currently focused floater to cover this floater without user interaction
 	BOOL			mDragOnLeft;
 	BOOL			mResizable;
 
-- 
cgit v1.2.3