| 3746 | } |
| 3747 | |
| 3748 | MainWindow::VMLock MainWindow::pauseAndLockVM() |
| 3749 | { |
| 3750 | // To switch out of fullscreen when displaying a popup, or not to? |
| 3751 | // For Windows, with driver's direct scanout, what renders behind tends to be hit and miss. |
| 3752 | // We can't draw anything over exclusive fullscreen, so get out of it in that case. |
| 3753 | // Wayland's a pain as usual, we need to recreate the window, which means there'll be a brief |
| 3754 | // period when there's no window, and Qt might shut us down. So avoid it there. |
| 3755 | // On MacOS, it forces a workspace switch, which is kinda jarring. |
| 3756 | #ifndef __APPLE__ |
| 3757 | const bool was_fullscreen = g_emu_thread->isFullscreen(); |
| 3758 | #else |
| 3759 | const bool was_fullscreen = false; |
| 3760 | #endif |
| 3761 | const bool was_paused = s_vm_paused; |
| 3762 | |
| 3763 | if (!was_paused) |
| 3764 | g_emu_thread->setVMPaused(true); |
| 3765 | |
| 3766 | // We need to switch out of exclusive fullscreen before we can display our popup. |
| 3767 | // However, we do not want to switch back to render-to-main, the window might have generated this event. |
| 3768 | if (was_fullscreen) |
| 3769 | { |
| 3770 | // m_is_temporarily_windowed needs to be set, so that we don't show the main window just for this popup. |
| 3771 | pxAssertRel(!g_main_window->m_is_temporarily_windowed, "Not already temporarily windowed"); |
| 3772 | g_main_window->m_is_temporarily_windowed = true; |
| 3773 | |
| 3774 | g_emu_thread->setFullscreen(false, false); |
| 3775 | |
| 3776 | // Process events untill both EmuThread and Qt have finished exiting fullscreen |
| 3777 | while (QtHost::IsVMValid() && (g_emu_thread->isFullscreen() || m_display_surface->isFullScreen())) |
| 3778 | { |
| 3779 | QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); |
| 3780 | } |
| 3781 | } |
| 3782 | |
| 3783 | // Ensure main window is visible. |
| 3784 | if (!g_main_window->isVisible()) |
| 3785 | g_main_window->show(); |
| 3786 | g_main_window->raise(); |
| 3787 | g_main_window->activateWindow(); |
| 3788 | |
| 3789 | #ifdef DISPLAY_SURFACE_WINDOW |
| 3790 | if (!m_display_container) |
| 3791 | { |
| 3792 | // Create a temporary parent for the dialog. |
| 3793 | QWidget* dialog_parent = new QWidget(); |
| 3794 | dialog_parent->setAttribute(Qt::WA_NativeWindow); |
| 3795 | QWindow* window_handle = dialog_parent->windowHandle(); |
| 3796 | |
| 3797 | // Set the transient parent to the display surface. |
| 3798 | // This will position the dialog_parent over the display surface (and thus so will any dialogs) |
| 3799 | // and also enforces the focus lock of modal dialogs against the display surface. |
| 3800 | // This works even without showing the dialog_parent window. |
| 3801 | window_handle->setTransientParent(m_display_surface); |
| 3802 | |
| 3803 | return VMLock(dialog_parent, was_paused, was_fullscreen, true); |
| 3804 | } |
| 3805 | else |
no test coverage detected