mirror of https://github.com/PCSX2/pcsx2.git
Host: Add ConfirmMessage() and OpenURL()
This commit is contained in:
parent
d18c8976b9
commit
a19045f9d6
|
@ -91,6 +91,41 @@ void EmuThread::stopInThread()
|
|||
m_shutdown_flag.store(true);
|
||||
}
|
||||
|
||||
bool EmuThread::confirmMessage(const QString& title, const QString& message)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
// This is definitely deadlock risky, but unlikely to happen (why would GS be confirming?).
|
||||
bool result = false;
|
||||
QMetaObject::invokeMethod(g_emu_thread, "confirmMessage", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result), Q_ARG(const QString&, title), Q_ARG(const QString&, message));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Easy if there's no VM.
|
||||
if (!VMManager::HasValidVM())
|
||||
return emit messageConfirmed(title, message);
|
||||
|
||||
// Preemptively pause/set surfaceless on the emu thread, because it can't run while the popup is open.
|
||||
const bool was_paused = (VMManager::GetState() == VMState::Paused);
|
||||
const bool was_fullscreen = isFullscreen();
|
||||
if (!was_paused)
|
||||
VMManager::SetPaused(true);
|
||||
if (was_fullscreen)
|
||||
setSurfaceless(true);
|
||||
|
||||
// This won't return until the user confirms one way or another.
|
||||
const bool result = emit messageConfirmed(title, message);
|
||||
|
||||
// Resume VM after confirming.
|
||||
if (was_fullscreen)
|
||||
setSurfaceless(false);
|
||||
if (!was_paused)
|
||||
VMManager::SetPaused(false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
void updatePerformanceMetrics(bool force);
|
||||
|
||||
public Q_SLOTS:
|
||||
bool confirmMessage(const QString& title, const QString& message);
|
||||
void startVM(std::shared_ptr<VMBootParameters> boot_params);
|
||||
void resetVM();
|
||||
void setVMPaused(bool paused);
|
||||
|
@ -88,6 +89,8 @@ public Q_SLOTS:
|
|||
void queueSnapshot(quint32 gsdump_frames);
|
||||
|
||||
Q_SIGNALS:
|
||||
bool messageConfirmed(const QString& title, const QString& message);
|
||||
|
||||
DisplayWidget* onCreateDisplayRequested(bool fullscreen, bool render_to_main);
|
||||
DisplayWidget* onUpdateDisplayRequested(bool fullscreen, bool render_to_main, bool surfaceless);
|
||||
void onResizeDisplayRequested(qint32 width, qint32 height);
|
||||
|
|
|
@ -354,6 +354,7 @@ void MainWindow::connectSignals()
|
|||
|
||||
void MainWindow::connectVMThreadSignals(EmuThread* thread)
|
||||
{
|
||||
connect(thread, &EmuThread::messageConfirmed, this, &MainWindow::confirmMessage, Qt::BlockingQueuedConnection);
|
||||
connect(thread, &EmuThread::onCreateDisplayRequested, this, &MainWindow::createDisplay, Qt::BlockingQueuedConnection);
|
||||
connect(thread, &EmuThread::onUpdateDisplayRequested, this, &MainWindow::updateDisplay, Qt::BlockingQueuedConnection);
|
||||
connect(thread, &EmuThread::onDestroyDisplayRequested, this, &MainWindow::destroyDisplay, Qt::BlockingQueuedConnection);
|
||||
|
@ -1002,6 +1003,12 @@ void MainWindow::reportError(const QString& title, const QString& message)
|
|||
QMessageBox::critical(this, title, message);
|
||||
}
|
||||
|
||||
bool MainWindow::confirmMessage(const QString& title, const QString& message)
|
||||
{
|
||||
VMLock lock(pauseAndLockVM());
|
||||
return (QMessageBox::question(this, title, message) == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void MainWindow::runOnUIThread(const std::function<void()>& func)
|
||||
{
|
||||
func();
|
||||
|
|
|
@ -102,6 +102,7 @@ public Q_SLOTS:
|
|||
void cancelGameListRefresh();
|
||||
void invalidateSaveStateCache();
|
||||
void reportError(const QString& title, const QString& message);
|
||||
bool confirmMessage(const QString& title, const QString& message);
|
||||
void runOnUIThread(const std::function<void()>& func);
|
||||
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool block_until_done = false);
|
||||
void requestExit();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtGui/QClipboard>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include "GameList/GameListWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
static constexpr u32 SETTINGS_VERSION = 1;
|
||||
|
@ -432,6 +434,30 @@ void Host::ReportErrorAsync(const std::string_view& title, const std::string_vie
|
|||
Q_ARG(const QString&, message.empty() ? QString() : QString::fromUtf8(message.data(), message.size())));
|
||||
}
|
||||
|
||||
bool Host::ConfirmMessage(const std::string_view& title, const std::string_view& message)
|
||||
{
|
||||
const QString qtitle(QString::fromUtf8(title.data(), title.size()));
|
||||
const QString qmessage(QString::fromUtf8(message.data(), message.size()));
|
||||
return g_emu_thread->confirmMessage(qtitle, qmessage);
|
||||
}
|
||||
|
||||
void Host::OpenURL(const std::string_view& url)
|
||||
{
|
||||
QtHost::RunOnUIThread([url = QtUtils::StringViewToQString(url)]() {
|
||||
QtUtils::OpenURL(g_main_window, QUrl(url));
|
||||
});
|
||||
}
|
||||
|
||||
bool Host::CopyTextToClipboard(const std::string_view& text)
|
||||
{
|
||||
QtHost::RunOnUIThread([text = QtUtils::StringViewToQString(text)]() {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
if (clipboard)
|
||||
clipboard->setText(text);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name)
|
||||
{
|
||||
emit g_emu_thread->onInputDeviceConnected(
|
||||
|
|
|
@ -25,4 +25,14 @@ void Host::ReportFormattedErrorAsync(const std::string_view& title, const char*
|
|||
std::string message(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
ReportErrorAsync(title, message);
|
||||
}
|
||||
}
|
||||
|
||||
bool Host::ConfirmFormattedMessage(const std::string_view& title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message = StringUtil::StdStringFromFormatV(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ConfirmMessage(title, message);
|
||||
}
|
||||
|
|
10
pcsx2/Host.h
10
pcsx2/Host.h
|
@ -62,4 +62,14 @@ namespace Host
|
|||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportErrorAsync(const std::string_view& title, const std::string_view& message);
|
||||
void ReportFormattedErrorAsync(const std::string_view& title, const char* format, ...);
|
||||
|
||||
/// Displays a synchronous confirmation on the UI thread, i.e. blocks the caller.
|
||||
bool ConfirmMessage(const std::string_view& title, const std::string_view& message);
|
||||
bool ConfirmFormattedMessage(const std::string_view& title, const char* format, ...);
|
||||
|
||||
/// Opens a URL, using the default application.
|
||||
void OpenURL(const std::string_view& url);
|
||||
|
||||
/// Copies the provided text to the host's clipboard, if present.
|
||||
bool CopyTextToClipboard(const std::string_view& text);
|
||||
} // namespace Host
|
||||
|
|
|
@ -102,6 +102,11 @@ void Host::ReportErrorAsync(const std::string_view& title, const std::string_vie
|
|||
MsgButtons().OK()));
|
||||
}
|
||||
|
||||
bool Host::ConfirmMessage(const std::string_view& title, const std::string_view& message)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::unique_ptr<HostDisplay> s_host_display;
|
||||
|
||||
HostDisplay* Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
|
|
Loading…
Reference in New Issue