summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2025-04-15 13:55:01 -0400
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2025-04-15 13:55:01 -0400
commit52cca995ccc30ac5aa989588a71c0a7f4a9804ae (patch)
tree69aecdda91f34883bf38ac86eefe8df61b1c4f22 /indra/llui
parent97085ed30057ce950184f057340e0ecbcfc7614b (diff)
parente43baa755d9b91c029e7b5166317e76468baf896 (diff)
Merge branch 'release/2025.04' into rye/forevermac
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llbutton.cpp2
-rw-r--r--indra/llui/llcommandmanager.cpp2
-rw-r--r--indra/llui/llemojihelper.cpp11
-rw-r--r--indra/llui/llemojihelper.h7
-rw-r--r--indra/llui/llfloater.h6
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llnotifications.cpp33
-rw-r--r--indra/llui/llnotifications.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp2
-rw-r--r--indra/llui/llsearchablecontrol.h10
-rw-r--r--indra/llui/lltextbase.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp19
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/llurlentry.cpp10
14 files changed, 97 insertions, 12 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 1bce31edb1..d2534b3939 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -837,7 +837,7 @@ void LLButton::draw()
// Highlight if needed
if( ll::ui::SearchableControl::getHighlighted() )
- label_color = ll::ui::SearchableControl::getHighlightColor();
+ label_color = ll::ui::SearchableControl::getHighlightFontColor();
// overlay with keyboard focus border
if (hasFocus())
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 03717da80b..b10ec51f18 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -170,12 +170,14 @@ bool LLCommandManager::load()
if (!parser.readXUI(commands_file, commandsParams))
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Unable to load xml file: " << commands_file << LL_ENDL;
return false;
}
if (!commandsParams.validateBlock())
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Invalid commands file: " << commands_file << LL_ENDL;
return false;
}
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index b9441a9c91..b2c59ce775 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -99,6 +99,7 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
LLFloater* pHelperFloater = LLFloaterReg::getInstance(DEFAULT_EMOJI_HELPER_FLOATER);
mHelperHandle = pHelperFloater->getHandle();
mHelperCommitConn = pHelperFloater->setCommitCallback(std::bind([&](const LLSD& sdValue) { onCommitEmoji(utf8str_to_wstring(sdValue.asStringRef())[0]); }, std::placeholders::_2));
+ mHelperCloseConn = pHelperFloater->setCloseCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCloseHelper(ctrl, param); });
}
setHostCtrl(hostctrl_p);
mEmojiCommitCb = cb;
@@ -148,6 +149,16 @@ void LLEmojiHelper::onCommitEmoji(llwchar emoji)
}
}
+void LLEmojiHelper::onCloseHelper(LLUICtrl* ctrl, const LLSD& param)
+{
+ mCloseSignal(ctrl, param);
+}
+
+boost::signals2::connection LLEmojiHelper::setCloseCallback(const commit_signal_t::slot_type& cb)
+{
+ return mCloseSignal.connect(cb);
+}
+
void LLEmojiHelper::setHostCtrl(LLUICtrl* hostctrl_p)
{
const LLUICtrl* pCurHostCtrl = mHostHandle.get();
diff --git a/indra/llui/llemojihelper.h b/indra/llui/llemojihelper.h
index 2834b06061..26840eef94 100644
--- a/indra/llui/llemojihelper.h
+++ b/indra/llui/llemojihelper.h
@@ -51,16 +51,23 @@ public:
// Eventing
bool handleKey(const LLUICtrl* ctrl_p, KEY key, MASK mask);
void onCommitEmoji(llwchar emoji);
+ void onCloseHelper(LLUICtrl* ctrl, const LLSD& param);
+
+ typedef boost::signals2::signal<void(LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
+ boost::signals2::connection setCloseCallback(const commit_signal_t::slot_type& cb);
protected:
LLUICtrl* getHostCtrl() const { return mHostHandle.get(); }
void setHostCtrl(LLUICtrl* hostctrl_p);
private:
+ commit_signal_t mCloseSignal;
+
LLHandle<LLUICtrl> mHostHandle;
LLHandle<LLFloater> mHelperHandle;
boost::signals2::connection mHostCtrlFocusLostConn;
boost::signals2::connection mHelperCommitConn;
+ boost::signals2::connection mHelperCloseConn;
std::function<void(llwchar)> mEmojiCommitCb;
bool mIsHideDisabled;
};
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 9be2240f6f..eae2435117 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -377,6 +377,10 @@ public:
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }
+
+ void setAutoFocus(bool focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
+ bool getAutoFocus() const { return mAutoFocus; }
+
protected:
void applyControlsAndPosition(LLFloater* other);
@@ -401,8 +405,6 @@ protected:
void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
const LLRect& getExpandedRect() const { return mExpandedRect; }
- void setAutoFocus(bool focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
- bool getAutoFocus() const { return mAutoFocus; }
LLDragHandle* getDragHandle() const { return mDragHandle; }
void destroy(); // Don't call this directly. You probably want to call closeFloater()
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 69ffa9a94f..c11b42a348 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -508,7 +508,7 @@ void LLMenuItemGL::draw( void )
// Highlight if needed
if( ll::ui::SearchableControl::getHighlighted() )
- color = ll::ui::SearchableControl::getHighlightColor();
+ color = ll::ui::SearchableControl::getHighlightFontColor();
// Draw the text on top.
if (mBriefItem)
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 7405413a3d..a05feab1d9 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -614,6 +614,13 @@ void LLNotification::cancel()
LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)
{
LLSD response = LLSD::emptyMap();
+
+ if (!mForm)
+ {
+ LL_WARNS("Notifications") << "Null form when getting response template for notification " << getName() << LL_ENDL;
+ return response;
+ }
+
for (S32 element_idx = 0;
element_idx < mForm->getNumElements();
++element_idx)
@@ -1249,9 +1256,26 @@ LLNotifications::LLNotifications()
LLInstanceTracker<LLNotificationChannel, std::string>::instanceCount();
}
+
+LLNotifications::~LLNotifications()
+{
+ // Clear explicitly, something in ~LLNotifications() crashes so narrowing down suspects
+ pHistoryChannel = nullptr;
+ pExpirationChannel = nullptr;
+ mGlobalStrings.clear();
+ mTemplates.clear();
+ mVisibilityRules.clear();
+ mUniqueNotifications.clear();
+ mListener = nullptr;
+}
+
void LLNotifications::clear()
{
- mDefaultChannels.clear();
+ mDefaultChannels.clear();
+ // At this point mTemplates still gets used by lingering notifications
+ // to do responses (ex: group notice will call forceResponse()), but
+ // since network should be down and everything save, it's questionable
+ // whether it should stay that way
}
// The expiration channel gets all notifications that are cancelled
@@ -1464,6 +1488,13 @@ bool LLNotifications::templateExists(std::string_view name)
void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
{
LLNotificationPtr temp_notify(new LLNotification(params));
+
+ if (!temp_notify->getForm())
+ {
+ LL_WARNS("Notifications") << "Cannot force response for notification with null form: " << (std::string)params.name << LL_ENDL;
+ return;
+ }
+
LLSD response = temp_notify->getResponseTemplate();
LLSD selected_item = temp_notify->getForm()->getElement(option);
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 46286457cf..138f1969d5 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -887,7 +887,7 @@ class LLNotifications :
{
LLSINGLETON(LLNotifications);
LOG_CLASS(LLNotifications);
- virtual ~LLNotifications() {}
+ virtual ~LLNotifications();
public:
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 943aff1ca1..245339b107 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3394,7 +3394,7 @@ bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
bool res = false;
- setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red4));
+ setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4));
std::string filter_str_lc(filter_str);
LLStringUtil::toLower(filter_str_lc);
diff --git a/indra/llui/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h
index 7f1421dd19..bae85fe9a5 100644
--- a/indra/llui/llsearchablecontrol.h
+++ b/indra/llui/llsearchablecontrol.h
@@ -43,9 +43,15 @@ namespace ll
virtual ~SearchableControl()
{ }
- const LLColor4& getHighlightColor( ) const
+ const LLColor4& getHighlightBgColor( ) const
{
- static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red4);
+ static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4);
+ return highlight_color.get();
+ }
+
+ const LLColor4& getHighlightFontColor() const
+ {
+ static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightFontColor", LLColor4::red4);
return highlight_color.get();
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index fae22fd248..41e7094163 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1378,7 +1378,7 @@ void LLTextBase::draw()
// Draw highlighted if needed
if( ll::ui::SearchableControl::getHighlighted() )
{
- const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightColor();
+ const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightBgColor();
LLRect bg_rect = mVisibleTextRect;
if( mScroller )
bg_rect.intersectWith( text_rect );
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3537c764b9..fe4cce29ab 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -209,8 +209,15 @@ public:
}
virtual bool execute( LLTextBase* editor, S32* delta )
{
- mWString = editor->getWText().substr(getPosition(), mLen);
- *delta = remove(editor, getPosition(), mLen );
+ try
+ {
+ mWString = editor->getWText().substr(getPosition(), mLen);
+ *delta = remove(editor, getPosition(), mLen);
+ }
+ catch (std::out_of_range&)
+ {
+ return false;
+ }
return (*delta != 0);
}
virtual S32 undo( LLTextBase* editor )
@@ -1211,6 +1218,14 @@ void LLTextEditor::showEmojiHelper()
LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, LLStringUtil::null, cb);
}
+void LLTextEditor::hideEmojiHelper()
+{
+ if (mShowEmojiHelper)
+ {
+ LLEmojiHelper::instance().hideHelper(this);
+ }
+}
+
void LLTextEditor::tryToShowEmojiHelper()
{
if (mReadOnly || !mShowEmojiHelper)
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index e9e7070414..b2b14b01e2 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -207,6 +207,7 @@ public:
bool getShowContextMenu() const { return mShowContextMenu; }
void showEmojiHelper();
+ void hideEmojiHelper();
void setShowEmojiHelper(bool show);
bool getShowEmojiHelper() const { return mShowEmojiHelper; }
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 3cc0c05ffa..77f132e9d8 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -221,6 +221,16 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
},
L'\u002F'); // Solidus
+ std::replace_if(wlabel.begin(),
+ wlabel.end(),
+ [](const llwchar& chr)
+ {
+ return // Not a decomposition, but suficiently similar
+ (chr == L'\u04BA') // "Cyrillic Capital Letter Shha"
+ || (chr == L'\u04BB'); // "Cyrillic Small Letter Shha"
+ },
+ L'\u0068'); // "Latin Small Letter H"
+
std::string label = wstring_to_utf8str(wlabel);
if ((label.find(".com") != std::string::npos
|| label.find("www.") != std::string::npos)