mirror of https://github.com/PCSX2/pcsx2.git
Qt: Better handle VM-requesting-shutdown case
This was a bit wonky in batch mode before. Now all possible exit paths close the application at the same point.
This commit is contained in:
parent
c596a51593
commit
f447aded57
|
@ -373,7 +373,7 @@ void Host::SetFullscreen(bool enabled)
|
|||
{
|
||||
}
|
||||
|
||||
void Host::RequestExit(bool save_state_if_running)
|
||||
void Host::RequestExit(bool allow_confirm)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ void AutoUpdaterDialog::downloadUpdateClicked()
|
|||
else if (result == 1)
|
||||
{
|
||||
// updater started. since we're a modal on the main window, we have to queue this.
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::requestExit, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, true));
|
||||
done(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ void DisplayWidget::handleCloseEvent(QCloseEvent* event)
|
|||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::requestExit);
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Q_ARG(bool, true));
|
||||
}
|
||||
|
||||
// Cancel the event from closing the window.
|
||||
|
|
|
@ -1275,8 +1275,7 @@ void MainWindow::runOnUIThread(const std::function<void()>& func)
|
|||
func();
|
||||
}
|
||||
|
||||
bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */,
|
||||
bool default_save_to_state /* = true */, bool block_until_done /* = false */)
|
||||
bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, bool default_save_to_state)
|
||||
{
|
||||
if (!s_vm_valid)
|
||||
return true;
|
||||
|
@ -1321,34 +1320,21 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav
|
|||
|
||||
// Now we can actually shut down the VM.
|
||||
g_emu_thread->shutdownVM(save_state);
|
||||
|
||||
if (block_until_done || m_is_closing || QtHost::InBatchMode())
|
||||
{
|
||||
// We need to yield here, since the display gets destroyed.
|
||||
while (VMManager::GetState() != VMState::Shutdown)
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
||||
}
|
||||
|
||||
if (!m_is_closing && QtHost::InBatchMode())
|
||||
{
|
||||
// If we don't set the closing flag here, the VM shutdown may not complete by the time closeEvent() is called,
|
||||
// leading to a confirm.
|
||||
m_is_closing = true;
|
||||
QGuiApplication::quit();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::requestExit()
|
||||
void MainWindow::requestExit(bool allow_confirm)
|
||||
{
|
||||
// this is block, because otherwise closeEvent() will also prompt
|
||||
if (!requestShutdown(true, true, EmuConfig.SaveStateOnShutdown, true))
|
||||
if (!requestShutdown(allow_confirm, true, EmuConfig.SaveStateOnShutdown))
|
||||
return;
|
||||
|
||||
// We could use close here, but if we're not visible (e.g. quitting from fullscreen), closing the window
|
||||
// doesn't quit the application.
|
||||
QGuiApplication::quit();
|
||||
// VM stopped signal won't have fired yet, so queue an exit if we still have one.
|
||||
// Otherwise, immediately exit, because there's no VM to exit us later.
|
||||
if (QtHost::IsVMValid())
|
||||
m_is_closing = true;
|
||||
else
|
||||
QGuiApplication::quit();
|
||||
}
|
||||
|
||||
void MainWindow::checkForSettingChanges()
|
||||
|
@ -1943,6 +1929,13 @@ void MainWindow::onVMStopped()
|
|||
updateStatusBarWidgetVisibility();
|
||||
updateInputRecordingActions(false);
|
||||
|
||||
// If we're closing or in batch mode, quit the whole application now.
|
||||
if (m_is_closing || QtHost::InBatchMode())
|
||||
{
|
||||
QCoreApplication::quit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_display_widget)
|
||||
updateDisplayWidgetCursor();
|
||||
else
|
||||
|
@ -1982,7 +1975,7 @@ void MainWindow::showEvent(QShowEvent* event)
|
|||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (!requestShutdown(true, true, EmuConfig.SaveStateOnShutdown, true))
|
||||
if (!requestShutdown(true, true, EmuConfig.SaveStateOnShutdown))
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
|
|
|
@ -117,9 +117,8 @@ public Q_SLOTS:
|
|||
void reportError(const QString& title, const QString& message);
|
||||
bool confirmMessage(const QString& title, const QString& message);
|
||||
void runOnUIThread(const std::function<void()>& func);
|
||||
bool requestShutdown(
|
||||
bool allow_confirm = true, bool allow_save_to_state = true, bool default_save_to_state = true, bool block_until_done = false);
|
||||
void requestExit();
|
||||
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool default_save_to_state = true);
|
||||
void requestExit(bool allow_confirm = true);
|
||||
void checkForSettingChanges();
|
||||
std::optional<WindowInfo> getWindowInfo();
|
||||
|
||||
|
|
|
@ -1228,12 +1228,9 @@ void Host::CancelGameListRefresh()
|
|||
QMetaObject::invokeMethod(g_main_window, "cancelGameListRefresh", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
void Host::RequestExit(bool save_state_if_running)
|
||||
void Host::RequestExit(bool allow_confirm)
|
||||
{
|
||||
if (VMManager::HasValidVM())
|
||||
g_emu_thread->shutdownVM(save_state_if_running);
|
||||
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, allow_confirm));
|
||||
}
|
||||
|
||||
void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool default_save_state)
|
||||
|
@ -1241,16 +1238,24 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def
|
|||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
// MainWindow handles close-on-exit for batch mode.
|
||||
if (allow_confirm || QtHost::InBatchMode())
|
||||
// This is a bit messy here - we want to shut down immediately (in case it was requested by the game),
|
||||
// but we also need to exit-on-shutdown for batch mode. So, if we're running on the CPU thread, destroy
|
||||
// the VM, then request the main window to exit.
|
||||
if (allow_confirm || !g_emu_thread->isOnEmuThread())
|
||||
{
|
||||
// Run it on the host thread, that way we get the confirm prompt (if enabled).
|
||||
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection, Q_ARG(bool, allow_confirm),
|
||||
Q_ARG(bool, allow_save_state), Q_ARG(bool, default_save_state), Q_ARG(bool, false));
|
||||
Q_ARG(bool, allow_save_state), Q_ARG(bool, default_save_state));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change state to stopping -> return -> shut down VM.
|
||||
g_emu_thread->shutdownVM(allow_save_state && default_save_state);
|
||||
|
||||
// This will probably call shutdownVM() again, but by the time it runs, we'll have already shut down
|
||||
// and it'll be a noop.
|
||||
if (QtHost::InBatchMode())
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1559,7 +1564,7 @@ static void SignalHandler(int signal)
|
|||
graceful_shutdown_attempted = true;
|
||||
|
||||
// This could be a bit risky invoking from a signal handler... hopefully it's okay.
|
||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::requestExit, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, false));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1062,7 +1062,7 @@ void FullscreenUI::DoChangeDisc()
|
|||
|
||||
void FullscreenUI::DoRequestExit()
|
||||
{
|
||||
Host::RunOnCPUThread([]() { Host::RequestExit(EmuConfig.SaveStateOnShutdown); });
|
||||
Host::RunOnCPUThread([]() { Host::RequestExit(true); });
|
||||
}
|
||||
|
||||
void FullscreenUI::DoToggleFullscreen()
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace Host
|
|||
|
||||
/// Requests shut down and exit of the hosting application. This may not actually exit,
|
||||
/// if the user cancels the shutdown confirmation.
|
||||
void RequestExit(bool save_state_if_running);
|
||||
void RequestExit(bool allow_confirm);
|
||||
|
||||
/// Requests shut down of the current virtual machine.
|
||||
void RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool default_save_state);
|
||||
|
|
Loading…
Reference in New Issue