From 106addf5a88d4d116c93984d4710e394eb126d47 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 3 Oct 2022 22:18:49 +1000 Subject: [PATCH] Qt: Fix shutdown and save state in fullscreen UI --- src/core/system.h | 2 +- src/duckstation-nogui/nogui_host.cpp | 4 ++-- src/duckstation-qt/mainwindow.cpp | 14 ++++++++------ src/duckstation-qt/mainwindow.h | 2 +- src/duckstation-qt/qthost.cpp | 4 ++-- src/frontend-common/fullscreen_ui.cpp | 10 +++++----- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/core/system.h b/src/core/system.h index 75d785ecd..56d7bbf28 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -473,7 +473,7 @@ void RequestResizeHostDisplay(s32 width, s32 height); void RequestExit(bool save_state_if_running); /// Requests shut down of the current virtual machine. -void RequestSystemShutdown(bool allow_confirm, bool allow_save_state); +void RequestSystemShutdown(bool allow_confirm, bool save_state); /// Returns true if the hosting application is currently fullscreen. bool IsFullscreen(); diff --git a/src/duckstation-nogui/nogui_host.cpp b/src/duckstation-nogui/nogui_host.cpp index 66607e08a..18c342bc4 100644 --- a/src/duckstation-nogui/nogui_host.cpp +++ b/src/duckstation-nogui/nogui_host.cpp @@ -975,12 +975,12 @@ void Host::RequestExit(bool save_state_if_running) s_running.store(false, std::memory_order_release); } -void Host::RequestSystemShutdown(bool allow_confirm, bool allow_save_state) +void Host::RequestSystemShutdown(bool allow_confirm, bool save_state) { // TODO: Confirm if (System::IsValid()) { - Host::RunOnCPUThread([allow_save_state]() { System::ShutdownSystem(allow_save_state); }); + Host::RunOnCPUThread([save_state]() { System::ShutdownSystem(save_state); }); } } diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 96c2378b9..67dc3d77f 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -1793,8 +1793,10 @@ void MainWindow::connectSignals() connect(m_ui.actionRemoveDisc, &QAction::triggered, this, &MainWindow::onRemoveDiscActionTriggered); connect(m_ui.actionAddGameDirectory, &QAction::triggered, [this]() { getSettingsDialog()->getGameListSettingsWidget()->addSearchDirectory(this); }); - connect(m_ui.actionPowerOff, &QAction::triggered, this, [this]() { requestShutdown(true, true); }); - connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this, [this]() { requestShutdown(false, false); }); + connect(m_ui.actionPowerOff, &QAction::triggered, this, + [this]() { requestShutdown(true, true, g_settings.save_state_on_exit); }); + connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this, + [this]() { requestShutdown(false, false, false); }); connect(m_ui.actionReset, &QAction::triggered, g_emu_thread, &EmuThread::resetSystem); connect(m_ui.actionPause, &QAction::toggled, [](bool active) { g_emu_thread->setSystemPaused(active); }); connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot); @@ -2367,14 +2369,14 @@ void MainWindow::runOnUIThread(const std::function& func) } bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, - bool block_until_done /* = false */) + bool save_state /* = true */, bool block_until_done /* = false */) { if (!s_system_valid) return true; // If we don't have a serial, we can't save state. allow_save_to_state &= !m_current_game_code.empty(); - bool save_state = allow_save_to_state && g_settings.save_state_on_exit; + save_state &= allow_save_to_state; // Only confirm on UI thread because we need to display a msgbox. if (!m_is_closing && allow_confirm && g_settings.confim_power_off) @@ -2387,7 +2389,7 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav msgbox.setText("Are you sure you want to shut down the virtual machine?"); QCheckBox* save_cb = new QCheckBox(tr("Save State For Resume"), &msgbox); - save_cb->setChecked(save_state); + save_cb->setChecked(allow_save_to_state && save_state); save_cb->setEnabled(allow_save_to_state); msgbox.setCheckBox(save_cb); msgbox.addButton(QMessageBox::Yes); @@ -2434,7 +2436,7 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav void MainWindow::requestExit(bool allow_save_to_state /* = true */) { // this is block, because otherwise closeEvent() will also prompt - if (!requestShutdown(true, allow_save_to_state, true)) + if (!requestShutdown(true, allow_save_to_state, g_settings.save_state_on_exit)) return; // We could use close here, but if we're not visible (e.g. quitting from fullscreen), closing the window diff --git a/src/duckstation-qt/mainwindow.h b/src/duckstation-qt/mainwindow.h index 436ad4c46..e1590edfd 100644 --- a/src/duckstation-qt/mainwindow.h +++ b/src/duckstation-qt/mainwindow.h @@ -94,7 +94,7 @@ public Q_SLOTS: void cancelGameListRefresh(); void runOnUIThread(const std::function& func); - bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool block_until_done = false); + bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool save_state = true, bool block_until_done = false); void requestExit(bool allow_save_to_state = true); void checkForSettingChanges(); diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index f5ddfbcd3..9ac2cb80b 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -1714,13 +1714,13 @@ void QtHost::QueueSettingsSave() s_settings_save_timer->start(SETTINGS_SAVE_DELAY); } -void Host::RequestSystemShutdown(bool allow_confirm, bool allow_save_state) +void Host::RequestSystemShutdown(bool allow_confirm, bool save_state) { if (!System::IsValid()) return; QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection, Q_ARG(bool, allow_confirm), - Q_ARG(bool, allow_save_state), Q_ARG(bool, false)); + Q_ARG(bool, true), Q_ARG(bool, save_state), Q_ARG(bool, false)); } void Host::RequestExit(bool save_state_if_running) diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 41a37ac36..db3a77935 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -3909,7 +3909,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) case PauseSubMenu::None: { // NOTE: Menu close must come first, because otherwise VM destruction options will race. - const bool can_load_or_save_state = System::IsValid(); + const bool has_game = System::IsValid() && !System::GetRunningCode().empty(); if (ActiveButton(ICON_FA_PLAY " Resume Game", false) || WantsToCloseMenu()) ClosePauseMenu(); @@ -3920,13 +3920,13 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) DoToggleFastForward(); } - if (ActiveButton(ICON_FA_UNDO " Load State", false, can_load_or_save_state)) + if (ActiveButton(ICON_FA_UNDO " Load State", false, has_game)) { if (OpenSaveStateSelector(true)) s_current_main_window = MainWindowType::None; } - if (ActiveButton(ICON_FA_DOWNLOAD " Save State", false, can_load_or_save_state)) + if (ActiveButton(ICON_FA_DOWNLOAD " Save State", false, has_game)) { if (OpenSaveStateSelector(false)) s_current_main_window = MainWindowType::None; @@ -3945,7 +3945,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) DoToggleAnalogMode(); } - if (ActiveButton(ICON_FA_WRENCH " Game Properties", false, !System::GetRunningCode().empty())) + if (ActiveButton(ICON_FA_WRENCH " Game Properties", false, has_game)) { SwitchToGameSettings(); } @@ -3984,7 +3984,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) if (ActiveButton(ICON_FA_POWER_OFF " Close Game", false)) { // skip submenu when we can't save anyway - if (!can_load_or_save_state) + if (!has_game) DoShutdown(false); else OpenPauseSubMenu(PauseSubMenu::Exit);