From 851858688c51359c75d063abc346a6346d8d6615 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 23 Dec 2022 09:24:59 +0100 Subject: [PATCH 01/10] feat: c++ 20 --- CMakeLists.txt | 4 ++-- src/messages/LimitedQueue.hpp | 2 +- src/messages/layouts/MessageLayout.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9e5688713f..46a7ecb364f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.12) cmake_policy(SET CMP0087 NEW) include(FeatureSummary) @@ -143,7 +143,7 @@ else() add_subdirectory("${CMAKE_SOURCE_DIR}/lib/settings" EXCLUDE_FROM_ALL) endif() -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (BUILD_TESTS OR BUILD_BENCHMARKS) diff --git a/src/messages/LimitedQueue.hpp b/src/messages/LimitedQueue.hpp index 8c419e184f2..6918919064c 100644 --- a/src/messages/LimitedQueue.hpp +++ b/src/messages/LimitedQueue.hpp @@ -167,7 +167,7 @@ class LimitedQueue { std::unique_lock lock(this->mutex_); - size_t numToPush = std::min(items.size(), this->space()); + size_t numToPush = (std::min)(items.size(), this->space()); std::vector pushed; pushed.reserve(numToPush); diff --git a/src/messages/layouts/MessageLayout.cpp b/src/messages/layouts/MessageLayout.cpp index e744809872c..902e7ede055 100644 --- a/src/messages/layouts/MessageLayout.cpp +++ b/src/messages/layouts/MessageLayout.cpp @@ -273,7 +273,7 @@ void MessageLayout::paint(QPainter &painter, int width, int y, int messageIndex, if (isLastReadMessage) { QColor color; - if (getSettings()->lastMessageColor != "") + if (getSettings()->lastMessageColor != QStringLiteral("")) { color = QColor(getSettings()->lastMessageColor.getValue()); } From fdcf799c1dfbf2cf69c930fa07b5684ce73f5ca7 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 23 Dec 2022 10:52:36 +0100 Subject: [PATCH 02/10] fix: c++ 20 deprecations --- src/Application.cpp | 4 +-- src/common/CompletionModel.cpp | 2 +- .../notifications/NotificationController.cpp | 2 +- src/messages/LimitedQueue.hpp | 2 +- .../liveupdates/BasicPubSubManager.hpp | 4 +-- src/providers/twitch/IrcMessageHandler.cpp | 2 +- src/providers/twitch/PubSubManager.cpp | 2 +- src/providers/twitch/TwitchChannel.cpp | 10 +++---- src/providers/twitch/TwitchIrcServer.cpp | 2 +- src/providers/twitch/api/Helix.cpp | 8 +++--- src/widgets/AccountSwitchWidget.cpp | 4 +-- src/widgets/Window.cpp | 4 +-- src/widgets/dialogs/BadgePickerDialog.cpp | 2 +- src/widgets/dialogs/ColorPickerDialog.cpp | 17 ++++++------ src/widgets/dialogs/LoginDialog.cpp | 27 ++++++++++--------- src/widgets/dialogs/SelectChannelDialog.cpp | 9 ++++--- src/widgets/dialogs/UserInfoPopup.cpp | 2 +- src/widgets/helper/ChannelView.cpp | 11 ++++---- src/widgets/helper/NotebookTab.cpp | 4 +-- src/widgets/settingspages/GeneralPageView.cpp | 4 +-- .../settingspages/HighlightingPage.cpp | 2 +- src/widgets/settingspages/ModerationPage.cpp | 2 +- src/widgets/splits/Split.cpp | 6 ++--- src/widgets/splits/SplitContainer.cpp | 4 +-- src/widgets/splits/SplitInput.cpp | 17 ++++++------ 25 files changed, 79 insertions(+), 74 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 7e6dc2b69e6..fa2fdd50578 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -551,7 +551,7 @@ void Application::initPubSub() this->twitch->pubsub->start(); - auto RequestModerationActions = [=]() { + auto RequestModerationActions = [this]() { this->twitch->pubsub->setAccount( getApp()->accounts->twitch.getCurrent()); // TODO(pajlada): Unlisten to all authed topics instead of only @@ -561,7 +561,7 @@ void Application::initPubSub() }; this->accounts->twitch.currentUserChanged.connect( - [=] { + [this] { this->twitch->pubsub->unlistenAllModerationActions(); this->twitch->pubsub->unlistenAutomod(); this->twitch->pubsub->unlistenWhispers(); diff --git a/src/common/CompletionModel.cpp b/src/common/CompletionModel.cpp index f246c69ebfe..0c76dc91d86 100644 --- a/src/common/CompletionModel.cpp +++ b/src/common/CompletionModel.cpp @@ -94,7 +94,7 @@ void CompletionModel::refresh(const QString &prefix, bool isFirstWord) // Twitch channel auto *tc = dynamic_cast(&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 if (type == TaggedString::TwitchCommand) { diff --git a/src/controllers/notifications/NotificationController.cpp b/src/controllers/notifications/NotificationController.cpp index 79aef372d26..8fd5ea540f2 100644 --- a/src/controllers/notifications/NotificationController.cpp +++ b/src/controllers/notifications/NotificationController.cpp @@ -42,7 +42,7 @@ void NotificationController::initialize(Settings &settings, Paths &paths) this->fetchFakeChannels(); - QObject::connect(this->liveStatusTimer_, &QTimer::timeout, [=] { + QObject::connect(this->liveStatusTimer_, &QTimer::timeout, [this] { this->fetchFakeChannels(); }); this->liveStatusTimer_->start(60 * 1000); diff --git a/src/messages/LimitedQueue.hpp b/src/messages/LimitedQueue.hpp index 6918919064c..8c419e184f2 100644 --- a/src/messages/LimitedQueue.hpp +++ b/src/messages/LimitedQueue.hpp @@ -167,7 +167,7 @@ class LimitedQueue { std::unique_lock lock(this->mutex_); - size_t numToPush = (std::min)(items.size(), this->space()); + size_t numToPush = std::min(items.size(), this->space()); std::vector pushed; pushed.reserve(numToPush); diff --git a/src/providers/liveupdates/BasicPubSubManager.hpp b/src/providers/liveupdates/BasicPubSubManager.hpp index dce963575e4..f849eefda09 100644 --- a/src/providers/liveupdates/BasicPubSubManager.hpp +++ b/src/providers/liveupdates/BasicPubSubManager.hpp @@ -204,8 +204,8 @@ class BasicPubSubManager this->clients_.emplace(hdl, client); - auto pendingSubsToTake = (std::min)(this->pendingSubscriptions_.size(), - client->maxSubscriptions); + auto pendingSubsToTake = std::min(this->pendingSubscriptions_.size(), + client->maxSubscriptions); qCDebug(chatterinoLiveupdates) << "LiveUpdate connection opened, subscribing to" diff --git a/src/providers/twitch/IrcMessageHandler.cpp b/src/providers/twitch/IrcMessageHandler.cpp index 8edd3ade6f0..d412a249b42 100644 --- a/src/providers/twitch/IrcMessageHandler.cpp +++ b/src/providers/twitch/IrcMessageHandler.cpp @@ -464,7 +464,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *_message, "callback since reward is not known:" << rewardId; channel->channelPointRewardAdded.connect( - [=, &server](ChannelPointReward reward) { + [=, this, &server](ChannelPointReward reward) { qCDebug(chatterinoTwitch) << "TwitchChannel reward added callback:" << reward.id << "-" << rewardId; diff --git a/src/providers/twitch/PubSubManager.cpp b/src/providers/twitch/PubSubManager.cpp index 8909663f175..52a25938e4b 100644 --- a/src/providers/twitch/PubSubManager.cpp +++ b/src/providers/twitch/PubSubManager.cpp @@ -829,7 +829,7 @@ void PubSub::onConnectionOpen(WebsocketHandle hdl) qCDebug(chatterinoPubSub) << "PubSub connection opened!"; const auto topicsToTake = - (std::min)(this->requests.size(), PubSubClient::MAX_LISTENS); + std::min(this->requests.size(), PubSubClient::MAX_LISTENS); std::vector newTopics( std::make_move_iterator(this->requests.begin()), diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index c16315ac6fd..dcb67095afb 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -38,7 +38,7 @@ namespace chatterino { namespace { - constexpr char MAGIC_MESSAGE_SUFFIX[] = u8" \U000E0000"; + constexpr char8_t MAGIC_MESSAGE_SUFFIX[] = u8" \U000E0000"; constexpr int TITLE_REFRESH_PERIOD = 10000; constexpr int CLIP_CREATION_COOLDOWN = 5000; const QString CLIPS_LINK("https://clips.twitch.tv/%1"); @@ -72,7 +72,7 @@ TwitchChannel::TwitchChannel(const QString &name) qCDebug(chatterinoTwitch) << "[TwitchChannel" << name << "] Opened"; this->bSignals_.emplace_back( - getApp()->accounts->twitch.currentUserChanged.connect([=] { + getApp()->accounts->twitch.currentUserChanged.connect([this] { this->setMod(false); this->refreshPubSub(); })); @@ -124,13 +124,13 @@ TwitchChannel::TwitchChannel(const QString &name) // timers - QObject::connect(&this->chattersListTimer_, &QTimer::timeout, [=] { + QObject::connect(&this->chattersListTimer_, &QTimer::timeout, [this] { this->refreshChatters(); }); 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 // being cleaned up on messageRemovedFromStart. This could occur if // some other part of the program, like a user card, held a reference @@ -367,7 +367,7 @@ QString TwitchChannel::prepareMessage(const QString &message) const if (spaceIndex == -1) { // no spaces found, fall back to old magic character - parsedMessage.append(MAGIC_MESSAGE_SUFFIX); + parsedMessage.append((const char *)MAGIC_MESSAGE_SUFFIX); } else { diff --git a/src/providers/twitch/TwitchIrcServer.cpp b/src/providers/twitch/TwitchIrcServer.cpp index 7dd704a5cc6..04053400996 100644 --- a/src/providers/twitch/TwitchIrcServer.cpp +++ b/src/providers/twitch/TwitchIrcServer.cpp @@ -71,7 +71,7 @@ void TwitchIrcServer::initialize(Settings &settings, Paths &paths) this->reloadSevenTVGlobalEmotes(); /* 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->bulkLiveStatusTimer_.start(30 * 1000); diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index fcad454598c..0b816f8db5d 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -1815,7 +1815,7 @@ void Helix::onFetchChattersSuccess( this->fetchChatters( broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, chatters.cursor, - [=](auto chatters) { + [=, this](auto chatters) { this->onFetchChattersSuccess( finalChatters, broadcasterID, moderatorID, maxChattersToFetch, successCallback, failureCallback, chatters); @@ -1925,7 +1925,7 @@ void Helix::onFetchModeratorsSuccess( this->fetchModerators( broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, moderators.cursor, - [=](auto moderators) { + [=, this](auto moderators) { this->onFetchModeratorsSuccess( finalModerators, broadcasterID, maxModeratorsToFetch, successCallback, failureCallback, moderators); @@ -2236,7 +2236,7 @@ void Helix::getChatters( // Initiate the recursive calls this->fetchChatters( broadcasterID, moderatorID, NUM_CHATTERS_TO_FETCH, "", - [=](auto chatters) { + [=, this](auto chatters) { this->onFetchChattersSuccess( finalChatters, broadcasterID, moderatorID, maxChattersToFetch, successCallback, failureCallback, chatters); @@ -2255,7 +2255,7 @@ void Helix::getModerators( // Initiate the recursive calls this->fetchModerators( broadcasterID, NUM_MODERATORS_TO_FETCH_PER_REQUEST, "", - [=](auto moderators) { + [=, this](auto moderators) { this->onFetchModeratorsSuccess( finalModerators, broadcasterID, maxModeratorsToFetch, successCallback, failureCallback, moderators); diff --git a/src/widgets/AccountSwitchWidget.cpp b/src/widgets/AccountSwitchWidget.cpp index b7a5eefc96f..21afb7be2c2 100644 --- a/src/widgets/AccountSwitchWidget.cpp +++ b/src/widgets/AccountSwitchWidget.cpp @@ -20,7 +20,7 @@ AccountSwitchWidget::AccountSwitchWidget(QWidget *parent) this->addItem(userName); } - app->accounts->twitch.userListUpdated.connect([=]() { + app->accounts->twitch.userListUpdated.connect([=, this]() { this->blockSignals(true); this->clear(); @@ -39,7 +39,7 @@ AccountSwitchWidget::AccountSwitchWidget(QWidget *parent) this->refreshSelection(); - QObject::connect(this, &QListWidget::clicked, [=] { + QObject::connect(this, &QListWidget::clicked, [=, this] { if (!this->selectedItems().isEmpty()) { QString newUsername = this->currentItem()->text(); diff --git a/src/widgets/Window.cpp b/src/widgets/Window.cpp index fa3cb6f52f4..e1a0c44c9e5 100644 --- a/src/widgets/Window.cpp +++ b/src/widgets/Window.cpp @@ -641,13 +641,13 @@ void Window::addMenuBar() QAction *nextTab = windowMenu->addAction(QString("Select next tab")); nextTab->setShortcuts({QKeySequence("Meta+Tab")}); - connect(nextTab, &QAction::triggered, this, [=] { + connect(nextTab, &QAction::triggered, this, [this] { this->notebook_->selectNextTab(); }); QAction *prevTab = windowMenu->addAction(QString("Select previous tab")); prevTab->setShortcuts({QKeySequence("Meta+Shift+Tab")}); - connect(prevTab, &QAction::triggered, this, [=] { + connect(prevTab, &QAction::triggered, this, [this] { this->notebook_->selectPreviousTab(); }); } diff --git a/src/widgets/dialogs/BadgePickerDialog.cpp b/src/widgets/dialogs/BadgePickerDialog.cpp index 16e90040448..e4bd4e3cc13 100644 --- a/src/widgets/dialogs/BadgePickerDialog.cpp +++ b/src/widgets/dialogs/BadgePickerDialog.cpp @@ -42,7 +42,7 @@ BadgePickerDialog::BadgePickerDialog(QList badges, this->dropdown_->addItem(item.displayName(), item.badgeName()); } - const auto updateBadge = [=](int index) { + const auto updateBadge = [=, this](int index) { BadgeOpt badge; if (index >= 0 && index < badges.size()) { diff --git a/src/widgets/dialogs/ColorPickerDialog.cpp b/src/widgets/dialogs/ColorPickerDialog.cpp index 9237f2c329e..4eebac79fb1 100644 --- a/src/widgets/dialogs/ColorPickerDialog.cpp +++ b/src/widgets/dialogs/ColorPickerDialog.cpp @@ -94,13 +94,14 @@ ColorPickerDialog::ColorPickerDialog(const QColor &initial, QWidget *parent) layout.emplace().emplace(this); { auto *button_ok = buttons->addButton(QDialogButtonBox::Ok); - QObject::connect(button_ok, &QPushButton::clicked, [=](bool) { + QObject::connect(button_ok, &QPushButton::clicked, [this](bool) { this->ok(); }); auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel); - QObject::connect(button_cancel, &QAbstractButton::clicked, [=](bool) { - this->close(); - }); + QObject::connect(button_cancel, &QAbstractButton::clicked, + [this](bool) { + this->close(); + }); } this->themeChangedEvent(); @@ -226,7 +227,7 @@ void ColorPickerDialog::initRecentColors(LayoutCreator &creator) grid->addWidget(button, rowInd, columnInd); - QObject::connect(button, &QPushButton::clicked, [=] { + QObject::connect(button, &QPushButton::clicked, [=, this] { this->selectColor(button->color(), false); }); @@ -260,7 +261,7 @@ void ColorPickerDialog::initDefaultColors(LayoutCreator &creator) grid->addWidget(button, rowInd, columnInd); - QObject::connect(button, &QPushButton::clicked, [=] { + QObject::connect(button, &QPushButton::clicked, [=, this] { this->selectColor(button->color(), false); }); @@ -299,7 +300,7 @@ void ColorPickerDialog::initColorPicker(LayoutCreator &creator) QObject::connect( 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(); this->selectColor(QColor::fromHsv(h, s, v, alpha), true); }); @@ -344,7 +345,7 @@ void ColorPickerDialog::initSpinBoxes(LayoutCreator &creator) { QObject::connect( this->ui_.picker.spinBoxes[i], - QOverload::of(&QSpinBox::valueChanged), [=](int value) { + QOverload::of(&QSpinBox::valueChanged), [=, this](int value) { this->selectColor(QColor(red->value(), green->value(), blue->value(), alpha->value()), false); diff --git a/src/widgets/dialogs/LoginDialog.cpp b/src/widgets/dialogs/LoginDialog.cpp index eb26ac26383..18b3acf80cf 100644 --- a/src/widgets/dialogs/LoginDialog.cpp +++ b/src/widgets/dialogs/LoginDialog.cpp @@ -177,16 +177,16 @@ AdvancedLoginWidget::AdvancedLoginWidget() this->ui_.oauthTokenInput.setEchoMode(QLineEdit::Password); - connect(&this->ui_.userIDInput, &QLineEdit::textChanged, [=]() { + connect(&this->ui_.userIDInput, &QLineEdit::textChanged, [this]() { this->refreshButtons(); }); - connect(&this->ui_.usernameInput, &QLineEdit::textChanged, [=]() { + connect(&this->ui_.usernameInput, &QLineEdit::textChanged, [this]() { this->refreshButtons(); }); - connect(&this->ui_.clientIDInput, &QLineEdit::textChanged, [=]() { + connect(&this->ui_.clientIDInput, &QLineEdit::textChanged, [this]() { this->refreshButtons(); }); - connect(&this->ui_.oauthTokenInput, &QLineEdit::textChanged, [=]() { + connect(&this->ui_.oauthTokenInput, &QLineEdit::textChanged, [this]() { this->refreshButtons(); }); @@ -201,22 +201,23 @@ AdvancedLoginWidget::AdvancedLoginWidget() &this->ui_.buttonUpperRow.clearFieldsButton); connect(&this->ui_.buttonUpperRow.clearFieldsButton, &QPushButton::clicked, - [=]() { + [this]() { this->ui_.userIDInput.clear(); this->ui_.usernameInput.clear(); this->ui_.clientIDInput.clear(); this->ui_.oauthTokenInput.clear(); }); - connect( - &this->ui_.buttonUpperRow.addUserButton, &QPushButton::clicked, [=]() { - QString userID = this->ui_.userIDInput.text(); - QString username = this->ui_.usernameInput.text(); - QString clientID = this->ui_.clientIDInput.text(); - QString oauthToken = this->ui_.oauthTokenInput.text(); + connect(&this->ui_.buttonUpperRow.addUserButton, &QPushButton::clicked, + [this]() { + QString userID = this->ui_.userIDInput.text(); + QString username = this->ui_.usernameInput.text(); + QString clientID = this->ui_.clientIDInput.text(); + QString oauthToken = this->ui_.oauthTokenInput.text(); - logInWithCredentials(this, userID, username, clientID, oauthToken); - }); + logInWithCredentials(this, userID, username, clientID, + oauthToken); + }); } void AdvancedLoginWidget::refreshButtons() diff --git a/src/widgets/dialogs/SelectChannelDialog.cpp b/src/widgets/dialogs/SelectChannelDialog.cpp index 0d6cbc40794..0fb754292b9 100644 --- a/src/widgets/dialogs/SelectChannelDialog.cpp +++ b/src/widgets/dialogs/SelectChannelDialog.cpp @@ -223,13 +223,14 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent) layout.emplace().emplace(this); { auto *button_ok = buttons->addButton(QDialogButtonBox::Ok); - QObject::connect(button_ok, &QPushButton::clicked, [=](bool) { + QObject::connect(button_ok, &QPushButton::clicked, [this](bool) { this->ok(); }); auto *button_cancel = buttons->addButton(QDialogButtonBox::Cancel); - QObject::connect(button_cancel, &QAbstractButton::clicked, [=](bool) { - this->close(); - }); + QObject::connect(button_cancel, &QAbstractButton::clicked, + [this](bool) { + this->close(); + }); } this->setMinimumSize(300, 310); diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index df34dc6020d..808c0503ab0 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -919,7 +919,7 @@ void UserInfoPopup::loadAvatar(const QUrl &url) static auto manager = new QNetworkAccessManager(); auto *reply = manager->get(req); - QObject::connect(reply, &QNetworkReply::finished, this, [=] { + QObject::connect(reply, &QNetworkReply::finished, this, [=, this] { if (reply->error() == QNetworkReply::NoError) { const auto data = reply->readAll(); diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 14746c72759..031268ddfe0 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -206,12 +206,13 @@ void ChannelView::initializeLayout() this->goToBottom_->getLabel().setText("More messages below"); this->goToBottom_->setVisible(false); - QObject::connect(this->goToBottom_, &EffectLabel::leftClicked, this, [=] { - QTimer::singleShot(180, [=] { - this->scrollBar_->scrollToBottom( - getSettings()->enableSmoothScrollingNewMessages.getValue()); + QObject::connect( + this->goToBottom_, &EffectLabel::leftClicked, this, [this] { + QTimer::singleShot(180, [this] { + this->scrollBar_->scrollToBottom( + getSettings()->enableSmoothScrollingNewMessages.getValue()); + }); }); - }); } void ChannelView::initializeScrollbar() diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index 732da815988..2eef532a63b 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -89,7 +89,7 @@ NotebookTab::NotebookTab(Notebook *notebook) this->menu_.addAction( "Close Tab", - [=]() { + [this]() { this->notebook_->removePage(this->page); }, getApp()->hotkeys->getDisplaySequence(HotkeyCategory::Window, @@ -97,7 +97,7 @@ NotebookTab::NotebookTab(Notebook *notebook) this->menu_.addAction( "Popup Tab", - [=]() { + [this]() { if (auto container = dynamic_cast(this->page)) { container->popup(); diff --git a/src/widgets/settingspages/GeneralPageView.cpp b/src/widgets/settingspages/GeneralPageView.cpp index ff2b5862341..70733b95364 100644 --- a/src/widgets/settingspages/GeneralPageView.cpp +++ b/src/widgets/settingspages/GeneralPageView.cpp @@ -39,7 +39,7 @@ GeneralPageView::GeneralPageView(QWidget *parent) {scrollArea, new QSpacerItem(16, 1), navigation})); QObject::connect(scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, - this, [=] { + this, [this] { this->updateNavigationHighlighting(); }); } @@ -74,7 +74,7 @@ TitleLabel *GeneralPageView::addTitle(const QString &title) navLabel->setCursor(Qt::PointingHandCursor); this->navigationLayout_->addWidget(navLabel); - QObject::connect(navLabel, &NavigationLabel::leftMouseUp, label, [=] { + QObject::connect(navLabel, &NavigationLabel::leftMouseUp, label, [=, this] { this->contentScrollArea_->verticalScrollBar()->setValue(label->y()); }); diff --git a/src/widgets/settingspages/HighlightingPage.cpp b/src/widgets/settingspages/HighlightingPage.cpp index 846abeb35e7..e794eea33b2 100644 --- a/src/widgets/settingspages/HighlightingPage.cpp +++ b/src/widgets/settingspages/HighlightingPage.cpp @@ -269,7 +269,7 @@ HighlightingPage::HighlightingPage() auto selectFile = customSound.emplace("Change..."); QObject::connect(selectFile.getElement(), &QPushButton::clicked, - this, [=]() mutable { + this, [this]() mutable { auto fileName = QFileDialog::getOpenFileName( this, tr("Open Sound"), "", tr("Audio Files (*.mp3 *.wav)")); diff --git a/src/widgets/settingspages/ModerationPage.cpp b/src/widgets/settingspages/ModerationPage.cpp index 41b70f14c0f..074c7105f91 100644 --- a/src/widgets/settingspages/ModerationPage.cpp +++ b/src/widgets/settingspages/ModerationPage.cpp @@ -213,7 +213,7 @@ void ModerationPage::addModerationButtonSettings( texts->setContentsMargins(0, 0, 0, 15); texts->setSizeConstraint(QLayout::SetMaximumSize); - const auto valueChanged = [=] { + const auto valueChanged = [=, this] { const auto index = QObject::sender()->objectName().toInt(); const auto line = this->durationInputs_[index]; diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index bcf5c3b71f5..4f38943e271 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -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) { // 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->setWindowTitle(dialogTitle); dialog->show(); - dialog->closed.connect([=] { + dialog->closed.connect([=, this] { if (dialog->hasSeletedChannel()) { this->setChannel(dialog->getSelectedChannel()); @@ -1030,7 +1030,7 @@ void Split::showViewerList() NetworkRequest::twitchRequest("https://tmi.twitch.tv/group/user/" + this->getChannel()->getName() + "/chatters") .caller(this) - .onSuccess([=](auto result) -> Outcome { + .onSuccess([=, this](auto result) -> Outcome { auto obj = result.parseJson(); QJsonObject chattersObj = obj.value("chatters").toObject(); diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 9f72631f2ba..8b33b33bc0a 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -125,7 +125,7 @@ Split *SplitContainer::appendNewSplit(bool openChannelNameDialog) if (openChannelNameDialog) { - split->showChangeChannelPopup("Open channel", true, [=](bool ok) { + split->showChangeChannelPopup("Open channel", true, [=, this](bool ok) { if (!ok) { this->deleteSplit(split); @@ -1242,7 +1242,7 @@ void SplitContainer::Node::layout(bool addSpacing, float _scale, 0.0001, this->getChildrensTotalFlex(isVertical)); qreal totalSize = std::accumulate( this->children_.begin(), this->children_.end(), qreal(0), - [=](int val, std::unique_ptr &node) { + [=, this](int val, std::unique_ptr &node) { return val + std::max( this->getSize(isVertical) / std::max(0.0001, totalFlex) * diff --git a/src/widgets/splits/SplitInput.cpp b/src/widgets/splits/SplitInput.cpp index 58e0ddb3027..a9ef07174c2 100644 --- a/src/widgets/splits/SplitInput.cpp +++ b/src/widgets/splits/SplitInput.cpp @@ -137,21 +137,22 @@ void SplitInput::initLayout() QObject::connect(this->ui_.textEdit, &QTextEdit::textChanged, this, &SplitInput::onTextChanged); - this->managedConnections_.managedConnect(app->fonts->fontChanged, [=]() { - this->ui_.textEdit->setFont( - app->fonts->getFont(FontStyle::ChatMedium, this->scale())); - this->ui_.replyLabel->setFont( - app->fonts->getFont(FontStyle::ChatMediumBold, this->scale())); - }); + this->managedConnections_.managedConnect( + app->fonts->fontChanged, [=, this]() { + this->ui_.textEdit->setFont( + app->fonts->getFont(FontStyle::ChatMedium, this->scale())); + this->ui_.replyLabel->setFont( + app->fonts->getFont(FontStyle::ChatMediumBold, this->scale())); + }); // open emote popup - QObject::connect(this->ui_.emoteButton, &EffectLabel::leftClicked, [=] { + QObject::connect(this->ui_.emoteButton, &EffectLabel::leftClicked, [this] { this->openEmotePopup(); }); // clear input and remove reply thread QObject::connect(this->ui_.cancelReplyButton, &EffectLabel::leftClicked, - [=] { + [this] { this->clearInput(); }); From bcdf16500a89c946ff2dc38a00cdaec780830b7c Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 23 Dec 2022 10:53:46 +0100 Subject: [PATCH 03/10] fix(msvc): warnings --- src/CMakeLists.txt | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f7912f44e60..647a0c03aff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -788,28 +788,32 @@ if (MSVC) # Someone adds /W3 before we add /W4. # This makes sure, only /W4 is specified. string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # 4714 - function marked as __forceinline not inlined - # 4996 - occurs when the compiler encounters a function or variable that is marked as deprecated. - # These functions may have a different preferred name, may be insecure or have - # a more secure variant, or may be obsolete. - # 4505 - unreferenced local version has been removed - # 4127 - conditional expression is constant - # 4503 - decorated name length exceeded, name was truncated - # 4100 - unreferences formal parameter - # 4305 - possible truncation of data - # 4267 - possible loss of data in return + # 4505 - "unreferenced local version has been removed" + # Although this might give hints on dead code, + # there are some cases where it's distracting. + # + # 4100 - "unreferenced formal parameter" + # There are a lot of functions and methods where + # an argument was given a name but never used. + # There's a clang-tidy rule that will catch this + # for new/updated functions/methods. + # + # 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 - /W4 - # Disable the following warnings - /wd4714 - /wd4996 - /wd4505 - /wd4127 - /wd4503 - /wd4100 - /wd4305 - /wd4267 - ) + /W4 + # 5038 - warnings about initialization order + /w15038 + # 4855 - implicit capture of 'this' via '[=]' is deprecated + /w14855 + # Disable the following warnings (see reasoning above) + /wd4505 + /wd4100 + /wd4267 + ) + target_compile_definitions(${LIBRARY_PROJECT} PUBLIC NOMINMAX) else () target_compile_options(${LIBRARY_PROJECT} PUBLIC -Wall From 366a5628cc7f80a04316f4fa48973fab50eb599d Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 23 Dec 2022 11:24:03 +0100 Subject: [PATCH 04/10] chore: add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86424a62cd0..0cf3051bab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Bugfix: Fixed Reply window missing selection clear behaviour between chat and input box. (#4218) - Bugfix: Fixed crash that could occur when changing Tab layout and utilizing multiple windows. (#4248) - Dev: Ignore `WM_SHOWWINDOW` hide events, causing fewer attempted rescales. (#4198) +- Dev: Migrated to C++ 20 (#4252) ## 2.4.0 From 7b598e28ca5333fe84eb923ffcb5bed6ec719202 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 23 Dec 2022 11:50:06 +0100 Subject: [PATCH 05/10] fix: formatting --- src/CMakeLists.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 647a0c03aff..1e06f978bbf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -803,16 +803,16 @@ if (MSVC) # 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 - /W4 - # 5038 - warnings about initialization order - /w15038 - # 4855 - implicit capture of 'this' via '[=]' is deprecated - /w14855 - # Disable the following warnings (see reasoning above) - /wd4505 - /wd4100 - /wd4267 - ) + /W4 + # 5038 - warnings about initialization order + /w15038 + # 4855 - implicit capture of 'this' via '[=]' is deprecated + /w14855 + # Disable the following warnings (see reasoning above) + /wd4505 + /wd4100 + /wd4267 + ) target_compile_definitions(${LIBRARY_PROJECT} PUBLIC NOMINMAX) else () target_compile_options(${LIBRARY_PROJECT} PUBLIC From 8dad52b3647733d1c679ab3d5d1a7596314f7639 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 24 Dec 2022 11:14:27 +0100 Subject: [PATCH 06/10] Update websocketpp to the `develop` branch --- lib/websocketpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/websocketpp b/lib/websocketpp index 1b11fd30153..b9aeec6eaf3 160000 --- a/lib/websocketpp +++ b/lib/websocketpp @@ -1 +1 @@ -Subproject commit 1b11fd301531e6df35a6107c1e8665b1e77a2d8e +Subproject commit b9aeec6eaf3d5610503439b4fae3581d9aff08e8 From 1a8950e3721f6c92b04cd933bbff08660bff68ac Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 24 Dec 2022 11:15:16 +0100 Subject: [PATCH 07/10] Specify other template type in FlagsEnum != operator --- src/common/FlagsEnum.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/FlagsEnum.hpp b/src/common/FlagsEnum.hpp index c5d65e186b9..da309301572 100644 --- a/src/common/FlagsEnum.hpp +++ b/src/common/FlagsEnum.hpp @@ -32,7 +32,7 @@ class FlagsEnum return this->value_ == other.value_; } - bool operator!=(const FlagsEnum &other) + bool operator!=(const FlagsEnum &other) { return this->value_ != other.value_; } From caa3421043841a95f74598630e63cf67968ae40d Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 24 Dec 2022 11:15:31 +0100 Subject: [PATCH 08/10] 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 --- .../twitch/ChatterinoWebSocketppLogger.hpp | 231 +++++++++--------- 1 file changed, 112 insertions(+), 119 deletions(-) diff --git a/src/providers/twitch/ChatterinoWebSocketppLogger.hpp b/src/providers/twitch/ChatterinoWebSocketppLogger.hpp index d82e4307bac..c846affab00 100644 --- a/src/providers/twitch/ChatterinoWebSocketppLogger.hpp +++ b/src/providers/twitch/ChatterinoWebSocketppLogger.hpp @@ -25,8 +25,7 @@ * */ -#ifndef CHATTERINOWEBSOCKETPPLOGGER_HPP -#define CHATTERINOWEBSOCKETPPLOGGER_HPP +#pragma once #include "common/QLogging.hpp" @@ -36,166 +35,160 @@ #include -namespace websocketpp { -namespace log { +namespace websocketpp::log { - template - class chatterinowebsocketpplogger : public basic - { - public: - typedef chatterinowebsocketpplogger base; +template +class chatterinowebsocketpplogger : public basic +{ +public: + using base = chatterinowebsocketpplogger; - chatterinowebsocketpplogger( - channel_type_hint::value) - : m_static_channels(0xffffffff) - , m_dynamic_channels(0) - { - } + chatterinowebsocketpplogger(channel_type_hint::value) + : m_static_channels(0xffffffff) + , m_dynamic_channels(0) + { + } - chatterinowebsocketpplogger(std::ostream *) - : m_static_channels(0xffffffff) - , m_dynamic_channels(0) - { - } + chatterinowebsocketpplogger(std::ostream *) + : m_static_channels(0xffffffff) + , m_dynamic_channels(0) + { + } - chatterinowebsocketpplogger( - level c, channel_type_hint::value) - : m_static_channels(c) - , m_dynamic_channels(0) - { - } + chatterinowebsocketpplogger(level c, channel_type_hint::value) + : m_static_channels(c) + , m_dynamic_channels(0) + { + } - chatterinowebsocketpplogger(level c, std::ostream *) - : m_static_channels(c) - , m_dynamic_channels(0) - { - } + chatterinowebsocketpplogger(level c, std::ostream *) + : m_static_channels(c) + , m_dynamic_channels(0) + { + } - ~chatterinowebsocketpplogger() - { - } + ~chatterinowebsocketpplogger() + { + } - chatterinowebsocketpplogger( - chatterinowebsocketpplogger const &other) - : m_static_channels(other.m_static_channels) - , m_dynamic_channels(other.m_dynamic_channels) - { - } + chatterinowebsocketpplogger( + chatterinowebsocketpplogger const &other) + : m_static_channels(other.m_static_channels) + , m_dynamic_channels(other.m_dynamic_channels) + { + } #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ - chatterinowebsocketpplogger &operator=( - chatterinowebsocketpplogger const &) = delete; + chatterinowebsocketpplogger &operator=( + chatterinowebsocketpplogger const &) = delete; #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ - /// Move constructor - chatterinowebsocketpplogger( - chatterinowebsocketpplogger &&other) - : m_static_channels(other.m_static_channels) - , m_dynamic_channels(other.m_dynamic_channels) - { - } + /// Move constructor + chatterinowebsocketpplogger( + chatterinowebsocketpplogger &&other) + : m_static_channels(other.m_static_channels) + , m_dynamic_channels(other.m_dynamic_channels) + { + } # ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ - // no move assignment operator because of const member variables - chatterinowebsocketpplogger &operator=( - chatterinowebsocketpplogger &&) = delete; + // no move assignment operator because of const member variables + chatterinowebsocketpplogger &operator=( + chatterinowebsocketpplogger &&) = delete; # endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ #endif // _WEBSOCKETPP_MOVE_SEMANTICS_ - /// Explicitly do nothing, this logger doesn't support changing ostream - void set_ostream(std::ostream *) - { - } + /// Explicitly do nothing, this logger doesn't support changing ostream + void set_ostream(std::ostream *) + { + } - /// Dynamically enable the given list of channels - /** + /// Dynamically enable the given list of channels + /** * @param channels The package of channels to enable */ - void set_channels(level channels) + void set_channels(level channels) + { + if (channels == names::none) { - if (channels == names::none) - { - clear_channels(names::all); - return; - } - - scoped_lock_type lock(m_lock); - m_dynamic_channels |= (channels & m_static_channels); + clear_channels(names::all); + return; } - /// Dynamically disable the given list of channels - /** + scoped_lock_type lock(m_lock); + m_dynamic_channels |= (channels & m_static_channels); + } + + /// Dynamically disable the given list of channels + /** * @param channels The package of channels to disable */ - void clear_channels(level channels) - { - scoped_lock_type lock(m_lock); - m_dynamic_channels &= ~channels; - } + void clear_channels(level channels) + { + scoped_lock_type lock(m_lock); + m_dynamic_channels &= ~channels; + } - /// Write a string message to the given channel - /** + /// Write a string message to the given channel + /** * @param channel The channel to write to * @param msg The message to write */ - void write(level channel, std::string const &msg) + void write(level channel, std::string const &msg) + { + scoped_lock_type lock(m_lock); + if (!this->dynamic_test(channel)) { - scoped_lock_type lock(m_lock); - if (!this->dynamic_test(channel)) - { - return; - } - qCDebug(chatterinoWebsocket).nospace() - << names::channel_name(channel) << ": " - << QString::fromStdString(msg); + return; } + qCDebug(chatterinoWebsocket).nospace() + << names::channel_name(channel) << ": " + << QString::fromStdString(msg); + } - /// Write a cstring message to the given channel - /** + /// Write a cstring message to the given channel + /** * @param channel The channel to write to * @param msg The message to write */ - void write(level channel, char const *msg) + void write(level channel, char const *msg) + { + scoped_lock_type lock(m_lock); + if (!this->dynamic_test(channel)) { - scoped_lock_type lock(m_lock); - if (!this->dynamic_test(channel)) - { - return; - } - qCDebug(chatterinoWebsocket).nospace() - << names::channel_name(channel) << ": " << msg; + return; } + qCDebug(chatterinoWebsocket).nospace() + << names::channel_name(channel) << ": " << msg; + } - /// Test whether a channel is statically enabled - /** + /// Test whether a channel is statically enabled + /** * @param channel The package of channels to test */ - _WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const - { - return ((channel & m_static_channels) != 0); - } + _WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const + { + return ((channel & m_static_channels) != 0); + } - /// Test whether a channel is dynamically enabled - /** + /// Test whether a channel is dynamically enabled + /** * @param channel The package of channels to test */ - bool dynamic_test(level channel) - { - return ((channel & m_dynamic_channels) != 0); - } - - protected: - typedef typename concurrency::scoped_lock_type scoped_lock_type; - typedef typename concurrency::mutex_type mutex_type; - mutex_type m_lock; + bool dynamic_test(level channel) + { + return ((channel & m_dynamic_channels) != 0); + } - private: - level const m_static_channels; - level m_dynamic_channels; - }; +protected: + using scoped_lock_type = typename concurrency::scoped_lock_type; + using mutex_type = typename concurrency::mutex_type; + mutex_type m_lock; -} // namespace log -} // namespace websocketpp +private: + level const m_static_channels; + level m_dynamic_channels; +}; -#endif // CHATTERINOWEBSOCKETPPLOGGER_HPP +} // namespace websocketpp::log From 6bb2d85b2cd3daf0bf55ce9d2f6c66d6da97c886 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 24 Dec 2022 11:32:24 +0100 Subject: [PATCH 09/10] fix: turn `MAGIC_MESSAGE_SUFFIX` into a `QString` --- src/providers/twitch/TwitchChannel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index dcb67095afb..b8def8bcd8b 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -38,7 +38,7 @@ namespace chatterino { namespace { - constexpr char8_t MAGIC_MESSAGE_SUFFIX[] = u8" \U000E0000"; + const QString MAGIC_MESSAGE_SUFFIX = QString((const char *)u8" \U000E0000"); constexpr int TITLE_REFRESH_PERIOD = 10000; constexpr int CLIP_CREATION_COOLDOWN = 5000; const QString CLIPS_LINK("https://clips.twitch.tv/%1"); @@ -367,7 +367,7 @@ QString TwitchChannel::prepareMessage(const QString &message) const if (spaceIndex == -1) { // no spaces found, fall back to old magic character - parsedMessage.append((const char *)MAGIC_MESSAGE_SUFFIX); + parsedMessage.append(MAGIC_MESSAGE_SUFFIX); } else { From a62f66590ae2d39f7cacea6a4da9bee0db789403 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 24 Dec 2022 12:24:16 +0100 Subject: [PATCH 10/10] hacky unhacky hacky const char hack --- src/providers/twitch/TwitchChannel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index b8def8bcd8b..0c995bd9f35 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -38,7 +38,11 @@ namespace chatterino { namespace { +#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 CLIP_CREATION_COOLDOWN = 5000; const QString CLIPS_LINK("https://clips.twitch.tv/%1");