From c3d3903b6fa8809f46bb12cb41fafbcc2c68b403 Mon Sep 17 00:00:00 2001 From: Mm2PL Date: Tue, 5 Dec 2023 18:37:42 +0100 Subject: [PATCH] feat: add `--safe-mode` command line option (#4985) This ensures the settings button isn't hidden, and disables plugins from being loaded to make sure the user can always recover from messing things up --- CHANGELOG.md | 1 + src/common/Args.cpp | 8 +++++++ src/common/Args.hpp | 1 + src/controllers/plugins/PluginController.cpp | 15 ++++++++++--- src/widgets/Notebook.cpp | 22 ++++++++++++++------ src/widgets/Window.cpp | 6 ++++++ src/widgets/settingspages/PluginsPage.cpp | 14 +++++++++++++ 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 544306830..9048d8a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Minor: The `/reply` command now replies to the latest message of the user. (#4919) - Minor: All sound capabilities can now be disabled by setting your "Sound backend" setting to "Null" and restarting Chatterino. (#4978) - Minor: Add an option to use new experimental smarter emote completion. (#4987) +- Minor: Add `--safe-mode` command line option that can be used for troubleshooting when Chatterino is misbehaving or is misconfigured. It disables hiding the settings button & prevents plugins from loading. (#4985) - Bugfix: Fixed an issue where certain emojis did not send to Twitch chat correctly. (#4840) - Bugfix: Fixed capitalized channel names in log inclusion list not being logged. (#4848) - Bugfix: Trimmed custom streamlink paths on all platforms making sure you don't accidentally add spaces at the beginning or end of its path. (#4834) diff --git a/src/common/Args.cpp b/src/common/Args.cpp index 2894c3f7b..7bc48573c 100644 --- a/src/common/Args.cpp +++ b/src/common/Args.cpp @@ -38,6 +38,9 @@ Args::Args(const QApplication &app) "Attaches to the Console on windows, " "allowing you to see debug output."}); crashRecoveryOption.setFlags(QCommandLineOption::HiddenFromHelp); + QCommandLineOption safeModeOption( + "safe-mode", "Starts Chatterino without loading Plugins and always " + "show the settings button."); parser.addOptions({ {{"V", "version"}, "Displays version information."}, @@ -45,6 +48,7 @@ Args::Args(const QApplication &app) parentWindowOption, parentWindowIdOption, verboseOption, + safeModeOption, }); parser.addOption(QCommandLineOption( {"c", "channels"}, @@ -89,6 +93,10 @@ Args::Args(const QApplication &app) this->parentWindowId = parser.value(parentWindowIdOption).toULongLong(); } + if (parser.isSet(safeModeOption)) + { + this->safeMode = true; + } } void Args::applyCustomChannelLayout(const QString &argValue) diff --git a/src/common/Args.hpp b/src/common/Args.hpp index 9fba4bdaf..73144b7da 100644 --- a/src/common/Args.hpp +++ b/src/common/Args.hpp @@ -26,6 +26,7 @@ public: bool dontLoadMainWindow{}; std::optional customChannelLayout; bool verbose{}; + bool safeMode{}; private: void applyCustomChannelLayout(const QString &argValue); diff --git a/src/controllers/plugins/PluginController.cpp b/src/controllers/plugins/PluginController.cpp index e98a30720..9a3356e96 100644 --- a/src/controllers/plugins/PluginController.cpp +++ b/src/controllers/plugins/PluginController.cpp @@ -2,6 +2,7 @@ # include "controllers/plugins/PluginController.hpp" # include "Application.hpp" +# include "common/Args.hpp" # include "common/QLogging.hpp" # include "controllers/commands/CommandContext.hpp" # include "controllers/commands/CommandController.hpp" @@ -194,12 +195,20 @@ void PluginController::openLibrariesFor(lua_State *L, void PluginController::load(const QFileInfo &index, const QDir &pluginDir, const PluginMeta &meta) { - lua_State *l = luaL_newstate(); - PluginController::openLibrariesFor(l, meta); - auto pluginName = pluginDir.dirName(); + lua_State *l = luaL_newstate(); auto plugin = std::make_unique(pluginName, l, meta, pluginDir); this->plugins_.insert({pluginName, std::move(plugin)}); + + if (getArgs().safeMode) + { + // This isn't done earlier to ensure the user can disable a misbehaving plugin + qCWarning(chatterinoLua) << "Skipping loading plugin " << meta.name + << " because safe mode is enabled."; + return; + } + PluginController::openLibrariesFor(l, meta); + if (!PluginController::isPluginEnabled(pluginName) || !getSettings()->pluginsEnabled) { diff --git a/src/widgets/Notebook.cpp b/src/widgets/Notebook.cpp index 2ac276e3e..adb427ac3 100644 --- a/src/widgets/Notebook.cpp +++ b/src/widgets/Notebook.cpp @@ -1,6 +1,7 @@ #include "widgets/Notebook.hpp" #include "Application.hpp" +#include "common/Args.hpp" #include "common/QLogging.hpp" #include "controllers/hotkeys/HotkeyCategory.hpp" #include "controllers/hotkeys/HotkeyController.hpp" @@ -1345,13 +1346,22 @@ void SplitNotebook::addCustomButtons() // settings auto settingsBtn = this->addCustomButton(); - settingsBtn->setVisible(!getSettings()->hidePreferencesButton.getValue()); + // This is to ensure you can't lock yourself out of the settings + if (getArgs().safeMode) + { + settingsBtn->setVisible(true); + } + else + { + settingsBtn->setVisible( + !getSettings()->hidePreferencesButton.getValue()); - getSettings()->hidePreferencesButton.connect( - [settingsBtn](bool hide, auto) { - settingsBtn->setVisible(!hide); - }, - this->signalHolder_); + getSettings()->hidePreferencesButton.connect( + [settingsBtn](bool hide, auto) { + settingsBtn->setVisible(!hide); + }, + this->signalHolder_); + } settingsBtn->setIcon(NotebookButton::Settings); diff --git a/src/widgets/Window.cpp b/src/widgets/Window.cpp index 0193b4359..be9f7f7ff 100644 --- a/src/widgets/Window.cpp +++ b/src/widgets/Window.cpp @@ -1,6 +1,7 @@ #include "widgets/Window.hpp" #include "Application.hpp" +#include "common/Args.hpp" #include "common/Credentials.hpp" #include "common/Modes.hpp" #include "common/QLogging.hpp" @@ -736,6 +737,11 @@ void Window::onAccountSelected() } #endif + if (getArgs().safeMode) + { + windowTitle += " (safe mode)"; + } + this->setWindowTitle(windowTitle); // update user diff --git a/src/widgets/settingspages/PluginsPage.cpp b/src/widgets/settingspages/PluginsPage.cpp index 20e65fd3c..87966a81a 100644 --- a/src/widgets/settingspages/PluginsPage.cpp +++ b/src/widgets/settingspages/PluginsPage.cpp @@ -2,6 +2,7 @@ # include "widgets/settingspages/PluginsPage.hpp" # include "Application.hpp" +# include "common/Args.hpp" # include "controllers/plugins/PluginController.hpp" # include "singletons/Paths.hpp" # include "singletons/Settings.hpp" @@ -52,6 +53,15 @@ PluginsPage::PluginsPage() this->rebuildContent(); }); groupLayout->addRow(box); + if (getArgs().safeMode) + { + box->setEnabled(false); + auto *disabledLabel = new QLabel(this); + disabledLabel->setText("Plugins will not be fully loaded because " + "Chatterino is in safe mode. You can still " + "enable and disable them."); + groupLayout->addRow(disabledLabel); + } } this->rebuildContent(); @@ -177,6 +187,10 @@ void PluginsPage::rebuildContent() this->rebuildContent(); }); pluginEntry->addRow(reloadButton); + if (getArgs().safeMode) + { + reloadButton->setEnabled(false); + } } }