Qt: Improve more window close behaviour

- Closing FSUI display window without a game running should not exit the
  application.
- Closing display window with FSUI started should exit the application
  in nogui mode.
This commit is contained in:
Stenzek 2025-07-19 14:34:29 +10:00
parent 8bd493eae0
commit 3e232b76b3
No known key found for this signature in database
4 changed files with 24 additions and 12 deletions

View File

@ -142,7 +142,11 @@ void DisplayWidget::handleCloseEvent(QCloseEvent* event)
if (QtHost::IsSystemValid() && !isActuallyFullscreen())
{
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection, Q_ARG(bool, true),
Q_ARG(bool, true), Q_ARG(bool, false), Q_ARG(bool, true));
Q_ARG(bool, true), Q_ARG(bool, false), Q_ARG(bool, true), Q_ARG(bool, true));
}
else if (QtHost::IsFullscreenUIStarted())
{
g_emu_thread->stopFullscreenUI();
}
else
{

View File

@ -2255,9 +2255,9 @@ void MainWindow::connectSignals()
connect(m_ui.actionAddGameDirectory, &QAction::triggered,
[this]() { getSettingsWindow()->getGameListSettingsWidget()->addSearchDirectory(this); });
connect(m_ui.actionPowerOff, &QAction::triggered, this,
[this]() { requestShutdown(true, true, g_settings.save_state_on_exit, true); });
[this]() { requestShutdown(true, true, g_settings.save_state_on_exit, true, false); });
connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this,
[this]() { requestShutdown(false, false, false, true); });
[this]() { requestShutdown(false, false, false, true, false); });
connect(m_ui.actionReset, &QAction::triggered, this, []() { g_emu_thread->resetSystem(true); });
connect(m_ui.actionPause, &QAction::toggled, this, [](bool active) { g_emu_thread->setSystemPaused(active); });
connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot);
@ -2666,7 +2666,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
event->ignore();
// Exit cancelled?
if (!requestShutdown(true, true, g_settings.save_state_on_exit, true))
if (!requestShutdown(true, true, g_settings.save_state_on_exit, true, true))
return;
// Application will be exited in VM stopped handler.
@ -2786,7 +2786,8 @@ void MainWindow::runOnUIThread(const std::function<void()>& func)
func();
}
bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, bool save_state, bool check_memcard_busy)
bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, bool save_state, bool check_safety,
bool exit_fullscreen_ui)
{
if (!s_system_valid)
return true;
@ -2827,15 +2828,19 @@ bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, b
if (QtHost::InBatchMode())
m_is_closing = true;
// Stop fullscreen UI from reopening if requested.
if (exit_fullscreen_ui && s_fullscreen_ui_started)
g_emu_thread->stopFullscreenUI();
// Now we can actually shut down the VM.
g_emu_thread->shutdownSystem(save_state, check_memcard_busy);
g_emu_thread->shutdownSystem(save_state, check_safety);
return true;
}
void MainWindow::requestExit(bool allow_confirm /* = true */)
{
// this is block, because otherwise closeEvent() will also prompt
if (!requestShutdown(allow_confirm, true, g_settings.save_state_on_exit, true))
if (!requestShutdown(allow_confirm, true, g_settings.save_state_on_exit, true, true))
return;
// VM stopped signal won't have fired yet, so queue an exit if we still have one.
@ -2844,9 +2849,6 @@ void MainWindow::requestExit(bool allow_confirm /* = true */)
if (s_system_valid)
return;
if (s_fullscreen_ui_started)
g_emu_thread->stopFullscreenUI();
quit();
}

View File

@ -122,7 +122,8 @@ public Q_SLOTS:
void cancelGameListRefresh();
void runOnUIThread(const std::function<void()>& func);
bool requestShutdown(bool allow_confirm, bool allow_save_to_state, bool save_state, bool check_memcard_busy);
bool requestShutdown(bool allow_confirm, bool allow_save_to_state, bool save_state, bool check_safety,
bool exit_fullscreen_ui);
void requestExit(bool allow_confirm = true);
void checkForSettingChanges();
std::optional<WindowInfo> getWindowInfo();

View File

@ -745,6 +745,10 @@ void EmuThread::stopFullscreenUI()
{
QMetaObject::invokeMethod(this, &EmuThread::stopFullscreenUI, Qt::QueuedConnection);
// if we still have a system, don't wait
if (QtHost::IsSystemValid())
return;
// wait until the host display is gone
QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, []() {
return QtHost::IsFullscreenUIStarted() || g_main_window->hasDisplayWidget();
@ -2580,7 +2584,8 @@ void Host::RequestSystemShutdown(bool allow_confirm, bool save_state, bool check
return;
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection, Q_ARG(bool, allow_confirm),
Q_ARG(bool, true), Q_ARG(bool, save_state), Q_ARG(bool, check_memcard_busy));
Q_ARG(bool, true), Q_ARG(bool, save_state), Q_ARG(bool, check_memcard_busy),
Q_ARG(bool, false));
}
void Host::RequestResetSettings(bool system, bool controller)