diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d00a7257a4..a65e2cf271a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ - Dev: BREAKING: Replace custom `import()` with normal Lua `require()`. (#5014) - Dev: Fixed most compiler warnings. (#5028) - Dev: Added the ability to show `ChannelView`s without a `Split`. (#4747) +- Dev: Refactor Args to be less of a singleton. (#5041) - Dev: Channels without any animated elements on screen will skip updates from the GIF timer. (#5042, #5043, #5045) ## 2.4.6 diff --git a/mocks/include/mocks/EmptyApplication.hpp b/mocks/include/mocks/EmptyApplication.hpp index 424c1d25b06..5917172b2dc 100644 --- a/mocks/include/mocks/EmptyApplication.hpp +++ b/mocks/include/mocks/EmptyApplication.hpp @@ -1,6 +1,7 @@ #pragma once #include "Application.hpp" +#include "common/Args.hpp" namespace chatterino::mock { @@ -9,6 +10,11 @@ class EmptyApplication : public IApplication public: virtual ~EmptyApplication() = default; + const Args &getArgs() override + { + return this->args_; + } + Theme *getThemes() override { return nullptr; @@ -110,6 +116,9 @@ class EmptyApplication : public IApplication { return nullptr; } + +private: + Args args_; }; } // namespace chatterino::mock diff --git a/src/Application.cpp b/src/Application.cpp index c28e36c621b..cfb28f13d85 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -104,8 +104,9 @@ IApplication::IApplication() // It will create the instances of the major classes, and connect their signals // to each other -Application::Application(Settings &_settings, Paths &_paths) - : themes(&this->emplace()) +Application::Application(Settings &_settings, Paths &_paths, const Args &_args) + : args_(_args) + , themes(&this->emplace()) , fonts(&this->emplace()) , emotes(&this->emplace()) , accounts(&this->emplace()) @@ -146,7 +147,7 @@ void Application::initialize(Settings &settings, Paths &paths) isAppInitialized = true; // Show changelog - if (!getArgs().isFramelessEmbed && + if (!this->args_.isFramelessEmbed && getSettings()->currentVersion.getValue() != "" && getSettings()->currentVersion.getValue() != CHATTERINO_VERSION) { @@ -161,7 +162,7 @@ void Application::initialize(Settings &settings, Paths &paths) } } - if (!getArgs().isFramelessEmbed) + if (!this->args_.isFramelessEmbed) { getSettings()->currentVersion.setValue(CHATTERINO_VERSION); @@ -179,7 +180,7 @@ void Application::initialize(Settings &settings, Paths &paths) // Show crash message. // On Windows, the crash message was already shown. #ifndef Q_OS_WIN - if (!getArgs().isFramelessEmbed && getArgs().crashRecovery) + if (!this->args_.isFramelessEmbed && this->args_.crashRecovery) { if (auto selected = this->windows->getMainWindow().getNotebook().getSelectedPage()) @@ -203,7 +204,7 @@ void Application::initialize(Settings &settings, Paths &paths) this->windows->updateWordTypeMask(); - if (!getArgs().isFramelessEmbed) + if (!this->args_.isFramelessEmbed) { this->initNm(paths); } @@ -219,7 +220,7 @@ int Application::run(QApplication &qtApp) this->twitch->connect(); - if (!getArgs().isFramelessEmbed) + if (!this->args_.isFramelessEmbed) { this->windows->getMainWindow().show(); } diff --git a/src/Application.hpp b/src/Application.hpp index 75d8bf3732a..656c0510b43 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -11,6 +11,7 @@ namespace chatterino { +class Args; class TwitchIrcServer; class ITwitchIrcServer; class PubSub; @@ -54,6 +55,7 @@ class IApplication static IApplication *instance; + virtual const Args &getArgs() = 0; virtual Theme *getThemes() = 0; virtual Fonts *getFonts() = 0; virtual IEmotes *getEmotes() = 0; @@ -78,6 +80,7 @@ class IApplication class Application : public IApplication { + const Args &args_; std::vector> singletons_; int argc_{}; char **argv_{}; @@ -85,7 +88,7 @@ class Application : public IApplication public: static Application *instance; - Application(Settings &settings, Paths &paths); + Application(Settings &_settings, Paths &_paths, const Args &_args); void initialize(Settings &settings, Paths &paths); void load(); @@ -126,6 +129,10 @@ class Application : public IApplication /*[[deprecated]]*/ Logging *const logging{}; + const Args &getArgs() override + { + return this->args_; + } Theme *getThemes() override { return this->themes; diff --git a/src/RunGui.cpp b/src/RunGui.cpp index 00b4b7497e8..39bed5594a5 100644 --- a/src/RunGui.cpp +++ b/src/RunGui.cpp @@ -98,9 +98,9 @@ namespace { installCustomPalette(); } - void showLastCrashDialog() + void showLastCrashDialog(const Args &args) { - auto *dialog = new LastRunCrashDialog; + auto *dialog = new LastRunCrashDialog(args); // Use exec() over open() to block the app from being loaded // and to be able to set the safe mode. dialog->exec(); @@ -223,16 +223,16 @@ namespace { } } // namespace -void runGui(QApplication &a, Paths &paths, Settings &settings) +void runGui(QApplication &a, Paths &paths, Settings &settings, const Args &args) { initQt(); initResources(); initSignalHandler(); #ifdef Q_OS_WIN - if (getArgs().crashRecovery) + if (args.crashRecovery) { - showLastCrashDialog(); + showLastCrashDialog(args); } #endif @@ -271,12 +271,12 @@ void runGui(QApplication &a, Paths &paths, Settings &settings) chatterino::NetworkManager::init(); chatterino::Updates::instance().checkForUpdates(); - Application app(settings, paths); + Application app(settings, paths, args); app.initialize(settings, paths); app.run(a); app.save(); - if (!getArgs().dontSaveSettings) + if (!args.dontSaveSettings) { pajlada::Settings::SettingManager::gSave(); } diff --git a/src/RunGui.hpp b/src/RunGui.hpp index 3381644043c..61bd41f0b0e 100644 --- a/src/RunGui.hpp +++ b/src/RunGui.hpp @@ -3,8 +3,12 @@ class QApplication; namespace chatterino { + +class Args; class Paths; class Settings; -void runGui(QApplication &a, Paths &paths, Settings &settings); +void runGui(QApplication &a, Paths &paths, Settings &settings, + const Args &args); + } // namespace chatterino diff --git a/src/common/Args.cpp b/src/common/Args.cpp index 1096372cddb..c480f71b8e4 100644 --- a/src/common/Args.cpp +++ b/src/common/Args.cpp @@ -1,4 +1,4 @@ -#include "Args.hpp" +#include "common/Args.hpp" #include "common/QLogging.hpp" #include "debug/AssertInGuiThread.hpp" @@ -248,18 +248,4 @@ void Args::applyCustomChannelLayout(const QString &argValue) } } -static Args *instance = nullptr; - -void initArgs(const QApplication &app) -{ - instance = new Args(app); -} - -const Args &getArgs() -{ - assert(instance); - - return *instance; -} - } // namespace chatterino diff --git a/src/common/Args.hpp b/src/common/Args.hpp index 39b7d627b11..a60e988fcff 100644 --- a/src/common/Args.hpp +++ b/src/common/Args.hpp @@ -30,6 +30,7 @@ namespace chatterino { class Args { public: + Args() = default; Args(const QApplication &app); bool printVersion{}; @@ -60,7 +61,4 @@ class Args QStringList currentArguments_; }; -void initArgs(const QApplication &app); -const Args &getArgs(); - } // namespace chatterino diff --git a/src/controllers/plugins/PluginController.cpp b/src/controllers/plugins/PluginController.cpp index 55def19cee8..8566c9e24f0 100644 --- a/src/controllers/plugins/PluginController.cpp +++ b/src/controllers/plugins/PluginController.cpp @@ -233,7 +233,7 @@ void PluginController::load(const QFileInfo &index, const QDir &pluginDir, auto *temp = plugin.get(); this->plugins_.insert({pluginName, std::move(plugin)}); - if (getArgs().safeMode) + if (getApp()->getArgs().safeMode) { // This isn't done earlier to ensure the user can disable a misbehaving plugin qCWarning(chatterinoLua) << "Skipping loading plugin " << meta.name diff --git a/src/main.cpp b/src/main.cpp index 1366ae5cba8..bbd95581482 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,18 +62,18 @@ int main(int argc, char **argv) return 1; } - initArgs(a); + const Args args(a); #ifdef CHATTERINO_WITH_CRASHPAD - const auto crashpadHandler = installCrashHandler(); + const auto crashpadHandler = installCrashHandler(args); #endif // run in gui mode or browser extension host mode - if (getArgs().shouldRunBrowserExtensionHost) + if (args.shouldRunBrowserExtensionHost) { runBrowserExtensionHost(); } - else if (getArgs().printVersion) + else if (args.printVersion) { attachToConsole(); @@ -87,7 +87,7 @@ int main(int argc, char **argv) } else { - if (getArgs().verbose) + if (args.verbose) { attachToConsole(); } @@ -99,7 +99,7 @@ int main(int argc, char **argv) Settings settings(paths->settingsDirectory); - runGui(a, *paths, settings); + runGui(a, *paths, settings, args); } return 0; } diff --git a/src/singletons/CrashHandler.cpp b/src/singletons/CrashHandler.cpp index 76518e90999..ea77b09a180 100644 --- a/src/singletons/CrashHandler.cpp +++ b/src/singletons/CrashHandler.cpp @@ -82,10 +82,9 @@ std::optional readRecoverySettings(const Paths &paths) return shouldRecover.toBool(); } -bool canRestart(const Paths &paths) +bool canRestart(const Paths &paths, const Args &args) { #ifdef NDEBUG - const auto &args = chatterino::getArgs(); if (args.isFramelessEmbed || args.shouldRunBrowserExtensionHost) { return false; @@ -109,10 +108,10 @@ bool canRestart(const Paths &paths) /// additional plus ('++' -> '+'). /// /// The decoding happens in crash-handler/src/CommandLine.cpp -std::string encodeArguments() +std::string encodeArguments(const Args &appArgs) { std::string args; - for (auto arg : getArgs().currentArguments()) + for (auto arg : appArgs.currentArguments()) { if (!args.empty()) { @@ -161,7 +160,7 @@ void CrashHandler::saveShouldRecover(bool value) } #ifdef CHATTERINO_WITH_CRASHPAD -std::unique_ptr installCrashHandler() +std::unique_ptr installCrashHandler(const Args &args) { // Currently, the following directory layout is assumed: // [applicationDirPath] @@ -197,7 +196,7 @@ std::unique_ptr installCrashHandler() std::map annotations{ { "canRestart"s, - canRestart(*getPaths()) ? "true"s : "false"s, + canRestart(*getPaths(), args) ? "true"s : "false"s, }, { "exePath"s, @@ -209,7 +208,7 @@ std::unique_ptr installCrashHandler() }, { "exeArguments"s, - encodeArguments(), + encodeArguments(args), }, }; diff --git a/src/singletons/CrashHandler.hpp b/src/singletons/CrashHandler.hpp index 7f47708a081..058e46aed1f 100644 --- a/src/singletons/CrashHandler.hpp +++ b/src/singletons/CrashHandler.hpp @@ -12,6 +12,8 @@ namespace chatterino { +class Args; + class CrashHandler : public Singleton { public: @@ -30,7 +32,7 @@ class CrashHandler : public Singleton }; #ifdef CHATTERINO_WITH_CRASHPAD -std::unique_ptr installCrashHandler(); +std::unique_ptr installCrashHandler(const Args &args); #endif } // namespace chatterino diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index d8692efda5a..d2f8295bbfd 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -55,7 +55,7 @@ using SplitDirection = SplitContainer::Direction; void WindowManager::showSettingsDialog(QWidget *parent, SettingsDialogPreference preference) { - if (getArgs().dontSaveSettings) + if (getApp()->getArgs().dontSaveSettings) { QMessageBox::critical(parent, "Chatterino - Editing Settings Forbidden", "Settings cannot be edited when running with\n" @@ -356,9 +356,9 @@ void WindowManager::initialize(Settings &settings, Paths &paths) { WindowLayout windowLayout; - if (getArgs().customChannelLayout) + if (getApp()->getArgs().customChannelLayout) { - windowLayout = getArgs().customChannelLayout.value(); + windowLayout = getApp()->getArgs().customChannelLayout.value(); } else { @@ -370,7 +370,7 @@ void WindowManager::initialize(Settings &settings, Paths &paths) this->applyWindowLayout(windowLayout); } - if (getArgs().isFramelessEmbed) + if (getApp()->getArgs().isFramelessEmbed) { this->framelessEmbedWindow_.reset(new FramelessEmbedWindow); this->framelessEmbedWindow_->show(); @@ -383,7 +383,7 @@ void WindowManager::initialize(Settings &settings, Paths &paths) this->mainWindow_->getNotebook().addPage(true); // TODO: don't create main window if it's a frameless embed - if (getArgs().isFramelessEmbed) + if (getApp()->getArgs().isFramelessEmbed) { this->mainWindow_->hide(); } @@ -418,7 +418,7 @@ void WindowManager::initialize(Settings &settings, Paths &paths) void WindowManager::save() { - if (getArgs().dontSaveSettings) + if (getApp()->getArgs().dontSaveSettings) { return; } @@ -724,7 +724,7 @@ WindowLayout WindowManager::loadWindowLayoutFromFile() const void WindowManager::applyWindowLayout(const WindowLayout &layout) { - if (getArgs().dontLoadMainWindow) + if (getApp()->getArgs().dontLoadMainWindow) { return; } diff --git a/src/widgets/FramelessEmbedWindow.cpp b/src/widgets/FramelessEmbedWindow.cpp index d9e5479d880..c07b869c2e1 100644 --- a/src/widgets/FramelessEmbedWindow.cpp +++ b/src/widgets/FramelessEmbedWindow.cpp @@ -64,13 +64,13 @@ bool FramelessEmbedWindow::nativeEvent(const QByteArray &eventType, void FramelessEmbedWindow::showEvent(QShowEvent *) { - if (!getArgs().parentWindowId) + if (!getApp()->getArgs().parentWindowId) { return; } if (auto parentHwnd = - reinterpret_cast(getArgs().parentWindowId.value())) + reinterpret_cast(getApp()->getArgs().parentWindowId.value())) { auto handle = reinterpret_cast(this->winId()); if (!::SetParent(handle, parentHwnd)) diff --git a/src/widgets/Notebook.cpp b/src/widgets/Notebook.cpp index adb427ac3ed..b85b50b4509 100644 --- a/src/widgets/Notebook.cpp +++ b/src/widgets/Notebook.cpp @@ -1347,7 +1347,7 @@ void SplitNotebook::addCustomButtons() auto settingsBtn = this->addCustomButton(); // This is to ensure you can't lock yourself out of the settings - if (getArgs().safeMode) + if (getApp()->getArgs().safeMode) { settingsBtn->setVisible(true); } diff --git a/src/widgets/Window.cpp b/src/widgets/Window.cpp index be9f7f7ff8c..fa4b6c8a622 100644 --- a/src/widgets/Window.cpp +++ b/src/widgets/Window.cpp @@ -737,7 +737,7 @@ void Window::onAccountSelected() } #endif - if (getArgs().safeMode) + if (getApp()->getArgs().safeMode) { windowTitle += " (safe mode)"; } diff --git a/src/widgets/dialogs/LastRunCrashDialog.cpp b/src/widgets/dialogs/LastRunCrashDialog.cpp index f038b03f6ad..6de4daba9d8 100644 --- a/src/widgets/dialogs/LastRunCrashDialog.cpp +++ b/src/widgets/dialogs/LastRunCrashDialog.cpp @@ -43,7 +43,7 @@ namespace chatterino { using namespace literals; -LastRunCrashDialog::LastRunCrashDialog() +LastRunCrashDialog::LastRunCrashDialog(const Args &args) { this->setWindowFlag(Qt::WindowContextHelpButtonHint, false); this->setWindowTitle(u"Chatterino - " % randomMessage()); @@ -62,14 +62,14 @@ LastRunCrashDialog::LastRunCrashDialog() "" % reportsDir % u".
"; - if (getArgs().exceptionCode) + if (args.exceptionCode) { text += u"The last run crashed with code 0x" % - QString::number(*getArgs().exceptionCode, 16) % u""; + QString::number(*args.exceptionCode, 16) % u""; - if (getArgs().exceptionMessage) + if (args.exceptionMessage) { - text += u" (" % *getArgs().exceptionMessage % u")"; + text += u" (" % *args.exceptionMessage % u")"; } text += u".
"_s; diff --git a/src/widgets/dialogs/LastRunCrashDialog.hpp b/src/widgets/dialogs/LastRunCrashDialog.hpp index a4aa75ef75b..1f31c51f7db 100644 --- a/src/widgets/dialogs/LastRunCrashDialog.hpp +++ b/src/widgets/dialogs/LastRunCrashDialog.hpp @@ -4,10 +4,12 @@ namespace chatterino { +class Args; + class LastRunCrashDialog : public QDialog { public: - LastRunCrashDialog(); + explicit LastRunCrashDialog(const Args &args); }; } // namespace chatterino diff --git a/src/widgets/dialogs/SettingsDialog.cpp b/src/widgets/dialogs/SettingsDialog.cpp index 9d98913e8bd..591bfe93ac0 100644 --- a/src/widgets/dialogs/SettingsDialog.cpp +++ b/src/widgets/dialogs/SettingsDialog.cpp @@ -411,7 +411,7 @@ void SettingsDialog::showEvent(QShowEvent *e) ///// Widget creation helpers void SettingsDialog::onOkClicked() { - if (!getArgs().dontSaveSettings) + if (!getApp()->getArgs().dontSaveSettings) { getApp()->commands->save(); pajlada::Settings::SettingManager::gSave(); diff --git a/src/widgets/settingspages/PluginsPage.cpp b/src/widgets/settingspages/PluginsPage.cpp index d3beaa323f0..00fe5a791cf 100644 --- a/src/widgets/settingspages/PluginsPage.cpp +++ b/src/widgets/settingspages/PluginsPage.cpp @@ -53,7 +53,7 @@ PluginsPage::PluginsPage() this->rebuildContent(); }); groupLayout->addRow(box); - if (getArgs().safeMode) + if (getApp()->getArgs().safeMode) { box->setEnabled(false); auto *disabledLabel = new QLabel(this); @@ -197,7 +197,7 @@ void PluginsPage::rebuildContent() this->rebuildContent(); }); pluginEntry->addRow(reloadButton); - if (getArgs().safeMode) + if (getApp()->getArgs().safeMode) { reloadButton->setEnabled(false); }