Qt: Add shutdown hotkey

This commit is contained in:
Connor McLaughlin 2022-03-25 20:14:23 +10:00 committed by refractionpcsx2
parent d65950cda2
commit 551d013b63
6 changed files with 45 additions and 32 deletions

View File

@ -139,27 +139,8 @@ void EmuThread::setVMPaused(bool paused)
VMManager::SetPaused(paused);
}
bool EmuThread::shutdownVM(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, bool blocking /* = false */)
bool EmuThread::shutdownVM(bool allow_save_to_state /* = true */)
{
if (!isOnEmuThread())
{
// only confirm on UI thread because we need to display a msgbox
if (allow_confirm && g_main_window && !g_main_window->confirmShutdown())
return false;
QMetaObject::invokeMethod(this, "shutdownVM", Qt::QueuedConnection, Q_ARG(bool, false),
Q_ARG(bool, allow_save_to_state), Q_ARG(bool, blocking));
if (blocking)
{
// we need to yield here, since the display gets destroyed
while (VMManager::HasValidVM())
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
}
return true;
}
const VMState state = VMManager::GetState();
if (state == VMState::Paused)
m_event_loop->quit();
@ -550,7 +531,7 @@ void EmuThread::connectDisplaySignals(DisplayWidget* widget)
connect(widget, &DisplayWidget::windowFocusEvent, this, &EmuThread::onDisplayWindowFocused);
connect(widget, &DisplayWidget::windowResizedEvent, this, &EmuThread::onDisplayWindowResized);
// connect(widget, &DisplayWidget::windowRestoredEvent, this, &EmuThread::redrawDisplayWindow);
connect(widget, &DisplayWidget::windowClosedEvent, []() { g_emu_thread->shutdownVM(true, true); });
connect(widget, &DisplayWidget::windowClosedEvent, []() { g_main_window->requestShutdown(); });
connect(widget, &DisplayWidget::windowKeyEvent, this, &EmuThread::onDisplayWindowKeyEvent);
connect(widget, &DisplayWidget::windowMouseMoveEvent, this, &EmuThread::onDisplayWindowMouseMoveEvent);
connect(widget, &DisplayWidget::windowMouseButtonEvent, this, &EmuThread::onDisplayWindowMouseButtonEvent);
@ -792,6 +773,14 @@ DEFINE_HOTKEY("Screenshot", "General", "Save Screenshot", [](bool pressed) {
// TODO
}
})
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](bool pressed) {
if (!pressed)
{
// run it on the host thread, that way we get the confirm prompt (if enabled)
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Qt::QueuedConnection,
Q_ARG(bool, true), Q_ARG(bool, true), Q_ARG(bool, true));
}
})
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](bool pressed) {
if (!pressed)
g_emu_thread->setVMPaused(VMManager::GetState() != VMState::Paused);

View File

@ -57,7 +57,7 @@ public Q_SLOTS:
void startVM(std::shared_ptr<VMBootParameters> boot_params);
void resetVM();
void setVMPaused(bool paused);
bool shutdownVM(bool allow_confirm = true, bool allow_save_to_state = true, bool blocking = false);
bool shutdownVM(bool allow_save_to_state = true);
void loadState(const QString& filename);
void loadStateFromSlot(qint32 slot);
void saveState(const QString& filename);

View File

@ -27,6 +27,7 @@
#include "pcsx2/CDVD/CDVDaccess.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/GSDumpReplayer.h"
#include "pcsx2/HostDisplay.h"
#include "AboutDialog.h"
@ -131,7 +132,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionChangeDiscFromGameList, &QAction::triggered, this, &MainWindow::onChangeDiscFromGameListActionTriggered);
connect(m_ui.menuChangeDisc, &QMenu::aboutToShow, this, &MainWindow::onChangeDiscMenuAboutToShow);
connect(m_ui.menuChangeDisc, &QMenu::aboutToHide, this, &MainWindow::onChangeDiscMenuAboutToHide);
connect(m_ui.actionPowerOff, &QAction::triggered, []() { g_emu_thread->shutdownVM(); });
connect(m_ui.actionPowerOff, &QAction::triggered, this, [this]() { requestShutdown(); });
connect(m_ui.actionLoadState, &QAction::triggered, this, [this]() { m_ui.menuLoadState->exec(QCursor::pos()); });
connect(m_ui.actionSaveState, &QAction::triggered, this, [this]() { m_ui.menuSaveState->exec(QCursor::pos()); });
connect(m_ui.actionExit, &QAction::triggered, this, &MainWindow::close);
@ -236,7 +237,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread)
void MainWindow::recreate()
{
if (m_vm_valid)
g_emu_thread->shutdownVM(false, true, true);
requestShutdown(false, true, true);
close();
g_main_window = nullptr;
@ -659,20 +660,38 @@ void MainWindow::reportError(const QString& title, const QString& message)
QMessageBox::critical(this, title, message);
}
bool MainWindow::confirmShutdown()
bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_save_to_state /* = true */, bool block_until_done /* = false */)
{
if (!m_vm_valid || !QtHost::GetBaseBoolSettingValue("UI", "ConfirmShutdown", true))
if (!VMManager::HasValidVM())
return true;
ScopedVMPause pauser(m_vm_paused);
// only confirm on UI thread because we need to display a msgbox
if (allow_confirm && !GSDumpReplayer::IsReplayingDump() && QtHost::GetBaseBoolSettingValue("UI", "ConfirmShutdown", true))
{
ScopedVMPause pauser(m_vm_paused);
if (QMessageBox::question(g_main_window, tr("Confirm Shutdown"),
tr("Are you sure you want to shut down the virtual machine?\n\nAll unsaved progress will be lost.")) != QMessageBox::Yes)
{
return false;
}
}
return (QMessageBox::question(g_main_window, tr("Confirm Shutdown"),
tr("Are you sure you want to shut down the virtual machine?\n\nAll unsaved progress will be lost.")) == QMessageBox::Yes);
g_emu_thread->shutdownVM(allow_save_to_state);
if (block_until_done)
{
// we need to yield here, since the display gets destroyed
while (VMManager::HasValidVM())
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
}
return true;
}
void MainWindow::requestExit()
{
if (!g_emu_thread->shutdownVM(true, true, false))
// this is block, because otherwise closeEvent() will also prompt
if (!requestShutdown(true, true, true))
return;
close();
@ -1021,7 +1040,7 @@ void MainWindow::onGameChanged(const QString& path, const QString& serial, const
void MainWindow::closeEvent(QCloseEvent* event)
{
if (!g_emu_thread->shutdownVM(true, true, true))
if (!requestShutdown(true, true, true))
{
event->ignore();
return;

View File

@ -54,7 +54,7 @@ public Q_SLOTS:
void refreshGameList(bool invalidate_cache);
void invalidateSaveStateCache();
void reportError(const QString& title, const QString& message);
bool confirmShutdown();
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool block_until_done = false);
void requestExit();
private Q_SLOTS:

View File

@ -247,6 +247,7 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
si.SetStringValue("Hotkeys", "TogglePause", "Keyboard/Space");
si.SetStringValue("Hotkeys", "ToggleSlowMotion", "Keyboard/Shift & Keyboard/Backtab");
si.SetStringValue("Hotkeys", "ToggleTurbo", "Keyboard/Tab");
si.SetStringValue("Hotkeys", "ShutdownVM", "Keyboard/Escape");
}
void PAD::Update()

View File

@ -1349,6 +1349,10 @@ DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](bool presse
if (!pressed)
HotkeyAdjustTargetSpeed(-0.1);
})
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](bool pressed) {
if (!pressed && VMManager::HasValidVM())
VMManager::Reset();
})
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](bool pressed) {
if (!pressed)