summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/settings.cpp5
-rw-r--r--src/common/settings.h5
-rw-r--r--src/common/settings_enums.h2
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/shared_translation.cpp8
-rw-r--r--src/yuzu/main.cpp115
-rw-r--r--src/yuzu/main.h18
-rw-r--r--src/yuzu/uisettings.h11
8 files changed, 125 insertions, 43 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 3fde3cae6..98b43e49c 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -45,6 +45,7 @@ SWITCHABLE(CpuAccuracy, true);
45SWITCHABLE(FullscreenMode, true); 45SWITCHABLE(FullscreenMode, true);
46SWITCHABLE(GpuAccuracy, true); 46SWITCHABLE(GpuAccuracy, true);
47SWITCHABLE(Language, true); 47SWITCHABLE(Language, true);
48SWITCHABLE(MemoryLayout, true);
48SWITCHABLE(NvdecEmulation, false); 49SWITCHABLE(NvdecEmulation, false);
49SWITCHABLE(Region, true); 50SWITCHABLE(Region, true);
50SWITCHABLE(RendererBackend, true); 51SWITCHABLE(RendererBackend, true);
@@ -61,6 +62,10 @@ SWITCHABLE(u32, false);
61SWITCHABLE(u8, false); 62SWITCHABLE(u8, false);
62SWITCHABLE(u8, true); 63SWITCHABLE(u8, true);
63 64
65// Used in UISettings
66// TODO see if we can move this to uisettings.cpp
67SWITCHABLE(ConfirmStop, true);
68
64#undef SETTING 69#undef SETTING
65#undef SWITCHABLE 70#undef SWITCHABLE
66#endif 71#endif
diff --git a/src/common/settings.h b/src/common/settings.h
index 98ab0ec2e..236e33bee 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -67,6 +67,7 @@ SWITCHABLE(CpuAccuracy, true);
67SWITCHABLE(FullscreenMode, true); 67SWITCHABLE(FullscreenMode, true);
68SWITCHABLE(GpuAccuracy, true); 68SWITCHABLE(GpuAccuracy, true);
69SWITCHABLE(Language, true); 69SWITCHABLE(Language, true);
70SWITCHABLE(MemoryLayout, true);
70SWITCHABLE(NvdecEmulation, false); 71SWITCHABLE(NvdecEmulation, false);
71SWITCHABLE(Region, true); 72SWITCHABLE(Region, true);
72SWITCHABLE(RendererBackend, true); 73SWITCHABLE(RendererBackend, true);
@@ -83,6 +84,10 @@ SWITCHABLE(u32, false);
83SWITCHABLE(u8, false); 84SWITCHABLE(u8, false);
84SWITCHABLE(u8, true); 85SWITCHABLE(u8, true);
85 86
87// Used in UISettings
88// TODO see if we can move this to uisettings.h
89SWITCHABLE(ConfirmStop, true);
90
86#undef SETTING 91#undef SETTING
87#undef SWITCHABLE 92#undef SWITCHABLE
88#endif 93#endif
diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h
index 815cafe15..11429d7a8 100644
--- a/src/common/settings_enums.h
+++ b/src/common/settings_enums.h
@@ -133,6 +133,8 @@ ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid);
133 133
134ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb); 134ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb);
135 135
136ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
137
136ENUM(FullscreenMode, Borderless, Exclusive); 138ENUM(FullscreenMode, Borderless, Exclusive);
137 139
138ENUM(NvdecEmulation, Off, Cpu, Gpu); 140ENUM(NvdecEmulation, Off, Cpu, Gpu);
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 1de093447..d5157c502 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -128,8 +128,8 @@ const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{
128 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}}, 128 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}},
129 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}}, 129 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}},
130 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, 130 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}},
131 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut, false}}, 131 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral("R+Plus+Minus"), Qt::WindowShortcut, false}},
132 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut, false}}, 132 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral("L+Plus+Minus"), Qt::WindowShortcut, false}},
133 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, 133 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
134 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, 134 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
135 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, 135 {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index a4e8af1b4..3fe448f27 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -157,6 +157,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
157 INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); 157 INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", "");
158 INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); 158 INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", "");
159 INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", ""); 159 INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", "");
160 INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", "");
160 INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); 161 INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", "");
161 INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); 162 INSERT(UISettings, controller_applet_disabled, "Disable controller applet", "");
162 163
@@ -383,6 +384,13 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
383 translations->insert( 384 translations->insert(
384 {Settings::EnumMetadata<Settings::ConsoleMode>::Index(), 385 {Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
385 {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}}); 386 {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}});
387 translations->insert(
388 {Settings::EnumMetadata<Settings::ConfirmStop>::Index(),
389 {
390 PAIR(ConfirmStop, Ask_Always, "Always ask (Default)"),
391 PAIR(ConfirmStop, Ask_Based_On_Game, "Only if game specifies not to stop"),
392 PAIR(ConfirmStop, Ask_Never, "Never ask"),
393 }});
386 394
387#undef PAIR 395#undef PAIR
388#undef CTX_PAIR 396#undef CTX_PAIR
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 1a6b63856..1431cf2fe 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -211,7 +211,7 @@ void GMainWindow::ShowTelemetryCallout() {
211 tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous " 211 tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous "
212 "data is collected</a> to help improve yuzu. " 212 "data is collected</a> to help improve yuzu. "
213 "<br/><br/>Would you like to share your usage data with us?"); 213 "<br/><br/>Would you like to share your usage data with us?");
214 if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) { 214 if (!question(this, tr("Telemetry"), telemetry_message)) {
215 Settings::values.enable_telemetry = false; 215 Settings::values.enable_telemetry = false;
216 system->ApplySettings(); 216 system->ApplySettings();
217 } 217 }
@@ -2420,9 +2420,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
2420 } 2420 }
2421 }(); 2421 }();
2422 2422
2423 if (QMessageBox::question(this, tr("Remove Entry"), entry_question, 2423 if (!question(this, tr("Remove Entry"), entry_question, QMessageBox::Yes | QMessageBox::No,
2424 QMessageBox::Yes | QMessageBox::No, 2424 QMessageBox::No)) {
2425 QMessageBox::No) != QMessageBox::Yes) {
2426 return; 2425 return;
2427 } 2426 }
2428 2427
@@ -2521,8 +2520,8 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
2521 } 2520 }
2522 }(); 2521 }();
2523 2522
2524 if (QMessageBox::question(this, tr("Remove File"), question, QMessageBox::Yes | QMessageBox::No, 2523 if (!GMainWindow::question(this, tr("Remove File"), question,
2525 QMessageBox::No) != QMessageBox::Yes) { 2524 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) {
2526 return; 2525 return;
2527 } 2526 }
2528 2527
@@ -3409,10 +3408,13 @@ void GMainWindow::OnRestartGame() {
3409 if (!system->IsPoweredOn()) { 3408 if (!system->IsPoweredOn()) {
3410 return; 3409 return;
3411 } 3410 }
3412 // Make a copy since ShutdownGame edits game_path 3411
3413 const auto current_game = QString(current_game_path); 3412 if (ConfirmShutdownGame()) {
3414 ShutdownGame(); 3413 // Make a copy since ShutdownGame edits game_path
3415 BootGame(current_game); 3414 const auto current_game = QString(current_game_path);
3415 ShutdownGame();
3416 BootGame(current_game);
3417 }
3416} 3418}
3417 3419
3418void GMainWindow::OnPauseGame() { 3420void GMainWindow::OnPauseGame() {
@@ -3434,18 +3436,39 @@ void GMainWindow::OnPauseContinueGame() {
3434} 3436}
3435 3437
3436void GMainWindow::OnStopGame() { 3438void GMainWindow::OnStopGame() {
3437 if (system->GetExitLocked() && !ConfirmForceLockedExit()) { 3439 if (ConfirmShutdownGame()) {
3438 return; 3440 play_time_manager->Stop();
3441 // Update game list to show new play time
3442 game_list->PopulateAsync(UISettings::values.game_dirs);
3443 if (OnShutdownBegin()) {
3444 OnShutdownBeginDialog();
3445 } else {
3446 OnEmulationStopped();
3447 }
3439 } 3448 }
3449}
3440 3450
3441 play_time_manager->Stop(); 3451bool GMainWindow::ConfirmShutdownGame() {
3442 // Update game list to show new play time 3452 if (UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Always) {
3443 game_list->PopulateAsync(UISettings::values.game_dirs); 3453 if (system->GetExitLocked()) {
3444 if (OnShutdownBegin()) { 3454 if (!ConfirmForceLockedExit()) {
3445 OnShutdownBeginDialog(); 3455 return false;
3456 }
3457 } else {
3458 if (!ConfirmChangeGame()) {
3459 return false;
3460 }
3461 }
3446 } else { 3462 } else {
3447 OnEmulationStopped(); 3463 if (UISettings::values.confirm_before_stopping.GetValue() ==
3464 ConfirmStop::Ask_Based_On_Game &&
3465 system->GetExitLocked()) {
3466 if (!ConfirmForceLockedExit()) {
3467 return false;
3468 }
3469 }
3448 } 3470 }
3471 return true;
3449} 3472}
3450 3473
3451void GMainWindow::OnLoadComplete() { 3474void GMainWindow::OnLoadComplete() {
@@ -3825,22 +3848,11 @@ void GMainWindow::OnTasRecord() {
3825 const bool is_recording = input_subsystem->GetTas()->Record(); 3848 const bool is_recording = input_subsystem->GetTas()->Record();
3826 if (!is_recording) { 3849 if (!is_recording) {
3827 is_tas_recording_dialog_active = true; 3850 is_tas_recording_dialog_active = true;
3828 ControllerNavigation* controller_navigation = 3851
3829 new ControllerNavigation(system->HIDCore(), this); 3852 bool answer = question(this, tr("TAS Recording"), tr("Overwrite file of player 1?"),
3830 // Use QMessageBox instead of question so we can link controller navigation 3853 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
3831 QMessageBox* box_dialog = new QMessageBox(); 3854
3832 box_dialog->setWindowTitle(tr("TAS Recording")); 3855 input_subsystem->GetTas()->SaveRecording(answer);
3833 box_dialog->setText(tr("Overwrite file of player 1?"));
3834 box_dialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
3835 box_dialog->setDefaultButton(QMessageBox::Yes);
3836 connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent,
3837 [box_dialog](Qt::Key key) {
3838 QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
3839 QCoreApplication::postEvent(box_dialog, event);
3840 });
3841 int res = box_dialog->exec();
3842 controller_navigation->UnloadController();
3843 input_subsystem->GetTas()->SaveRecording(res == QMessageBox::Yes);
3844 is_tas_recording_dialog_active = false; 3856 is_tas_recording_dialog_active = false;
3845 } 3857 }
3846 OnTasStateChanged(); 3858 OnTasStateChanged();
@@ -4081,6 +4093,29 @@ void GMainWindow::OnLoadAmiibo() {
4081 LoadAmiibo(filename); 4093 LoadAmiibo(filename);
4082} 4094}
4083 4095
4096bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text,
4097 QMessageBox::StandardButtons buttons,
4098 QMessageBox::StandardButton defaultButton) {
4099
4100 QMessageBox* box_dialog = new QMessageBox(parent);
4101 box_dialog->setWindowTitle(title);
4102 box_dialog->setText(text);
4103 box_dialog->setStandardButtons(buttons);
4104 box_dialog->setDefaultButton(defaultButton);
4105
4106 ControllerNavigation* controller_navigation =
4107 new ControllerNavigation(system->HIDCore(), box_dialog);
4108 connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent,
4109 [box_dialog](Qt::Key key) {
4110 QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
4111 QCoreApplication::postEvent(box_dialog, event);
4112 });
4113 int res = box_dialog->exec();
4114
4115 controller_navigation->UnloadController();
4116 return res == QMessageBox::Yes;
4117}
4118
4084void GMainWindow::LoadAmiibo(const QString& filename) { 4119void GMainWindow::LoadAmiibo(const QString& filename) {
4085 auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); 4120 auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo();
4086 const QString title = tr("Error loading Amiibo data"); 4121 const QString title = tr("Error loading Amiibo data");
@@ -4814,8 +4849,7 @@ bool GMainWindow::ConfirmClose() {
4814 return true; 4849 return true;
4815 } 4850 }
4816 const auto text = tr("Are you sure you want to close yuzu?"); 4851 const auto text = tr("Are you sure you want to close yuzu?");
4817 const auto answer = QMessageBox::question(this, tr("yuzu"), text); 4852 return question(this, tr("yuzu"), text);
4818 return answer != QMessageBox::No;
4819} 4853}
4820 4854
4821void GMainWindow::closeEvent(QCloseEvent* event) { 4855void GMainWindow::closeEvent(QCloseEvent* event) {
@@ -4908,11 +4942,11 @@ bool GMainWindow::ConfirmChangeGame() {
4908 if (emu_thread == nullptr) 4942 if (emu_thread == nullptr)
4909 return true; 4943 return true;
4910 4944
4911 const auto answer = QMessageBox::question( 4945 // Use custom question to link controller navigation
4946 return question(
4912 this, tr("yuzu"), 4947 this, tr("yuzu"),
4913 tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), 4948 tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."),
4914 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); 4949 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
4915 return answer != QMessageBox::No;
4916} 4950}
4917 4951
4918bool GMainWindow::ConfirmForceLockedExit() { 4952bool GMainWindow::ConfirmForceLockedExit() {
@@ -4922,8 +4956,7 @@ bool GMainWindow::ConfirmForceLockedExit() {
4922 const auto text = tr("The currently running application has requested yuzu to not exit.\n\n" 4956 const auto text = tr("The currently running application has requested yuzu to not exit.\n\n"
4923 "Would you like to bypass this and exit anyway?"); 4957 "Would you like to bypass this and exit anyway?");
4924 4958
4925 const auto answer = QMessageBox::question(this, tr("yuzu"), text); 4959 return question(this, tr("yuzu"), text);
4926 return answer != QMessageBox::No;
4927} 4960}
4928 4961
4929void GMainWindow::RequestGameExit() { 4962void GMainWindow::RequestGameExit() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 2346eb3bd..270a40c5f 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -7,6 +7,7 @@
7#include <optional> 7#include <optional>
8 8
9#include <QMainWindow> 9#include <QMainWindow>
10#include <QMessageBox>
10#include <QTimer> 11#include <QTimer>
11#include <QTranslator> 12#include <QTranslator>
12 13
@@ -15,6 +16,7 @@
15#include "input_common/drivers/tas_input.h" 16#include "input_common/drivers/tas_input.h"
16#include "yuzu/compatibility_list.h" 17#include "yuzu/compatibility_list.h"
17#include "yuzu/hotkeys.h" 18#include "yuzu/hotkeys.h"
19#include "yuzu/util/controller_navigation.h"
18 20
19#ifdef __unix__ 21#ifdef __unix__
20#include <QVariant> 22#include <QVariant>
@@ -424,6 +426,11 @@ private:
424 bool CheckSystemArchiveDecryption(); 426 bool CheckSystemArchiveDecryption();
425 bool CheckFirmwarePresence(); 427 bool CheckFirmwarePresence();
426 void ConfigureFilesystemProvider(const std::string& filepath); 428 void ConfigureFilesystemProvider(const std::string& filepath);
429 /**
430 * Open (or not) the right confirm dialog based on current setting and game exit lock
431 * @returns true if the player confirmed or the settings do no require it
432 */
433 bool ConfirmShutdownGame();
427 434
428 QString GetTasStateDescription() const; 435 QString GetTasStateDescription() const;
429 bool CreateShortcut(const std::string& shortcut_path, const std::string& title, 436 bool CreateShortcut(const std::string& shortcut_path, const std::string& title,
@@ -431,6 +438,17 @@ private:
431 const std::string& command, const std::string& arguments, 438 const std::string& command, const std::string& arguments,
432 const std::string& categories, const std::string& keywords); 439 const std::string& categories, const std::string& keywords);
433 440
441 /**
442 * Mimic the behavior of QMessageBox::question but link controller navigation to the dialog
443 * The only difference is that it returns a boolean.
444 *
445 * @returns true if buttons contains QMessageBox::Yes and the user clicks on the "Yes" button.
446 */
447 bool question(QWidget* parent, const QString& title, const QString& text,
448 QMessageBox::StandardButtons buttons =
449 QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
450 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
451
434 std::unique_ptr<Ui::MainWindow> ui; 452 std::unique_ptr<Ui::MainWindow> ui;
435 453
436 std::unique_ptr<Core::System> system; 454 std::unique_ptr<Core::System> system;
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 975008159..b62ff620c 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -16,7 +16,9 @@
16#include "common/settings_enums.h" 16#include "common/settings_enums.h"
17 17
18using Settings::Category; 18using Settings::Category;
19using Settings::ConfirmStop;
19using Settings::Setting; 20using Settings::Setting;
21using Settings::SwitchableSetting;
20 22
21#ifndef CANNOT_EXPLICITLY_INSTANTIATE 23#ifndef CANNOT_EXPLICITLY_INSTANTIATE
22namespace Settings { 24namespace Settings {
@@ -94,6 +96,15 @@ struct Values {
94 Setting<bool> confirm_before_closing{ 96 Setting<bool> confirm_before_closing{
95 linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default, 97 linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default,
96 true, true}; 98 true, true};
99
100 SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage,
101 ConfirmStop::Ask_Always,
102 "confirmStop",
103 Category::UiGeneral,
104 Settings::Specialization::Default,
105 true,
106 true};
107
97 Setting<bool> first_start{linkage, true, "firstStart", Category::Ui}; 108 Setting<bool> first_start{linkage, true, "firstStart", Category::Ui};
98 Setting<bool> pause_when_in_background{linkage, 109 Setting<bool> pause_when_in_background{linkage,
99 false, 110 false,