From 837495d90f7e3d27927fbbe8731a81a9d8fde860 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 29 Aug 2022 20:31:29 +1000 Subject: [PATCH] Qt: Fix window close in nogui mode --- src/duckstation-qt/displaywidget.cpp | 31 ++++++++++++++++++---------- src/duckstation-qt/displaywidget.h | 4 ++++ src/duckstation-qt/mainwindow.cpp | 9 ++++---- src/duckstation-qt/qthost.cpp | 14 +++++++------ src/duckstation-qt/qthost.h | 3 +-- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/duckstation-qt/displaywidget.cpp b/src/duckstation-qt/displaywidget.cpp index ead309596..abc8478cb 100644 --- a/src/duckstation-qt/displaywidget.cpp +++ b/src/duckstation-qt/displaywidget.cpp @@ -162,6 +162,23 @@ void DisplayWidget::updateCursor(bool hidden) } } +void DisplayWidget::handleCloseEvent(QCloseEvent* event) +{ + // Closing the separate widget will either cancel the close, or trigger shutdown. + // In the latter case, it's going to destroy us, so don't let Qt do it first. + if (QtHost::IsSystemValid()) + { + QMetaObject::invokeMethod(g_main_window, "requestShutdown", Q_ARG(bool, true), Q_ARG(bool, true), + Q_ARG(bool, false)); + } + else + { + QMetaObject::invokeMethod(g_main_window, "requestExit"); + } + + event->ignore(); +} + void DisplayWidget::updateCenterPos() { #ifdef _WIN32 @@ -348,11 +365,7 @@ bool DisplayWidget::event(QEvent* event) case QEvent::Close: { - // Closing the separate widget will either cancel the close, or trigger shutdown. - // In the latter case, it's going to destroy us, so don't let Qt do it first. - QMetaObject::invokeMethod(g_main_window, "requestShutdown", Q_ARG(bool, true), Q_ARG(bool, true), - Q_ARG(bool, false)); - event->ignore(); + handleCloseEvent(static_cast(event)); return true; } @@ -416,13 +429,9 @@ DisplayWidget* DisplayContainer::removeDisplayWidget() bool DisplayContainer::event(QEvent* event) { - if (event->type() == QEvent::Close) + if (event->type() == QEvent::Close && m_display_widget) { - // Closing the separate widget will either cancel the close, or trigger shutdown. - // In the latter case, it's going to destroy us, so don't let Qt do it first. - QMetaObject::invokeMethod(g_main_window, "requestShutdown", Q_ARG(bool, true), Q_ARG(bool, true), - Q_ARG(bool, false)); - event->ignore(); + m_display_widget->handleCloseEvent(static_cast(event)); return true; } diff --git a/src/duckstation-qt/displaywidget.h b/src/duckstation-qt/displaywidget.h index a1c129da3..e9739ca9e 100644 --- a/src/duckstation-qt/displaywidget.h +++ b/src/duckstation-qt/displaywidget.h @@ -5,6 +5,8 @@ #include #include +class QCloseEvent; + class DisplayWidget final : public QWidget { Q_OBJECT @@ -24,6 +26,8 @@ public: void updateRelativeMode(bool enabled); void updateCursor(bool hidden); + void handleCloseEvent(QCloseEvent* event); + Q_SIGNALS: void windowResizedEvent(int width, int height, float scale); void windowRestoredEvent(); diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 7c9d6e65c..0fa50f946 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -2259,9 +2259,6 @@ void MainWindow::closeEvent(QCloseEvent* event) return; } - if (g_emu_thread->isRunningFullscreenUI()) - g_emu_thread->stopFullscreenUI(); - saveGeometryToConfig(); m_is_closing = true; @@ -2412,7 +2409,7 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav // Closing the window should shut down everything. 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; - close(); + QGuiApplication::quit(); } return true; @@ -2424,7 +2421,9 @@ void MainWindow::requestExit(bool allow_save_to_state /* = true */) if (!requestShutdown(true, allow_save_to_state, true)) return; - close(); + // 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(); } void MainWindow::checkForSettingChanges() diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index 7ee0dd594..e83e5bbe6 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -1373,7 +1373,9 @@ void EmuThread::stop() void EmuThread::stopInThread() { - m_shutdown_flag.store(true); + stopFullscreenUI(); + + m_shutdown_flag = true; m_event_loop->quit(); } @@ -1390,7 +1392,7 @@ void EmuThread::run() startBackgroundControllerPollTimer(); // main loop - while (!m_shutdown_flag.load()) + while (!m_shutdown_flag) { if (System::IsRunning()) { @@ -1398,9 +1400,6 @@ void EmuThread::run() } else { - m_event_loop->processEvents(QEventLoop::AllEvents); - CommonHost::PumpMessagesOnCPUThread(); - // we want to keep rendering the UI when paused and fullscreen UI is enabled if (!FullscreenUI::HasActiveWindow() && !System::IsRunning()) { @@ -1409,7 +1408,10 @@ void EmuThread::run() continue; } - renderDisplay(false); + m_event_loop->processEvents(QEventLoop::AllEvents); + CommonHost::PumpMessagesOnCPUThread(); + if (g_host_display) + renderDisplay(false); } } diff --git a/src/duckstation-qt/qthost.h b/src/duckstation-qt/qthost.h index 991bd6c76..6572217d1 100644 --- a/src/duckstation-qt/qthost.h +++ b/src/duckstation-qt/qthost.h @@ -210,8 +210,7 @@ private: QEventLoop* m_event_loop = nullptr; QTimer* m_background_controller_polling_timer = nullptr; - std::atomic_bool m_shutdown_flag{false}; - + bool m_shutdown_flag = false; bool m_run_fullscreen_ui = false; bool m_is_rendering_to_main = false; bool m_is_fullscreen = false;