From 81dd143d0d901e8e5234cff01fbda246e4621628 Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Tue, 8 Nov 2022 00:16:58 +0100
Subject: [PATCH] [FIXED] Various minor issues   - Typing :+1: doesn't replace
 the short code with the thumbs-up emoji   - Moving the mouse over the emoji
 complete panel highlights the wrong emoji when mScrollPos > 0   - Emoji
 complete panel is missing attributes   - Crash when attempting to show the
 tooltip for an emoji text segment   - Emoji autocomplete panel can sometimes
 show empty (type ':cat', select the heart eyed one, Ctrl-Z and then type 2
 which should show the emoji for :cat2 but shows an empty square instead)

---
 indra/llui/llemojidictionary.cpp                          | 8 ++++----
 indra/llui/llemojidictionary.h                            | 4 ++--
 indra/llui/llemojihelper.cpp                              | 3 ++-
 indra/newview/llpanelemojicomplete.cpp                    | 4 ++--
 .../skins/default/xui/en/widgets/emoji_complete.xml       | 3 +++
 5 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp
index c31638b0bf2..b70a9b2e7a4 100644
--- a/indra/llui/llemojidictionary.cpp
+++ b/indra/llui/llemojidictionary.cpp
@@ -178,22 +178,22 @@ LLWString LLEmojiDictionary::findMatchingEmojis(const std::string& needle) const
 const LLEmojiDescriptor* LLEmojiDictionary::getDescriptorFromShortCode(const std::string& short_code) const
 {
 	const auto it = mShortCode2Descr.find(short_code);
-	return (mShortCode2Descr.end() != it) ? &it->second : nullptr;
+	return (mShortCode2Descr.end() != it) ? it->second : nullptr;
 }
 
 std::string LLEmojiDictionary::getNameFromEmoji(llwchar ch) const
 {
 	const auto it = mEmoji2Descr.find(ch);
-	return (mEmoji2Descr.end() != it) ? it->second.Name : LLStringUtil::null;
+	return (mEmoji2Descr.end() != it) ? it->second->Name : LLStringUtil::null;
 }
 
 void LLEmojiDictionary::addEmoji(LLEmojiDescriptor&& descr)
 {
 	mEmojis.push_back(descr);
-	mEmoji2Descr.insert(std::make_pair(descr.Character, mEmojis.back()));
+	mEmoji2Descr.insert(std::make_pair(descr.Character, &mEmojis.back()));
 	for (const std::string& shortCode : descr.ShortCodes)
 	{
-		mShortCode2Descr.insert(std::make_pair(shortCode, mEmojis.back()));
+		mShortCode2Descr.insert(std::make_pair(shortCode, &mEmojis.back()));
 	}
 }
 
diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h
index 0cde6637196..46a61f1cd71 100644
--- a/indra/llui/llemojidictionary.h
+++ b/indra/llui/llemojidictionary.h
@@ -66,8 +66,8 @@ class LLEmojiDictionary : public LLParamSingleton<LLEmojiDictionary>, public LLI
 
 private:
 	std::list<LLEmojiDescriptor> mEmojis;
-	std::map<llwchar, const LLEmojiDescriptor&> mEmoji2Descr;
-	std::map<std::string, const LLEmojiDescriptor&> mShortCode2Descr;
+	std::map<llwchar, const LLEmojiDescriptor*> mEmoji2Descr;
+	std::map<std::string, const LLEmojiDescriptor*> mShortCode2Descr;
 };
 
 // ============================================================================
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index 32471e59a84..1e4c19a183f 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -57,7 +57,8 @@ bool LLEmojiHelper::isActive(const LLUICtrl* ctrl_p) const
 // static
 bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S32* pShortCodePos)
 {
-	S32 shortCodePos = cursorPos;
+	// If the cursor is currently on a colon start the check one character further back
+	S32 shortCodePos = (cursorPos == 0 || L':' != wtext[cursorPos - 1]) ? cursorPos : cursorPos - 1;
 
 	auto isPartOfShortcode = [](llwchar ch) {
 		switch (ch)
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index a7058a67248..f890a14e8ed 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -146,9 +146,9 @@ void LLPanelEmojiComplete::reshape(S32 width, S32 height, BOOL called_from_paren
 void LLPanelEmojiComplete::setEmojiHint(const std::string& hint)
 {
 	llwchar curEmoji = (mCurSelected < mEmojis.size()) ? mEmojis.at(mCurSelected) : 0;
-	size_t curEmojiIdx = (curEmoji) ? mEmojis.find(curEmoji) : std::string::npos;
 
 	mEmojis = LLEmojiDictionary::instance().findMatchingEmojis(hint);
+	size_t curEmojiIdx = (curEmoji) ? mEmojis.find(curEmoji) : std::string::npos;
 	mCurSelected = (std::string::npos != curEmojiIdx) ? curEmojiIdx : 0;
 
 	if (mAutoSize)
@@ -168,7 +168,7 @@ size_t LLPanelEmojiComplete::posToIndex(S32 x, S32 y) const
 {
 	if (mRenderRect.pointInRect(x, y))
 	{
-		return llmin((size_t)x / mEmojiWidth, mEmojis.size() - 1);
+		return mScrollPos + llmin((size_t)x / mEmojiWidth, mEmojis.size() - 1);
 	}
 	return npos;
 }
diff --git a/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml b/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
index f35105ff7e1..370f1d174e2 100644
--- a/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
+++ b/indra/newview/skins/default/xui/en/widgets/emoji_complete.xml
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <emoji_complete
+  autosize="false"
   font="EmojiHuge"
   hover_image="ListItem_Over"
+  max_emoji="7"
+  padding="8"
   selected_image="ListItem_Select"
   >
 </emoji_complete>
-- 
GitLab