From a440f0261a831bf582a3326ddc5270e89c4c2c43 Mon Sep 17 00:00:00 2001 From: pajlada Date: Sun, 23 Jul 2023 12:11:57 +0200 Subject: [PATCH] Fix crash that could occur when closing a split before its display name was updated (#4731) This fixes a crash that could occur when closing a split before the display name had a chance to update The reason I found this was because the LiveController change I made updated display names more regularly Additionally, we now make sure to not send duplicate `displayNameUpdated` signals upon each request for channels with CJK characters in their display name * Default-initialize the `actualDisplayName` with the user's login name to not send an initial display name update if the display name is the same casing as the login name --- CHANGELOG.md | 1 + src/providers/twitch/TwitchChannel.cpp | 6 ++++-- src/providers/twitch/TwitchChannel.hpp | 9 +++++++++ src/widgets/splits/Split.cpp | 7 ++++--- src/widgets/splits/Split.hpp | 4 ++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acb0a16b4..d6070479d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Bugfix: Fixed generation of crashdumps by the browser-extension process when the browser was closed. (#4667) - Bugfix: Fix spacing issue with mentions inside RTL text. (#4677) - Bugfix: Fixed a crash when opening and closing a reply thread and switching the user. (#4675) +- Bugfix: Fixed a crash that could happen when closing splits before their display name was updated. This was especially noticeable after the live controller changes. (#4731) - Bugfix: Fix visual glitches with smooth scrolling. (#4501) - Bugfix: Fixed pings firing for the "Your username" highlight when not signed in. (#4698) - Bugfix: Fixed partially broken filters on Qt 6 builds. (#4702) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 4d88bf5f7..26f1547ad 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -73,7 +73,7 @@ namespace { TwitchChannel::TwitchChannel(const QString &name) : Channel(name, Channel::Type::Twitch) , ChannelChatters(*static_cast(this)) - , nameOptions{name, name} + , nameOptions{name, name, name} , subscriptionUrl_("https://www.twitch.tv/subs/" + name) , channelUrl_("https://twitch.tv/" + name) , popoutPlayerUrl_("https://player.twitch.tv/?parent=twitch.tv&channel=" + @@ -472,7 +472,7 @@ void TwitchChannel::updateStreamTitle(const QString &title) void TwitchChannel::updateDisplayName(const QString &displayName) { - if (displayName == this->getDisplayName()) + if (displayName == this->nameOptions.actualDisplayName) { // Display name has not changed return; @@ -480,6 +480,8 @@ void TwitchChannel::updateDisplayName(const QString &displayName) // Display name has changed + this->nameOptions.actualDisplayName = displayName; + if (QString::compare(displayName, this->getName(), Qt::CaseInsensitive) == 0) { diff --git a/src/providers/twitch/TwitchChannel.hpp b/src/providers/twitch/TwitchChannel.hpp index 6f9fd6a96..35de959ca 100644 --- a/src/providers/twitch/TwitchChannel.hpp +++ b/src/providers/twitch/TwitchChannel.hpp @@ -229,8 +229,17 @@ public: private: struct NameOptions { + // displayName is the non-CJK-display name for this user + // This will always be the same as their `name_`, but potentially with different casing QString displayName; + + // localizedName is their display name that *may* contain CJK characters + // If the display name does not contain any CJK characters, this will be + // the same as `displayName` QString localizedName; + + // actualDisplayName is the raw display name string received from Twitch + QString actualDisplayName; } nameOptions; private: diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 5b9941ef1..1b00bf527 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -850,9 +850,10 @@ void Split::setChannel(IndirectChannel newChannel) this->header_->setViewersButtonVisible(false); } - this->channel_.get()->displayNameChanged.connect([this] { - this->actionRequested.invoke(Action::RefreshTab); - }); + this->channelSignalHolder_.managedConnect( + this->channel_.get()->displayNameChanged, [this] { + this->actionRequested.invoke(Action::RefreshTab); + }); this->channelChanged.invoke(); this->actionRequested.invoke(Action::RefreshTab); diff --git a/src/widgets/splits/Split.hpp b/src/widgets/splits/Split.hpp index 833bfffe4..c7c82e473 100644 --- a/src/widgets/splits/Split.hpp +++ b/src/widgets/splits/Split.hpp @@ -163,6 +163,10 @@ private: pajlada::Signals::Connection roomModeChangedConnection_; pajlada::Signals::Connection indirectChannelChangedConnection_; + + // This signal-holder is cleared whenever this split changes the underlying channel + pajlada::Signals::SignalHolder channelSignalHolder_; + pajlada::Signals::SignalHolder signalHolder_; std::vector bSignals_;