From 24a16db4376baccaf533fd4860c493a9c6d5f921 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 19 Jul 2025 01:04:22 +1000 Subject: [PATCH] Qt: Handle fullscreen cases on MacOS If the user exits fullscreen with the window button, restore render to main. --- src/duckstation-qt/displaywidget.cpp | 9 ++++++++- src/duckstation-qt/mainwindow.cpp | 21 +++++++++++++++------ src/duckstation-qt/mainwindow.h | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/duckstation-qt/displaywidget.cpp b/src/duckstation-qt/displaywidget.cpp index dec0babe7..6c13737fa 100644 --- a/src/duckstation-qt/displaywidget.cpp +++ b/src/duckstation-qt/displaywidget.cpp @@ -400,9 +400,16 @@ bool DisplayWidget::event(QEvent* event) { QWidget::event(event); - if (static_cast(event)->oldState() & Qt::WindowMinimized) + const QWindowStateChangeEvent* ws_event = static_cast(event); + if (ws_event->oldState() & Qt::WindowMinimized) emit windowRestoredEvent(); +#ifdef __APPLE__ + // On MacOS, the user can "cancel" fullscreen by unmaximizing the window. + if (ws_event->oldState() & Qt::WindowFullScreen && !(windowState() & Qt::WindowFullScreen)) + g_emu_thread->setFullscreen(false); +#endif + return true; } diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index 0541bb814..5298dba50 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -421,6 +421,16 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main) m_display_widget->setFocus(); } +void MainWindow::exitFullscreen(bool wait_for_completion) +{ + if (!m_display_widget || !isRenderingFullscreen()) + return; + + g_emu_thread->setFullscreen(false); + if (wait_for_completion) + QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() { return isRenderingFullscreen(); }); +} + void MainWindow::displayResizeRequested(qint32 width, qint32 height) { if (!m_display_widget) @@ -2179,6 +2189,9 @@ bool MainWindow::shouldHideMainWindow() const void MainWindow::switchToGameListView() { + // Normally, we'd never end up here. But on MacOS, the global menu is accessible while fullscreen. + exitFullscreen(true); + if (!isShowingGameList()) { if (wantsDisplayWidget()) @@ -3026,13 +3039,9 @@ void MainWindow::onToolsMemoryCardEditorTriggered() void MainWindow::onToolsCoverDownloaderTriggered() { // This can be invoked via big picture, so exit fullscreen. + // Wait for the fullscreen request to actually go through, otherwise the downloader appears behind the main window. if (isRenderingFullscreen()) - { - g_emu_thread->setFullscreen(false); - - // wait for the fullscreen request to actually go through, otherwise the downloader appears behind the main window. - QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() { return isRenderingFullscreen(); }); - } + exitFullscreen(true); if (!m_cover_download_window) { diff --git a/src/duckstation-qt/mainwindow.h b/src/duckstation-qt/mainwindow.h index 7e28f8fa2..6ca7c5c77 100644 --- a/src/duckstation-qt/mainwindow.h +++ b/src/duckstation-qt/mainwindow.h @@ -272,6 +272,7 @@ private: void destroyDisplayWidget(bool show_game_list); void updateDisplayWidgetCursor(); void updateDisplayRelatedActions(bool has_surface, bool fullscreen); + void exitFullscreen(bool wait_for_completion); void doSettings(const char* category = nullptr); void openGamePropertiesForCurrentGame(const char* category = nullptr);