Qt: fix GracefulShutdown regression

By replacing Emu.Stop() with GracefulShutdown() in gs_frame::close(), the game window was now unknowingly closed recursively, causing RPCS3 to crash in some cases.
Let's just ignore any consecutive calls to close() from now on.
Also don't close the window internally on a close event. request a shutdown instead.
This commit is contained in:
Megamouse 2022-04-01 03:44:05 +02:00
parent 36e3939ec2
commit 4f12f8b04f
3 changed files with 42 additions and 7 deletions

View file

@ -357,21 +357,34 @@ bool gs_frame::get_mouse_lock_state()
return isActive() && m_mouse_hide_and_lock;
}
void gs_frame::hide_on_close()
{
if (!(+g_progr))
{
// Hide the dialog before stopping if no progress bar is being shown.
// Otherwise users might think that the game softlocked if stopping takes too long.
QWindow::hide();
}
}
void gs_frame::close()
{
if (m_is_closing.exchange(true))
{
gui_log.notice("Closing game window (ignored, already closing)");
return;
}
gui_log.notice("Closing game window");
Emu.CallFromMainThread([this]()
{
if (!(+g_progr))
{
// Hide the dialog before stopping if no progress bar is being shown.
// Otherwise users might think that the game softlocked if stopping takes too long.
QWindow::hide();
}
// Hide window if necessary
hide_on_close();
if (!Emu.IsStopped())
{
// Blocking shutdown request. Obsolete, but I'm keeping it here as last resort.
Emu.GracefulShutdown(true, false);
}
@ -838,7 +851,23 @@ bool gs_frame::event(QEvent* ev)
}
gui_log.notice("Game window close event issued");
close();
if (Emu.IsStopped())
{
// This should be unreachable, but never say never. Properly close the window anyway.
close();
}
else
{
// Issue async shutdown
Emu.GracefulShutdown(true, true);
// Hide window if necessary
hide_on_close();
// Do not propagate the close event. It will be closed by the rsx_thread.
return true;
}
}
else if (ev->type() == QEvent::MouseMove && (!m_show_mouse || m_mousehide_timer.isActive()))
{

View file

@ -41,6 +41,7 @@ private:
u64 m_frames = 0;
std::string m_window_title;
QWindow::Visibility m_last_visibility = Visibility::Windowed;
atomic_t<bool> m_is_closing = false;
atomic_t<bool> m_show_mouse = true;
bool m_disable_mouse = false;
bool m_disable_kb_hotkeys = false;
@ -97,6 +98,7 @@ protected:
bool event(QEvent* ev) override;
private:
void hide_on_close();
void toggle_mouselock();
void update_cursor();
void handle_cursor(QWindow::Visibility visibility, bool from_event, bool start_idle_timer);

View file

@ -73,6 +73,10 @@ extern void process_qt_events()
{
if (thread_ctrl::is_main())
{
// NOTE:
// I noticed that calling this from an Emu callback can cause the
// caller to get stuck for a while during newly opened Qt dialogs.
// Adding a timeout here doesn't seem to do anything in that case.
QApplication::processEvents();
}
}