Migrate to C++ 20 & switch to websocketpp develop branch (#4252)

* feat: c++ 20

* fix: c++ 20 deprecations

* fix(msvc): warnings

* chore: add changelog entry

* fix: formatting

* Update websocketpp to the `develop` branch

* Specify other template type in FlagsEnum != operator

* Remove the user of simple template ids in our websocketpp template class

Also standardizes the file a bit by using nested namespaces, using
pragma once

* fix: turn `MAGIC_MESSAGE_SUFFIX` into a `QString`

* hacky unhacky hacky const char hack

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
nerix 2022-12-24 12:56:11 +01:00 committed by GitHub
parent 99e038ce5e
commit 86e71c8bd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 219 additions and 212 deletions

View file

@ -16,6 +16,7 @@
- Bugfix: Fixed crash that could occur when changing Tab layout and utilizing multiple windows. (#4248) - Bugfix: Fixed crash that could occur when changing Tab layout and utilizing multiple windows. (#4248)
- Dev: Remove protocol from QApplication's Organization Domain (so changed from `https://www.chatterino.com` to `chatterino.com`). (#4256) - Dev: Remove protocol from QApplication's Organization Domain (so changed from `https://www.chatterino.com` to `chatterino.com`). (#4256)
- Dev: Ignore `WM_SHOWWINDOW` hide events, causing fewer attempted rescales. (#4198) - Dev: Ignore `WM_SHOWWINDOW` hide events, causing fewer attempted rescales. (#4198)
- Dev: Migrated to C++ 20 (#4252)
## 2.4.0 ## 2.4.0

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.8) cmake_minimum_required(VERSION 3.12)
cmake_policy(SET CMP0087 NEW) cmake_policy(SET CMP0087 NEW)
include(FeatureSummary) include(FeatureSummary)
@ -143,7 +143,7 @@ else()
add_subdirectory("${CMAKE_SOURCE_DIR}/lib/settings" EXCLUDE_FROM_ALL) add_subdirectory("${CMAKE_SOURCE_DIR}/lib/settings" EXCLUDE_FROM_ALL)
endif() endif()
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (BUILD_TESTS OR BUILD_BENCHMARKS) if (BUILD_TESTS OR BUILD_BENCHMARKS)

@ -1 +1 @@
Subproject commit 1b11fd301531e6df35a6107c1e8665b1e77a2d8e Subproject commit b9aeec6eaf3d5610503439b4fae3581d9aff08e8

View file

@ -551,7 +551,7 @@ void Application::initPubSub()
this->twitch->pubsub->start(); this->twitch->pubsub->start();
auto RequestModerationActions = [=]() { auto RequestModerationActions = [this]() {
this->twitch->pubsub->setAccount( this->twitch->pubsub->setAccount(
getApp()->accounts->twitch.getCurrent()); getApp()->accounts->twitch.getCurrent());
// TODO(pajlada): Unlisten to all authed topics instead of only // TODO(pajlada): Unlisten to all authed topics instead of only
@ -561,7 +561,7 @@ void Application::initPubSub()
}; };
this->accounts->twitch.currentUserChanged.connect( this->accounts->twitch.currentUserChanged.connect(
[=] { [this] {
this->twitch->pubsub->unlistenAllModerationActions(); this->twitch->pubsub->unlistenAllModerationActions();
this->twitch->pubsub->unlistenAutomod(); this->twitch->pubsub->unlistenAutomod();
this->twitch->pubsub->unlistenWhispers(); this->twitch->pubsub->unlistenWhispers();

View file

@ -789,28 +789,32 @@ if (MSVC)
# Someone adds /W3 before we add /W4. # Someone adds /W3 before we add /W4.
# This makes sure, only /W4 is specified. # This makes sure, only /W4 is specified.
string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# 4714 - function marked as __forceinline not inlined # 4505 - "unreferenced local version has been removed"
# 4996 - occurs when the compiler encounters a function or variable that is marked as deprecated. # Although this might give hints on dead code,
# These functions may have a different preferred name, may be insecure or have # there are some cases where it's distracting.
# a more secure variant, or may be obsolete. #
# 4505 - unreferenced local version has been removed # 4100 - "unreferenced formal parameter"
# 4127 - conditional expression is constant # There are a lot of functions and methods where
# 4503 - decorated name length exceeded, name was truncated # an argument was given a name but never used.
# 4100 - unreferences formal parameter # There's a clang-tidy rule that will catch this
# 4305 - possible truncation of data # for new/updated functions/methods.
# 4267 - possible loss of data in return #
# 4267 - "possible loss of data in return"
# These are implicit conversions from size_t to int/qsizetype.
# We don't use size_t in a lot of cases, since
# Qt doesn't use it - it uses int (or qsizetype in Qt6).
target_compile_options(${LIBRARY_PROJECT} PUBLIC target_compile_options(${LIBRARY_PROJECT} PUBLIC
/W4 /W4
# Disable the following warnings # 5038 - warnings about initialization order
/wd4714 /w15038
/wd4996 # 4855 - implicit capture of 'this' via '[=]' is deprecated
/w14855
# Disable the following warnings (see reasoning above)
/wd4505 /wd4505
/wd4127
/wd4503
/wd4100 /wd4100
/wd4305
/wd4267 /wd4267
) )
target_compile_definitions(${LIBRARY_PROJECT} PUBLIC NOMINMAX)
else () else ()
target_compile_options(${LIBRARY_PROJECT} PUBLIC target_compile_options(${LIBRARY_PROJECT} PUBLIC
-Wall -Wall

View file

@ -94,7 +94,7 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord)
// Twitch channel // Twitch channel
auto *tc = dynamic_cast<TwitchChannel *>(&this->channel_); auto *tc = dynamic_cast<TwitchChannel *>(&this->channel_);
auto addString = [=](const QString &str, TaggedString::Type type) { auto addString = [=, this](const QString &str, TaggedString::Type type) {
// Special case for handling default Twitch commands // Special case for handling default Twitch commands
if (type == TaggedString::TwitchCommand) if (type == TaggedString::TwitchCommand)
{ {

View file

@ -32,7 +32,7 @@ public:
return this->value_ == other.value_; return this->value_ == other.value_;
} }
bool operator!=(const FlagsEnum &other) bool operator!=(const FlagsEnum<T> &other)
{ {
return this->value_ != other.value_; return this->value_ != other.value_;
} }

View file

@ -42,7 +42,7 @@ void NotificationController::initialize(Settings &settings, Paths &paths)
this->fetchFakeChannels(); this->fetchFakeChannels();
QObject::connect(this->liveStatusTimer_, &QTimer::timeout, [=] { QObject::connect(this->liveStatusTimer_, &QTimer::timeout, [this] {
this->fetchFakeChannels(); this->fetchFakeChannels();
}); });
this->liveStatusTimer_->start(60 * 1000); this->liveStatusTimer_->start(60 * 1000);

View file

@ -273,7 +273,7 @@ void MessageLayout::paint(QPainter &painter, int width, int y, int messageIndex,
if (isLastReadMessage) if (isLastReadMessage)
{ {
QColor color; QColor color;
if (getSettings()->lastMessageColor != "") if (getSettings()->lastMessageColor != QStringLiteral(""))
{ {
color = QColor(getSettings()->lastMessageColor.getValue()); color = QColor(getSettings()->lastMessageColor.getValue());
} }

View file

@ -204,7 +204,7 @@ private:
this->clients_.emplace(hdl, client); this->clients_.emplace(hdl, client);
auto pendingSubsToTake = (std::min)(this->pendingSubscriptions_.size(), auto pendingSubsToTake = std::min(this->pendingSubscriptions_.size(),
client->maxSubscriptions); client->maxSubscriptions);
qCDebug(chatterinoLiveupdates) qCDebug(chatterinoLiveupdates)

View file

@ -25,8 +25,7 @@
* *
*/ */
#ifndef CHATTERINOWEBSOCKETPPLOGGER_HPP #pragma once
#define CHATTERINOWEBSOCKETPPLOGGER_HPP
#include "common/QLogging.hpp" #include "common/QLogging.hpp"
@ -36,46 +35,43 @@
#include <string> #include <string>
namespace websocketpp { namespace websocketpp::log {
namespace log {
template <typename concurrency, typename names> template <typename concurrency, typename names>
class chatterinowebsocketpplogger : public basic<concurrency, names> class chatterinowebsocketpplogger : public basic<concurrency, names>
{ {
public: public:
typedef chatterinowebsocketpplogger<concurrency, names> base; using base = chatterinowebsocketpplogger<concurrency, names>;
chatterinowebsocketpplogger<concurrency, names>( chatterinowebsocketpplogger(channel_type_hint::value)
channel_type_hint::value)
: m_static_channels(0xffffffff) : m_static_channels(0xffffffff)
, m_dynamic_channels(0) , m_dynamic_channels(0)
{ {
} }
chatterinowebsocketpplogger<concurrency, names>(std::ostream *) chatterinowebsocketpplogger(std::ostream *)
: m_static_channels(0xffffffff) : m_static_channels(0xffffffff)
, m_dynamic_channels(0) , m_dynamic_channels(0)
{ {
} }
chatterinowebsocketpplogger<concurrency, names>( chatterinowebsocketpplogger(level c, channel_type_hint::value)
level c, channel_type_hint::value)
: m_static_channels(c) : m_static_channels(c)
, m_dynamic_channels(0) , m_dynamic_channels(0)
{ {
} }
chatterinowebsocketpplogger<concurrency, names>(level c, std::ostream *) chatterinowebsocketpplogger(level c, std::ostream *)
: m_static_channels(c) : m_static_channels(c)
, m_dynamic_channels(0) , m_dynamic_channels(0)
{ {
} }
~chatterinowebsocketpplogger<concurrency, names>() ~chatterinowebsocketpplogger()
{ {
} }
chatterinowebsocketpplogger<concurrency, names>( chatterinowebsocketpplogger(
chatterinowebsocketpplogger<concurrency, names> const &other) chatterinowebsocketpplogger<concurrency, names> const &other)
: m_static_channels(other.m_static_channels) : m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels) , m_dynamic_channels(other.m_dynamic_channels)
@ -89,7 +85,7 @@ namespace log {
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
/// Move constructor /// Move constructor
chatterinowebsocketpplogger<concurrency, names>( chatterinowebsocketpplogger(
chatterinowebsocketpplogger<concurrency, names> &&other) chatterinowebsocketpplogger<concurrency, names> &&other)
: m_static_channels(other.m_static_channels) : m_static_channels(other.m_static_channels)
, m_dynamic_channels(other.m_dynamic_channels) , m_dynamic_channels(other.m_dynamic_channels)
@ -185,17 +181,14 @@ namespace log {
return ((channel & m_dynamic_channels) != 0); return ((channel & m_dynamic_channels) != 0);
} }
protected: protected:
typedef typename concurrency::scoped_lock_type scoped_lock_type; using scoped_lock_type = typename concurrency::scoped_lock_type;
typedef typename concurrency::mutex_type mutex_type; using mutex_type = typename concurrency::mutex_type;
mutex_type m_lock; mutex_type m_lock;
private: private:
level const m_static_channels; level const m_static_channels;
level m_dynamic_channels; level m_dynamic_channels;
}; };
} // namespace log } // namespace websocketpp::log
} // namespace websocketpp
#endif // CHATTERINOWEBSOCKETPPLOGGER_HPP

View file

@ -464,7 +464,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *_message,
"callback since reward is not known:" "callback since reward is not known:"
<< rewardId; << rewardId;
channel->channelPointRewardAdded.connect( channel->channelPointRewardAdded.connect(
[=, &server](ChannelPointReward reward) { [=, this, &server](ChannelPointReward reward) {
qCDebug(chatterinoTwitch) qCDebug(chatterinoTwitch)
<< "TwitchChannel reward added callback:" << reward.id << "TwitchChannel reward added callback:" << reward.id
<< "-" << rewardId; << "-" << rewardId;

View file

@ -829,7 +829,7 @@ void PubSub::onConnectionOpen(WebsocketHandle hdl)
qCDebug(chatterinoPubSub) << "PubSub connection opened!"; qCDebug(chatterinoPubSub) << "PubSub connection opened!";
const auto topicsToTake = const auto topicsToTake =
(std::min)(this->requests.size(), PubSubClient::MAX_LISTENS); std::min(this->requests.size(), PubSubClient::MAX_LISTENS);
std::vector<QString> newTopics( std::vector<QString> newTopics(
std::make_move_iterator(this->requests.begin()), std::make_move_iterator(this->requests.begin()),

View file

@ -38,7 +38,11 @@
namespace chatterino { namespace chatterino {
namespace { namespace {
constexpr char MAGIC_MESSAGE_SUFFIX[] = u8" \U000E0000"; #if QT_VERSION < QT_VERSION_CHECK(6, 1, 0)
const QString MAGIC_MESSAGE_SUFFIX = QString((const char *)u8" \U000E0000");
#else
const QString MAGIC_MESSAGE_SUFFIX = QString::fromUtf8(u8" \U000E0000");
#endif
constexpr int TITLE_REFRESH_PERIOD = 10000; constexpr int TITLE_REFRESH_PERIOD = 10000;
constexpr int CLIP_CREATION_COOLDOWN = 5000; constexpr int CLIP_CREATION_COOLDOWN = 5000;
const QString CLIPS_LINK("https://clips.twitch.tv/%1"); const QString CLIPS_LINK("https://clips.twitch.tv/%1");
@ -72,7 +76,7 @@ TwitchChannel::TwitchChannel(const QString &name)
qCDebug(chatterinoTwitch) << "[TwitchChannel" << name << "] Opened"; qCDebug(chatterinoTwitch) << "[TwitchChannel" << name << "] Opened";
this->bSignals_.emplace_back( this->bSignals_.emplace_back(
getApp()->accounts->twitch.currentUserChanged.connect([=] { getApp()->accounts->twitch.currentUserChanged.connect([this] {
this->setMod(false); this->setMod(false);
this->refreshPubSub(); this->refreshPubSub();
})); }));
@ -124,13 +128,13 @@ TwitchChannel::TwitchChannel(const QString &name)
// timers // timers
QObject::connect(&this->chattersListTimer_, &QTimer::timeout, [=] { QObject::connect(&this->chattersListTimer_, &QTimer::timeout, [this] {
this->refreshChatters(); this->refreshChatters();
}); });
this->chattersListTimer_.start(5 * 60 * 1000); this->chattersListTimer_.start(5 * 60 * 1000);
QObject::connect(&this->threadClearTimer_, &QTimer::timeout, [=] { QObject::connect(&this->threadClearTimer_, &QTimer::timeout, [this] {
// We periodically check for any dangling reply threads that missed // We periodically check for any dangling reply threads that missed
// being cleaned up on messageRemovedFromStart. This could occur if // being cleaned up on messageRemovedFromStart. This could occur if
// some other part of the program, like a user card, held a reference // some other part of the program, like a user card, held a reference

View file

@ -71,7 +71,7 @@ void TwitchIrcServer::initialize(Settings &settings, Paths &paths)
this->reloadSevenTVGlobalEmotes(); this->reloadSevenTVGlobalEmotes();
/* Refresh all twitch channel's live status in bulk every 30 seconds after starting chatterino */ /* Refresh all twitch channel's live status in bulk every 30 seconds after starting chatterino */
QObject::connect(&this->bulkLiveStatusTimer_, &QTimer::timeout, [=] { QObject::connect(&this->bulkLiveStatusTimer_, &QTimer::timeout, [this] {
this->bulkRefreshLiveStatus(); this->bulkRefreshLiveStatus();
}); });
this->bulkLiveStatusTimer_.start(30 * 1000); this->bulkLiveStatusTimer_.start(30 * 1000);

View file

@ -1815,7 +1815,7 @@ void Helix::onFetchChattersSuccess(
this->fetchChatters( this->fetchChatters(
broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, chatters.cursor, broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, chatters.cursor,
[=](auto chatters) { [=, this](auto chatters) {
this->onFetchChattersSuccess( this->onFetchChattersSuccess(
finalChatters, broadcasterID, moderatorID, maxChattersToFetch, finalChatters, broadcasterID, moderatorID, maxChattersToFetch,
successCallback, failureCallback, chatters); successCallback, failureCallback, chatters);
@ -1925,7 +1925,7 @@ void Helix::onFetchModeratorsSuccess(
this->fetchModerators( this->fetchModerators(
broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, moderators.cursor, broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, moderators.cursor,
[=](auto moderators) { [=, this](auto moderators) {
this->onFetchModeratorsSuccess( this->onFetchModeratorsSuccess(
finalModerators, broadcasterID, maxModeratorsToFetch, finalModerators, broadcasterID, maxModeratorsToFetch,
successCallback, failureCallback, moderators); successCallback, failureCallback, moderators);
@ -2236,7 +2236,7 @@ void Helix::getChatters(
// Initiate the recursive calls // Initiate the recursive calls
this->fetchChatters( this->fetchChatters(
broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, "", broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, "",
[=](auto chatters) { [=, this](auto chatters) {
this->onFetchChattersSuccess( this->onFetchChattersSuccess(
finalChatters, broadcasterID, moderatorID, maxChattersToFetch, finalChatters, broadcasterID, moderatorID, maxChattersToFetch,
successCallback, failureCallback, chatters); successCallback, failureCallback, chatters);
@ -2255,7 +2255,7 @@ void Helix::getModerators(
// Initiate the recursive calls // Initiate the recursive calls
this->fetchModerators( this->fetchModerators(
broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, "", broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, "",
[=](auto moderators) { [=, this](auto moderators) {
this->onFetchModeratorsSuccess( this->onFetchModeratorsSuccess(
finalModerators, broadcasterID, maxModeratorsToFetch, finalModerators, broadcasterID, maxModeratorsToFetch,
successCallback, failureCallback, moderators); successCallback, failureCallback, moderators);

View file

@ -20,7 +20,7 @@ AccountSwitchWidget::AccountSwitchWidget(QWidget *parent)
this->addItem(userName); this->addItem(userName);
} }
app->accounts->twitch.userListUpdated.connect([=]() { app->accounts->twitch.userListUpdated.connect([=, this]() {
this->blockSignals(true); this->blockSignals(true);
this->clear(); this->clear();
@ -39,7 +39,7 @@ AccountSwitchWidget::AccountSwitchWidget(QWidget *parent)
this->refreshSelection(); this->refreshSelection();
QObject::connect(this, &QListWidget::clicked, [=] { QObject::connect(this, &QListWidget::clicked, [=, this] {
if (!this->selectedItems().isEmpty()) if (!this->selectedItems().isEmpty())
{ {
QString newUsername = this->currentItem()->text(); QString newUsername = this->currentItem()->text();

View file

@ -641,13 +641,13 @@ void Window::addMenuBar()
QAction *nextTab = windowMenu->addAction(QString("Select next tab")); QAction *nextTab = windowMenu->addAction(QString("Select next tab"));
nextTab->setShortcuts({QKeySequence("Meta+Tab")}); nextTab->setShortcuts({QKeySequence("Meta+Tab")});
connect(nextTab, &QAction::triggered, this, [=] { connect(nextTab, &QAction::triggered, this, [this] {
this->notebook_->selectNextTab(); this->notebook_->selectNextTab();
}); });
QAction *prevTab = windowMenu->addAction(QString("Select previous tab")); QAction *prevTab = windowMenu->addAction(QString("Select previous tab"));
prevTab->setShortcuts({QKeySequence("Meta+Shift+Tab")}); prevTab->setShortcuts({QKeySequence("Meta+Shift+Tab")});
connect(prevTab, &QAction::triggered, this, [=] { connect(prevTab, &QAction::triggered, this, [this] {
this->notebook_->selectPreviousTab(); this->notebook_->selectPreviousTab();
}); });
} }

View file

@ -42,7 +42,7 @@ BadgePickerDialog::BadgePickerDialog(QList<DisplayBadge> badges,
this->dropdown_->addItem(item.displayName(), item.badgeName()); this->dropdown_->addItem(item.displayName(), item.badgeName());
} }
const auto updateBadge = [=](int index) { const auto updateBadge = [=, this](int index) {
BadgeOpt badge; BadgeOpt badge;
if (index >= 0 && index < badges.size()) if (index >= 0 && index < badges.size())
{ {

View file

@ -94,11 +94,12 @@ ColorPickerDialog::ColorPickerDialog(const QColor &initial, QWidget *parent)
layout.emplace<QHBoxLayout>().emplace<QDialogButtonBox>(this); layout.emplace<QHBoxLayout>().emplace<QDialogButtonBox>(this);
{ {
auto *button_ok = buttons->addButton(QDialogButtonBox::Ok); auto *button_ok = buttons->addButton(QDialogButtonBox::Ok);
QObject::connect(button_ok, &QPushButton::clicked, [=](bool) { QObject::connect(button_ok, &QPushButton::clicked, [this](bool) {
this->ok(); this->ok();
}); });
auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel); auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel);
QObject::connect(button_cancel, &QAbstractButton::clicked, [=](bool) { QObject::connect(button_cancel, &QAbstractButton::clicked,
[this](bool) {
this->close(); this->close();
}); });
} }
@ -226,7 +227,7 @@ void ColorPickerDialog::initRecentColors(LayoutCreator<QWidget> &creator)
grid->addWidget(button, rowInd, columnInd); grid->addWidget(button, rowInd, columnInd);
QObject::connect(button, &QPushButton::clicked, [=] { QObject::connect(button, &QPushButton::clicked, [=, this] {
this->selectColor(button->color(), false); this->selectColor(button->color(), false);
}); });
@ -260,7 +261,7 @@ void ColorPickerDialog::initDefaultColors(LayoutCreator<QWidget> &creator)
grid->addWidget(button, rowInd, columnInd); grid->addWidget(button, rowInd, columnInd);
QObject::connect(button, &QPushButton::clicked, [=] { QObject::connect(button, &QPushButton::clicked, [=, this] {
this->selectColor(button->color(), false); this->selectColor(button->color(), false);
}); });
@ -299,7 +300,7 @@ void ColorPickerDialog::initColorPicker(LayoutCreator<QWidget> &creator)
QObject::connect( QObject::connect(
luminancePicker, &QColorLuminancePicker::newHsv, luminancePicker, &QColorLuminancePicker::newHsv,
[=](int h, int s, int v) { [this](int h, int s, int v) {
int alpha = this->ui_.picker.spinBoxes[SpinBox::ALPHA]->value(); int alpha = this->ui_.picker.spinBoxes[SpinBox::ALPHA]->value();
this->selectColor(QColor::fromHsv(h, s, v, alpha), true); this->selectColor(QColor::fromHsv(h, s, v, alpha), true);
}); });
@ -344,7 +345,7 @@ void ColorPickerDialog::initSpinBoxes(LayoutCreator<QWidget> &creator)
{ {
QObject::connect( QObject::connect(
this->ui_.picker.spinBoxes[i], this->ui_.picker.spinBoxes[i],
QOverload<int>::of(&QSpinBox::valueChanged), [=](int value) { QOverload<int>::of(&QSpinBox::valueChanged), [=, this](int value) {
this->selectColor(QColor(red->value(), green->value(), this->selectColor(QColor(red->value(), green->value(),
blue->value(), alpha->value()), blue->value(), alpha->value()),
false); false);

View file

@ -177,16 +177,16 @@ AdvancedLoginWidget::AdvancedLoginWidget()
this->ui_.oauthTokenInput.setEchoMode(QLineEdit::Password); this->ui_.oauthTokenInput.setEchoMode(QLineEdit::Password);
connect(&this->ui_.userIDInput, &QLineEdit::textChanged, [=]() { connect(&this->ui_.userIDInput, &QLineEdit::textChanged, [this]() {
this->refreshButtons(); this->refreshButtons();
}); });
connect(&this->ui_.usernameInput, &QLineEdit::textChanged, [=]() { connect(&this->ui_.usernameInput, &QLineEdit::textChanged, [this]() {
this->refreshButtons(); this->refreshButtons();
}); });
connect(&this->ui_.clientIDInput, &QLineEdit::textChanged, [=]() { connect(&this->ui_.clientIDInput, &QLineEdit::textChanged, [this]() {
this->refreshButtons(); this->refreshButtons();
}); });
connect(&this->ui_.oauthTokenInput, &QLineEdit::textChanged, [=]() { connect(&this->ui_.oauthTokenInput, &QLineEdit::textChanged, [this]() {
this->refreshButtons(); this->refreshButtons();
}); });
@ -201,21 +201,22 @@ AdvancedLoginWidget::AdvancedLoginWidget()
&this->ui_.buttonUpperRow.clearFieldsButton); &this->ui_.buttonUpperRow.clearFieldsButton);
connect(&this->ui_.buttonUpperRow.clearFieldsButton, &QPushButton::clicked, connect(&this->ui_.buttonUpperRow.clearFieldsButton, &QPushButton::clicked,
[=]() { [this]() {
this->ui_.userIDInput.clear(); this->ui_.userIDInput.clear();
this->ui_.usernameInput.clear(); this->ui_.usernameInput.clear();
this->ui_.clientIDInput.clear(); this->ui_.clientIDInput.clear();
this->ui_.oauthTokenInput.clear(); this->ui_.oauthTokenInput.clear();
}); });
connect( connect(&this->ui_.buttonUpperRow.addUserButton, &QPushButton::clicked,
&this->ui_.buttonUpperRow.addUserButton, &QPushButton::clicked, [=]() { [this]() {
QString userID = this->ui_.userIDInput.text(); QString userID = this->ui_.userIDInput.text();
QString username = this->ui_.usernameInput.text(); QString username = this->ui_.usernameInput.text();
QString clientID = this->ui_.clientIDInput.text(); QString clientID = this->ui_.clientIDInput.text();
QString oauthToken = this->ui_.oauthTokenInput.text(); QString oauthToken = this->ui_.oauthTokenInput.text();
logInWithCredentials(this, userID, username, clientID, oauthToken); logInWithCredentials(this, userID, username, clientID,
oauthToken);
}); });
} }

View file

@ -223,11 +223,12 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
layout.emplace<QHBoxLayout>().emplace<QDialogButtonBox>(this); layout.emplace<QHBoxLayout>().emplace<QDialogButtonBox>(this);
{ {
auto *button_ok = buttons->addButton(QDialogButtonBox::Ok); auto *button_ok = buttons->addButton(QDialogButtonBox::Ok);
QObject::connect(button_ok, &QPushButton::clicked, [=](bool) { QObject::connect(button_ok, &QPushButton::clicked, [this](bool) {
this->ok(); this->ok();
}); });
auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel); auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel);
QObject::connect(button_cancel, &QAbstractButton::clicked, [=](bool) { QObject::connect(button_cancel, &QAbstractButton::clicked,
[this](bool) {
this->close(); this->close();
}); });
} }

View file

@ -919,7 +919,7 @@ void UserInfoPopup::loadAvatar(const QUrl &url)
static auto manager = new QNetworkAccessManager(); static auto manager = new QNetworkAccessManager();
auto *reply = manager->get(req); auto *reply = manager->get(req);
QObject::connect(reply, &QNetworkReply::finished, this, [=] { QObject::connect(reply, &QNetworkReply::finished, this, [=, this] {
if (reply->error() == QNetworkReply::NoError) if (reply->error() == QNetworkReply::NoError)
{ {
const auto data = reply->readAll(); const auto data = reply->readAll();

View file

@ -206,8 +206,9 @@ void ChannelView::initializeLayout()
this->goToBottom_->getLabel().setText("More messages below"); this->goToBottom_->getLabel().setText("More messages below");
this->goToBottom_->setVisible(false); this->goToBottom_->setVisible(false);
QObject::connect(this->goToBottom_, &EffectLabel::leftClicked, this, [=] { QObject::connect(
QTimer::singleShot(180, [=] { this->goToBottom_, &EffectLabel::leftClicked, this, [this] {
QTimer::singleShot(180, [this] {
this->scrollBar_->scrollToBottom( this->scrollBar_->scrollToBottom(
getSettings()->enableSmoothScrollingNewMessages.getValue()); getSettings()->enableSmoothScrollingNewMessages.getValue());
}); });

View file

@ -89,7 +89,7 @@ NotebookTab::NotebookTab(Notebook *notebook)
this->menu_.addAction( this->menu_.addAction(
"Close Tab", "Close Tab",
[=]() { [this]() {
this->notebook_->removePage(this->page); this->notebook_->removePage(this->page);
}, },
getApp()->hotkeys->getDisplaySequence(HotkeyCategory::Window, getApp()->hotkeys->getDisplaySequence(HotkeyCategory::Window,
@ -97,7 +97,7 @@ NotebookTab::NotebookTab(Notebook *notebook)
this->menu_.addAction( this->menu_.addAction(
"Popup Tab", "Popup Tab",
[=]() { [this]() {
if (auto container = dynamic_cast<SplitContainer *>(this->page)) if (auto container = dynamic_cast<SplitContainer *>(this->page))
{ {
container->popup(); container->popup();

View file

@ -39,7 +39,7 @@ GeneralPageView::GeneralPageView(QWidget *parent)
{scrollArea, new QSpacerItem(16, 1), navigation})); {scrollArea, new QSpacerItem(16, 1), navigation}));
QObject::connect(scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, QObject::connect(scrollArea->verticalScrollBar(), &QScrollBar::valueChanged,
this, [=] { this, [this] {
this->updateNavigationHighlighting(); this->updateNavigationHighlighting();
}); });
} }
@ -74,7 +74,7 @@ TitleLabel *GeneralPageView::addTitle(const QString &title)
navLabel->setCursor(Qt::PointingHandCursor); navLabel->setCursor(Qt::PointingHandCursor);
this->navigationLayout_->addWidget(navLabel); this->navigationLayout_->addWidget(navLabel);
QObject::connect(navLabel, &NavigationLabel::leftMouseUp, label, [=] { QObject::connect(navLabel, &NavigationLabel::leftMouseUp, label, [=, this] {
this->contentScrollArea_->verticalScrollBar()->setValue(label->y()); this->contentScrollArea_->verticalScrollBar()->setValue(label->y());
}); });

View file

@ -269,7 +269,7 @@ HighlightingPage::HighlightingPage()
auto selectFile = customSound.emplace<QPushButton>("Change..."); auto selectFile = customSound.emplace<QPushButton>("Change...");
QObject::connect(selectFile.getElement(), &QPushButton::clicked, QObject::connect(selectFile.getElement(), &QPushButton::clicked,
this, [=]() mutable { this, [this]() mutable {
auto fileName = QFileDialog::getOpenFileName( auto fileName = QFileDialog::getOpenFileName(
this, tr("Open Sound"), "", this, tr("Open Sound"), "",
tr("Audio Files (*.mp3 *.wav)")); tr("Audio Files (*.mp3 *.wav)"));

View file

@ -213,7 +213,7 @@ void ModerationPage::addModerationButtonSettings(
texts->setContentsMargins(0, 0, 0, 15); texts->setContentsMargins(0, 0, 0, 15);
texts->setSizeConstraint(QLayout::SetMaximumSize); texts->setSizeConstraint(QLayout::SetMaximumSize);
const auto valueChanged = [=] { const auto valueChanged = [=, this] {
const auto index = QObject::sender()->objectName().toInt(); const auto index = QObject::sender()->objectName().toInt();
const auto line = this->durationInputs_[index]; const auto line = this->durationInputs_[index];

View file

@ -157,7 +157,7 @@ Split::Split(QWidget *parent)
} }
}); });
this->input_->textChanged.connect([=](const QString &newText) { this->input_->textChanged.connect([this](const QString &newText) {
if (getSettings()->showEmptyInput) if (getSettings()->showEmptyInput)
{ {
// We always show the input regardless of the text, so we can early out here // We always show the input regardless of the text, so we can early out here
@ -754,7 +754,7 @@ void Split::showChangeChannelPopup(const char *dialogTitle, bool empty,
dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle(dialogTitle); dialog->setWindowTitle(dialogTitle);
dialog->show(); dialog->show();
dialog->closed.connect([=] { dialog->closed.connect([=, this] {
if (dialog->hasSeletedChannel()) if (dialog->hasSeletedChannel())
{ {
this->setChannel(dialog->getSelectedChannel()); this->setChannel(dialog->getSelectedChannel());
@ -1030,7 +1030,7 @@ void Split::showViewerList()
NetworkRequest::twitchRequest("https://tmi.twitch.tv/group/user/" + NetworkRequest::twitchRequest("https://tmi.twitch.tv/group/user/" +
this->getChannel()->getName() + "/chatters") this->getChannel()->getName() + "/chatters")
.caller(this) .caller(this)
.onSuccess([=](auto result) -> Outcome { .onSuccess([=, this](auto result) -> Outcome {
auto obj = result.parseJson(); auto obj = result.parseJson();
QJsonObject chattersObj = obj.value("chatters").toObject(); QJsonObject chattersObj = obj.value("chatters").toObject();

View file

@ -125,7 +125,7 @@ Split *SplitContainer::appendNewSplit(bool openChannelNameDialog)
if (openChannelNameDialog) if (openChannelNameDialog)
{ {
split->showChangeChannelPopup("Open channel", true, [=](bool ok) { split->showChangeChannelPopup("Open channel", true, [=, this](bool ok) {
if (!ok) if (!ok)
{ {
this->deleteSplit(split); this->deleteSplit(split);
@ -1242,7 +1242,7 @@ void SplitContainer::Node::layout(bool addSpacing, float _scale,
0.0001, this->getChildrensTotalFlex(isVertical)); 0.0001, this->getChildrensTotalFlex(isVertical));
qreal totalSize = std::accumulate( qreal totalSize = std::accumulate(
this->children_.begin(), this->children_.end(), qreal(0), this->children_.begin(), this->children_.end(), qreal(0),
[=](int val, std::unique_ptr<Node> &node) { [=, this](int val, std::unique_ptr<Node> &node) {
return val + std::max<qreal>( return val + std::max<qreal>(
this->getSize(isVertical) / this->getSize(isVertical) /
std::max<qreal>(0.0001, totalFlex) * std::max<qreal>(0.0001, totalFlex) *

View file

@ -137,7 +137,8 @@ void SplitInput::initLayout()
QObject::connect(this->ui_.textEdit, &QTextEdit::textChanged, this, QObject::connect(this->ui_.textEdit, &QTextEdit::textChanged, this,
&SplitInput::onTextChanged); &SplitInput::onTextChanged);
this->managedConnections_.managedConnect(app->fonts->fontChanged, [=]() { this->managedConnections_.managedConnect(
app->fonts->fontChanged, [=, this]() {
this->ui_.textEdit->setFont( this->ui_.textEdit->setFont(
app->fonts->getFont(FontStyle::ChatMedium, this->scale())); app->fonts->getFont(FontStyle::ChatMedium, this->scale()));
this->ui_.replyLabel->setFont( this->ui_.replyLabel->setFont(
@ -145,13 +146,13 @@ void SplitInput::initLayout()
}); });
// open emote popup // open emote popup
QObject::connect(this->ui_.emoteButton, &EffectLabel::leftClicked, [=] { QObject::connect(this->ui_.emoteButton, &EffectLabel::leftClicked, [this] {
this->openEmotePopup(); this->openEmotePopup();
}); });
// clear input and remove reply thread // clear input and remove reply thread
QObject::connect(this->ui_.cancelReplyButton, &EffectLabel::leftClicked, QObject::connect(this->ui_.cancelReplyButton, &EffectLabel::leftClicked,
[=] { [this] {
this->clearInput(); this->clearInput();
}); });