diff --git a/CHANGELOG.md b/CHANGELOG.md index 66b8281b..d5b6f3b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - 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) +- Bugfix: Fixed crash that could occurr when closing the usercard too quickly after blocking or unblocking a user. (#4711) - Dev: Added command to set Qt's logging filter/rules at runtime (`/c2-set-logging-rules`). (#4637) - Dev: Added the ability to see & load custom themes from the Themes directory. No stable promises are made of this feature, changes might be made that breaks custom themes without notice. (#4570) - Dev: Added test cases for emote and tab completion. (#4644) @@ -30,6 +31,7 @@ - Dev: Added `sccache` in Windows CI. (#4678) - Dev: Moved preprocessor Git and date definitions to executables only. (#4681) - Dev: Refactored tests to be able to use `ctest` and run in debug builds. (#4700) +- Dev: Added the ability to use an alternate linker using the `-DUSE_ALTERNATE_LINKER=...` CMake parameter. (#4711) ## 2.4.4 diff --git a/CMakeLists.txt b/CMakeLists.txt index af05f742..db82c9ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,27 @@ elseif (CCACHE_PROGRAM) set(_compiler_launcher ${CCACHE_PROGRAM}) endif () + +# Alternate linker code taken from heavyai/heavydb +# https://github.com/heavyai/heavydb/blob/0517d99b467806f6af7b4c969e351368a667497d/CMakeLists.txt#L87-L103 +macro(set_alternate_linker linker) + find_program(LINKER_EXECUTABLE ld.${USE_ALTERNATE_LINKER} ${USE_ALTERNATE_LINKER}) + if(LINKER_EXECUTABLE) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 12.0.0) + add_link_options("-ld-path=${USE_ALTERNATE_LINKER}") + else() + add_link_options("-fuse-ld=${USE_ALTERNATE_LINKER}") + endif() + else() + set(USE_ALTERNATE_LINKER "" CACHE STRING "Use alternate linker" FORCE) + endif() +endmacro() + +set(USE_ALTERNATE_LINKER "" CACHE STRING "Use alternate linker. Leave empty for system default; alternatives are 'gold', 'lld', 'bfd', 'mold'") +if(NOT "${USE_ALTERNATE_LINKER}" STREQUAL "") + set_alternate_linker(${USE_ALTERNATE_LINKER}) +endif() + if (_compiler_launcher) set(CMAKE_CXX_COMPILER_LAUNCHER "${_compiler_launcher}" CACHE STRING "CXX compiler launcher") message(STATUS "Using ${_compiler_launcher} for speeding up build") diff --git a/mocks/include/mocks/Helix.hpp b/mocks/include/mocks/Helix.hpp index e7fe4ef4..45b1017e 100644 --- a/mocks/include/mocks/Helix.hpp +++ b/mocks/include/mocks/Helix.hpp @@ -105,12 +105,14 @@ public: (override)); MOCK_METHOD(void, blockUser, - (QString targetUserId, std::function successCallback, + (QString targetUserId, const QObject *caller, + std::function successCallback, HelixFailureCallback failureCallback), (override)); MOCK_METHOD(void, unblockUser, - (QString targetUserId, std::function successCallback, + (QString targetUserId, const QObject *caller, + std::function successCallback, HelixFailureCallback failureCallback), (override)); diff --git a/src/controllers/commands/CommandController.cpp b/src/controllers/commands/CommandController.cpp index 3956ec9c..bd282224 100644 --- a/src/controllers/commands/CommandController.cpp +++ b/src/controllers/commands/CommandController.cpp @@ -650,7 +650,7 @@ void CommandController::initialize(Settings &, Paths &paths) target, [currentUser, channel, target](const HelixUser &targetUser) { getApp()->accounts->twitch.getCurrent()->blockUser( - targetUser.id, + targetUser.id, nullptr, [channel, target, targetUser] { channel->addMessage(makeSystemMessage( QString("You successfully blocked user %1") @@ -703,7 +703,7 @@ void CommandController::initialize(Settings &, Paths &paths) target, [currentUser, channel, target](const auto &targetUser) { getApp()->accounts->twitch.getCurrent()->unblockUser( - targetUser.id, + targetUser.id, nullptr, [channel, target, targetUser] { channel->addMessage(makeSystemMessage( QString("You successfully unblocked user %1") diff --git a/src/providers/twitch/TwitchAccount.cpp b/src/providers/twitch/TwitchAccount.cpp index 789ed833..0830fa15 100644 --- a/src/providers/twitch/TwitchAccount.cpp +++ b/src/providers/twitch/TwitchAccount.cpp @@ -121,11 +121,12 @@ void TwitchAccount::loadBlocks() }); } -void TwitchAccount::blockUser(QString userId, std::function onSuccess, +void TwitchAccount::blockUser(QString userId, const QObject *caller, + std::function onSuccess, std::function onFailure) { getHelix()->blockUser( - userId, + userId, caller, [this, userId, onSuccess] { TwitchUser blockedUser; blockedUser.id = userId; @@ -141,11 +142,12 @@ void TwitchAccount::blockUser(QString userId, std::function onSuccess, std::move(onFailure)); } -void TwitchAccount::unblockUser(QString userId, std::function onSuccess, +void TwitchAccount::unblockUser(QString userId, const QObject *caller, + std::function onSuccess, std::function onFailure) { getHelix()->unblockUser( - userId, + userId, caller, [this, userId, onSuccess] { TwitchUser ignoredUser; ignoredUser.id = userId; diff --git a/src/providers/twitch/TwitchAccount.hpp b/src/providers/twitch/TwitchAccount.hpp index 7e4b69d2..154d307f 100644 --- a/src/providers/twitch/TwitchAccount.hpp +++ b/src/providers/twitch/TwitchAccount.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -71,9 +72,11 @@ public: bool isAnon() const; void loadBlocks(); - void blockUser(QString userId, std::function onSuccess, + void blockUser(QString userId, const QObject *caller, + std::function onSuccess, std::function onFailure); - void unblockUser(QString userId, std::function onSuccess, + void unblockUser(QString userId, const QObject *caller, + std::function onSuccess, std::function onFailure); SharedAccessGuard> accessBlockedUserIds() const; diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 59329ae5..b22e2066 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -541,7 +541,7 @@ void Helix::loadBlocks(QString userId, .execute(); } -void Helix::blockUser(QString targetUserId, +void Helix::blockUser(QString targetUserId, const QObject *caller, std::function successCallback, HelixFailureCallback failureCallback) { @@ -549,6 +549,7 @@ void Helix::blockUser(QString targetUserId, urlQuery.addQueryItem("target_user_id", targetUserId); this->makePut("users/blocks", urlQuery) + .caller(caller) .onSuccess([successCallback](auto /*result*/) -> Outcome { successCallback(); return Success; @@ -560,7 +561,7 @@ void Helix::blockUser(QString targetUserId, .execute(); } -void Helix::unblockUser(QString targetUserId, +void Helix::unblockUser(QString targetUserId, const QObject *caller, std::function successCallback, HelixFailureCallback failureCallback) { @@ -568,6 +569,7 @@ void Helix::unblockUser(QString targetUserId, urlQuery.addQueryItem("target_user_id", targetUserId); this->makeDelete("users/blocks", urlQuery) + .caller(caller) .onSuccess([successCallback](auto /*result*/) -> Outcome { successCallback(); return Success; diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 3a370a41..79ff59d6 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -805,12 +805,12 @@ public: HelixFailureCallback failureCallback) = 0; // https://dev.twitch.tv/docs/api/reference#block-user - virtual void blockUser(QString targetUserId, + virtual void blockUser(QString targetUserId, const QObject *caller, std::function successCallback, HelixFailureCallback failureCallback) = 0; // https://dev.twitch.tv/docs/api/reference#unblock-user - virtual void unblockUser(QString targetUserId, + virtual void unblockUser(QString targetUserId, const QObject *caller, std::function successCallback, HelixFailureCallback failureCallback) = 0; @@ -1118,11 +1118,12 @@ public: HelixFailureCallback failureCallback) final; // https://dev.twitch.tv/docs/api/reference#block-user - void blockUser(QString targetUserId, std::function successCallback, + void blockUser(QString targetUserId, const QObject *caller, + std::function successCallback, HelixFailureCallback failureCallback) final; // https://dev.twitch.tv/docs/api/reference#unblock-user - void unblockUser(QString targetUserId, + void unblockUser(QString targetUserId, const QObject *caller, std::function successCallback, HelixFailureCallback failureCallback) final; diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index e6978100..e5955884 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -36,6 +36,7 @@ #include #include #include +#include const QString TEXT_FOLLOWERS("Followers: %1"); const QString TEXT_CREATED("Created: %1"); @@ -593,7 +594,7 @@ void UserInfoPopup::installEvents() this->ui_.block->setEnabled(false); getApp()->accounts->twitch.getCurrent()->unblockUser( - this->userId_, + this->userId_, this, [this, reenableBlockCheckbox, currentUser] { this->channel_->addMessage(makeSystemMessage( QString("You successfully unblocked user %1") @@ -620,7 +621,7 @@ void UserInfoPopup::installEvents() this->ui_.block->setEnabled(false); getApp()->accounts->twitch.getCurrent()->blockUser( - this->userId_, + this->userId_, this, [this, reenableBlockCheckbox, currentUser] { this->channel_->addMessage(makeSystemMessage( QString("You successfully blocked user %1")