Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerkaber <social.pio@posteo.jp>2022-08-13 12:49:49 +0300
committerRobert Adam <dev@robert-adam.de>2022-09-16 16:14:02 +0300
commit4c4dfa7dfa60f7e85e7d580c55d2c12bb722449f (patch)
tree8f103bc6f226688b77f48e5c7147810c7f58ecbc
parentfa471b69a9c0fda4b2ffbbe6217c07411d44d983 (diff)
FEAT(client, ui): Extended quit behavior setting
This commit extends the quit behavior setting from being a binary toggle between ask or don't ask, when quitting while connected to a server, to give the user the options for Mumble to ask, minimize or quit straight away, either always or only while connected to a server. Fixes #5282
-rw-r--r--src/mumble/CMakeLists.txt1
-rw-r--r--src/mumble/EnumStringConversions.cpp11
-rw-r--r--src/mumble/EnumStringConversions.h2
-rw-r--r--src/mumble/JSONSerialization.cpp11
-rw-r--r--src/mumble/LookConfig.cpp6
-rw-r--r--src/mumble/LookConfig.ui43
-rw-r--r--src/mumble/MainWindow.cpp47
-rw-r--r--src/mumble/MainWindow.h2
-rw-r--r--src/mumble/MumbleApplication.cpp2
-rw-r--r--src/mumble/QuitBehavior.h18
-rw-r--r--src/mumble/Settings.cpp10
-rw-r--r--src/mumble/Settings.h3
-rw-r--r--src/mumble/SettingsKeys.h2
-rw-r--r--src/mumble/SettingsMacros.h2
-rw-r--r--src/mumble/VersionCheck.cpp2
-rwxr-xr-xsrc/tests/TestSettingsJSONSerialization/generate_test_case.py2
16 files changed, 137 insertions, 27 deletions
diff --git a/src/mumble/CMakeLists.txt b/src/mumble/CMakeLists.txt
index 5ee9783bd..b1ae27fba 100644
--- a/src/mumble/CMakeLists.txt
+++ b/src/mumble/CMakeLists.txt
@@ -138,6 +138,7 @@ set(MUMBLE_SOURCES
"ConnectDialogEdit.ui"
"ConnectDialog.h"
"ConnectDialog.ui"
+ "QuitBehavior.h"
"CustomElements.cpp"
"CustomElements.h"
"Database.cpp"
diff --git a/src/mumble/EnumStringConversions.cpp b/src/mumble/EnumStringConversions.cpp
index b36b1187b..a3c8e26e0 100644
--- a/src/mumble/EnumStringConversions.cpp
+++ b/src/mumble/EnumStringConversions.cpp
@@ -69,6 +69,13 @@
PROCESS(Settings::AlwaysOnTopBehaviour, OnTopInMinimal, "InMinimal") \
PROCESS(Settings::AlwaysOnTopBehaviour, OnTopInNormal, "InNormal")
+#define QUIT_VALUES \
+ PROCESS(QuitBehavior, ALWAYS_ASK, "AlwaysAsk") \
+ PROCESS(QuitBehavior, ASK_WHEN_CONNECTED, "AskWhenConnected") \
+ PROCESS(QuitBehavior, ALWAYS_MINIMIZE, "AlwaysMinimize") \
+ PROCESS(QuitBehavior, MINIMIZE_WHEN_CONNECTED, "MinimizeWhenConnected") \
+ PROCESS(QuitBehavior, ALWAYS_QUIT, "AlwaysQuit")
+
#define WINDOW_LAYOUT_VALUES \
PROCESS(Settings::WindowLayout, LayoutClassic, "Classic") \
PROCESS(Settings::WindowLayout, LayoutStacked, "Stacked") \
@@ -178,6 +185,9 @@
BEFORE_CODE(Settings::AlwaysOnTopBehaviour) \
ALWAYS_ON_TOP_VALUES \
AFTER_CODE \
+ BEFORE_CODE(QuitBehavior) \
+ QUIT_VALUES \
+ AFTER_CODE \
BEFORE_CODE(Settings::WindowLayout) \
WINDOW_LAYOUT_VALUES \
AFTER_CODE \
@@ -253,6 +263,7 @@ PROCESS_ALL_ENUMS
#undef RECORDING_MODE_VALUES
#undef WINDOW_LAYOUT_VALUES
#undef ALWAYS_ON_TOP_VALUES
+#undef QUIT_VALUES
#undef PROXY_TYPE_VALUES
#undef ECHO_CANCEL_VALUES
#undef NOISE_CANCEL_VALUES
diff --git a/src/mumble/EnumStringConversions.h b/src/mumble/EnumStringConversions.h
index c42a1d6c3..1431127dd 100644
--- a/src/mumble/EnumStringConversions.h
+++ b/src/mumble/EnumStringConversions.h
@@ -26,6 +26,7 @@ const char *enumToString(Settings::NoiseCancel e);
const char *enumToString(EchoCancelOptionID e);
const char *enumToString(Settings::ProxyType e);
const char *enumToString(Settings::AlwaysOnTopBehaviour e);
+const char *enumToString(QuitBehavior e);
const char *enumToString(Settings::WindowLayout e);
const char *enumToString(Settings::RecordingMode e);
const char *enumToString(Search::SearchDialog::UserAction e);
@@ -50,6 +51,7 @@ void stringToEnum(const std::string &str, Settings::NoiseCancel &e);
void stringToEnum(const std::string &str, EchoCancelOptionID &e);
void stringToEnum(const std::string &str, Settings::ProxyType &e);
void stringToEnum(const std::string &str, Settings::AlwaysOnTopBehaviour &e);
+void stringToEnum(const std::string &str, QuitBehavior &e);
void stringToEnum(const std::string &str, Settings::WindowLayout &e);
void stringToEnum(const std::string &str, Settings::RecordingMode &e);
void stringToEnum(const std::string &str, Search::SearchDialog::UserAction &e);
diff --git a/src/mumble/JSONSerialization.cpp b/src/mumble/JSONSerialization.cpp
index 8729e440e..cd24c483f 100644
--- a/src/mumble/JSONSerialization.cpp
+++ b/src/mumble/JSONSerialization.cpp
@@ -153,7 +153,16 @@ void migrateSettings(nlohmann::json &json, int settingsVersion) {
// Perform conversions required to transform the given JSON into the format applicable to be read out by the most
// recent standards
- (void) json;
+ // Check if the old ask_on_quit key exists and the new one does not exist within the json file
+ if (json.contains("ask_on_quit")
+ && (!json.contains(static_cast< const char * >(SettingsKeys::QUIT_BEHAVIOR_KEY)))) {
+ if (!json.at("ask_on_quit").get< bool >()) {
+ json[SettingsKeys::QUIT_BEHAVIOR_KEY] = QuitBehavior::ALWAYS_QUIT;
+ } else {
+ json[SettingsKeys::QUIT_BEHAVIOR_KEY] = QuitBehavior::ALWAYS_ASK;
+ }
+ }
+
(void) settingsVersion;
}
diff --git a/src/mumble/LookConfig.cpp b/src/mumble/LookConfig.cpp
index 2d67e3e35..4fc9e7c3b 100644
--- a/src/mumble/LookConfig.cpp
+++ b/src/mumble/LookConfig.cpp
@@ -186,7 +186,9 @@ void LookConfig::load(const Settings &r) {
loadComboBox(qcbChannelDrag, r.ceChannelDrag);
loadComboBox(qcbUserDrag, r.ceUserDrag);
loadCheckBox(qcbUsersTop, r.bUserTop);
- loadCheckBox(qcbAskOnQuit, r.bAskOnQuit);
+
+ loadComboBox(qcbQuitBehavior, static_cast< int >(r.quitBehavior));
+
loadCheckBox(qcbEnableDeveloperMenu, r.bEnableDeveloperMenu);
loadCheckBox(qcbLockLayout, (r.wlWindowLayout == Settings::LayoutCustom) && r.bLockLayout);
loadCheckBox(qcbHideTray, r.bHideInTray);
@@ -253,7 +255,7 @@ void LookConfig::save() const {
}
s.aotbAlwaysOnTop = static_cast< Settings::AlwaysOnTopBehaviour >(qcbAlwaysOnTop->currentIndex());
- s.bAskOnQuit = qcbAskOnQuit->isChecked();
+ s.quitBehavior = static_cast< QuitBehavior >(qcbQuitBehavior->currentIndex());
s.bEnableDeveloperMenu = qcbEnableDeveloperMenu->isChecked();
s.bLockLayout = qcbLockLayout->isChecked();
s.bHideInTray = qcbHideTray->isChecked();
diff --git a/src/mumble/LookConfig.ui b/src/mumble/LookConfig.ui
index 1be0b578e..1e6e52fed 100644
--- a/src/mumble/LookConfig.ui
+++ b/src/mumble/LookConfig.ui
@@ -447,17 +447,46 @@
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
- <widget class="QCheckBox" name="qcbAskOnQuit">
+ <item row="2" column="0">
+ <widget class="QLabel" name="qliQuitBehavior">
+ <property name="text">
+ <string>Quit Behavior</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="MUComboBox" name="qcbQuitBehavior">
<property name="toolTip">
- <string>Ask whether to close or minimize when quitting Mumble.</string>
+ <string>This setting controls the behavior of clicking on the X in the top right corner.</string>
</property>
<property name="whatsThis">
- <string>&lt;b&gt;If set, will verify you want to quit if connected.&lt;/b&gt;</string>
- </property>
- <property name="text">
- <string>Ask on quit while connected</string>
+ <string>This setting controls the behavior when closing Mumble. You can choose between being asked for confirmation, minimize instead if closing or just closing without any additional prompt. Optionally, the first two options can only apply when you are currently connected to a server (in that case, Mumble will quit without asking, when not connected to any server).</string>
</property>
+ <item>
+ <property name="text">
+ <string>Always Ask</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Ask when connected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Always Minimize</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Minimize when connected</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Always Quit</string>
+ </property>
+ </item>
</widget>
</item>
<item row="3" column="0" colspan="2">
diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp
index e15662945..fcdc0f9f0 100644
--- a/src/mumble/MainWindow.cpp
+++ b/src/mumble/MainWindow.cpp
@@ -128,9 +128,9 @@ MainWindow::MainWindow(QWidget *p) : QMainWindow(p) {
#ifdef Q_OS_WIN
uiNewHardware = 1;
#endif
- bSuppressAskOnQuit = false;
- restartOnQuit = false;
- bAutoUnmute = false;
+ forceQuit = false;
+ restartOnQuit = false;
+ bAutoUnmute = false;
Channel::add(Channel::ROOT_ID, tr("Root"));
@@ -504,29 +504,56 @@ bool MainWindow::nativeEvent(const QByteArray &, void *message, long *) {
#endif
void MainWindow::closeEvent(QCloseEvent *e) {
+ ServerHandlerPtr sh = Global::get().sh;
+ QuitBehavior quitBehavior = Global::get().s.quitBehavior;
+ const bool alwaysAsk = quitBehavior == QuitBehavior::ALWAYS_ASK;
+ const bool askDueToConnected = sh && sh->isRunning() && quitBehavior == QuitBehavior::ASK_WHEN_CONNECTED;
+ const bool alwaysMinimize = quitBehavior == QuitBehavior::ALWAYS_MINIMIZE;
+ const bool minimizeDueToConnected = sh && sh->isRunning() && quitBehavior == QuitBehavior::MINIMIZE_WHEN_CONNECTED;
+
+ if (!forceQuit && (alwaysAsk || askDueToConnected)) {
#ifndef Q_OS_MAC
- ServerHandlerPtr sh = Global::get().sh;
- if (sh && sh->isRunning() && Global::get().s.bAskOnQuit && !bSuppressAskOnQuit) {
QMessageBox mb(QMessageBox::Warning, QLatin1String("Mumble"),
- tr("Mumble is currently connected to a server. Do you want to Close or Minimize it?"),
+ tr("Are you sure you want to close Mumble? Perhaps you prefer to minimize it instead?"),
QMessageBox::NoButton, this);
+ QCheckBox *qcbRemember = new QCheckBox(tr("Remember this setting"));
QPushButton *qpbClose = mb.addButton(tr("Close"), QMessageBox::YesRole);
QPushButton *qpbMinimize = mb.addButton(tr("Minimize"), QMessageBox::NoRole);
QPushButton *qpbCancel = mb.addButton(tr("Cancel"), QMessageBox::RejectRole);
mb.setDefaultButton(qpbClose);
mb.setEscapeButton(qpbCancel);
+ mb.setCheckBox(qcbRemember);
mb.exec();
if (mb.clickedButton() == qpbMinimize) {
showMinimized();
e->ignore();
+
+ // If checkbox is checked and not connected, always minimize
+ // If checkbox is checked and connected, always minimize when connected
+ if (qcbRemember->isChecked() && !(sh && sh->isRunning())) {
+ Global::get().s.quitBehavior = QuitBehavior::ALWAYS_MINIMIZE;
+ } else if (qcbRemember->isChecked()) {
+ Global::get().s.quitBehavior = QuitBehavior::MINIMIZE_WHEN_CONNECTED;
+ }
+
return;
} else if (mb.clickedButton() == qpbCancel) {
e->ignore();
return;
}
+
+ // If checkbox is checked, quit always
+ if (qcbRemember->isChecked()) {
+ Global::get().s.quitBehavior = QuitBehavior::ALWAYS_QUIT;
+ }
+#endif
+ } else if (!forceQuit && (alwaysMinimize || minimizeDueToConnected)) {
+ showMinimized();
+ e->ignore();
+ return;
}
+
sh.reset();
-#endif
if (Global::get().s.bMinimalView) {
Global::get().s.qbaMinimalViewGeometry = saveGeometry();
@@ -2066,7 +2093,7 @@ void MainWindow::on_qaHide_triggered() {
}
void MainWindow::on_qaQuit_triggered() {
- bSuppressAskOnQuit = true;
+ forceQuit = true;
this->close();
}
@@ -2703,8 +2730,8 @@ void MainWindow::on_qaConfigDialog_triggered() {
tr("Some settings will only apply after a restart of Mumble. Restart Mumble now?"),
QMessageBox::Yes | QMessageBox::No)
== QMessageBox::Yes) {
- bSuppressAskOnQuit = true;
- restartOnQuit = true;
+ forceQuit = true;
+ restartOnQuit = true;
close();
}
diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h
index 433c09fc6..e8ad769aa 100644
--- a/src/mumble/MainWindow.h
+++ b/src/mumble/MainWindow.h
@@ -109,7 +109,7 @@ public:
bool bRetryServer;
QString qsDesiredChannel;
- bool bSuppressAskOnQuit;
+ bool forceQuit;
/// Restart the client after shutdown
bool restartOnQuit;
bool bAutoUnmute;
diff --git a/src/mumble/MumbleApplication.cpp b/src/mumble/MumbleApplication.cpp
index 60b5958d1..f577d7572 100644
--- a/src/mumble/MumbleApplication.cpp
+++ b/src/mumble/MumbleApplication.cpp
@@ -38,7 +38,7 @@ void MumbleApplication::onCommitDataRequest(QSessionManager &) {
if (Global::get().mw) {
Global::get().s.mumbleQuitNormally = true;
Global::get().s.save();
- Global::get().mw->bSuppressAskOnQuit = true;
+ Global::get().mw->forceQuit = true;
qWarning() << "Session likely ending. Suppressing ask on quit";
}
}
diff --git a/src/mumble/QuitBehavior.h b/src/mumble/QuitBehavior.h
new file mode 100644
index 000000000..d1bacb9f1
--- /dev/null
+++ b/src/mumble/QuitBehavior.h
@@ -0,0 +1,18 @@
+// Copyright 2022 The Mumble Developers. All rights reserved.
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file at the root of the
+// Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+#ifndef MUMBLE_QUITBEHAVIOR_H
+#define MUMBLE_QUITBEHAVIOR_H
+
+/// This enum lists a series of quit options
+enum class QuitBehavior {
+ ALWAYS_ASK = 0,
+ ASK_WHEN_CONNECTED = 1,
+ ALWAYS_MINIMIZE = 2,
+ MINIMIZE_WHEN_CONNECTED = 3,
+ ALWAYS_QUIT = 4
+};
+
+#endif // MUMBLE_QUITBEHAVIOR_H
diff --git a/src/mumble/Settings.cpp b/src/mumble/Settings.cpp
index 09b5aff75..d823d202e 100644
--- a/src/mumble/Settings.cpp
+++ b/src/mumble/Settings.cpp
@@ -928,7 +928,6 @@ void Settings::legacyLoad(const QString &path) {
LOADENUM(ceChannelDrag, "ui/drag");
LOADENUM(ceUserDrag, "ui/userdrag");
LOADENUM(aotbAlwaysOnTop, "ui/alwaysontop");
- LOAD(bAskOnQuit, "ui/askonquit");
LOAD(bEnableDeveloperMenu, "ui/developermenu");
LOAD(bLockLayout, "ui/locklayout");
LOAD(bMinimalView, "ui/minimalview");
@@ -969,6 +968,15 @@ void Settings::legacyLoad(const QString &path) {
LOAD(iChatMessageMargins, "ui/ChatMessageMargins");
LOAD(bDisablePublicList, "ui/disablepubliclist");
+ if (settings_ptr->contains("ui/askonquit")) {
+ // Compatibility layer for overtaking the old (now deprecated) settings
+ // This block should only be called once at the first start of the new Mumble version
+ bool deprecatedAskOnQuit = true;
+ LOAD(deprecatedAskOnQuit, "ui/askonquit");
+
+ quitBehavior = deprecatedAskOnQuit ? QuitBehavior::ALWAYS_ASK : QuitBehavior::ALWAYS_QUIT;
+ }
+
// TalkingUI
LOAD(qpTalkingUI_Position, "ui/talkingUIPosition");
LOAD(bShowTalkingUI, "ui/showTalkingUI");
diff --git a/src/mumble/Settings.h b/src/mumble/Settings.h
index 6d37b77fb..0446c780d 100644
--- a/src/mumble/Settings.h
+++ b/src/mumble/Settings.h
@@ -24,6 +24,7 @@
#include <Qt>
#include "EchoCancelOption.h"
+#include "QuitBehavior.h"
#include "SSL.h"
#include "SearchDialog.h"
@@ -392,7 +393,7 @@ struct Settings {
bool bMinimalView = false;
bool bHideFrame = false;
AlwaysOnTopBehaviour aotbAlwaysOnTop = OnTopNever;
- bool bAskOnQuit = true;
+ QuitBehavior quitBehavior = QuitBehavior::ALWAYS_ASK;
bool bEnableDeveloperMenu = false;
bool bLockLayout = false;
bool bHideInTray = false;
diff --git a/src/mumble/SettingsKeys.h b/src/mumble/SettingsKeys.h
index 990307b43..b2d4ba69f 100644
--- a/src/mumble/SettingsKeys.h
+++ b/src/mumble/SettingsKeys.h
@@ -169,7 +169,7 @@ const SettingsKey CHANNEL_EXPANSION_MODE_KEY = { "channel_expansion_mo
const SettingsKey CHANNEL_DRAG_MODE_KEY = { "channel_drag_mode" };
const SettingsKey USER_DRAG_MODE_KEY = { "user_drag_mode" };
const SettingsKey ALWAYS_ON_TOP_KEY = { "always_on_top" };
-const SettingsKey ASK_ON_QUIT_KEY = { "ask_on_quit" };
+const SettingsKey QUIT_BEHAVIOR_KEY = { "quit_behavior" };
const SettingsKey SHOW_DEVELOPER_MENU_KEY = { "show_developer_menu" };
const SettingsKey LOCK_LAYOUT_KEY = { "lock_layout" };
const SettingsKey MINIMAL_VIEW_KEY = { "minimal_view" };
diff --git a/src/mumble/SettingsMacros.h b/src/mumble/SettingsMacros.h
index 87e48618b..e3be8e9e4 100644
--- a/src/mumble/SettingsMacros.h
+++ b/src/mumble/SettingsMacros.h
@@ -143,7 +143,7 @@
PROCESS(ui, CHANNEL_DRAG_MODE_KEY, ceChannelDrag) \
PROCESS(ui, USER_DRAG_MODE_KEY, ceUserDrag) \
PROCESS(ui, ALWAYS_ON_TOP_KEY, aotbAlwaysOnTop) \
- PROCESS(ui, ASK_ON_QUIT_KEY, bAskOnQuit) \
+ PROCESS(ui, QUIT_BEHAVIOR_KEY, quitBehavior) \
PROCESS(ui, SHOW_DEVELOPER_MENU_KEY, bEnableDeveloperMenu) \
PROCESS(ui, LOCK_LAYOUT_KEY, bLockLayout) \
PROCESS(ui, MINIMAL_VIEW_KEY, bMinimalView) \
diff --git a/src/mumble/VersionCheck.cpp b/src/mumble/VersionCheck.cpp
index e6745c80b..c183192ca 100644
--- a/src/mumble/VersionCheck.cpp
+++ b/src/mumble/VersionCheck.cpp
@@ -150,7 +150,7 @@ void VersionCheck::fetched(QByteArray a, QUrl url) {
execinfo.nShow = SW_NORMAL;
if (ShellExecuteExW(&execinfo)) {
- Global::get().mw->bSuppressAskOnQuit = true;
+ Global::get().mw->forceQuit = true;
qApp->closeAllWindows();
} else {
Global::get().mw->msgBox(tr("Failed to launch snapshot installer."));
diff --git a/src/tests/TestSettingsJSONSerialization/generate_test_case.py b/src/tests/TestSettingsJSONSerialization/generate_test_case.py
index 57e37c4a6..5ae436790 100755
--- a/src/tests/TestSettingsJSONSerialization/generate_test_case.py
+++ b/src/tests/TestSettingsJSONSerialization/generate_test_case.py
@@ -136,6 +136,8 @@ def getDefaultValueForType(dataType):
return "Settings::NoiseCancelBoth"
elif dataType in ["EchoCancelOptionID"]:
return "EchoCancelOptionID::SPEEX_MULTICHANNEL"
+ elif dataType in ["QuitBehavior"]:
+ return "QuitBehavior::ALWAYS_QUIT"
elif dataType in ["OverlayShow"]:
return "OverlaySettings::HomeChannel"
elif dataType in ["OverlayShow"]: