Misc: Backports from PCSX2 UI

This commit is contained in:
Connor McLaughlin
2022-10-23 14:09:54 +10:00
parent 8438506206
commit 72dfbaf6cc
37 changed files with 1037 additions and 271 deletions

View File

@ -24,10 +24,6 @@
#include "settingwidgetbinder.h"
#include "util/cd_image.h"
#ifdef WITH_CHEEVOS
#include "frontend-common/achievements.h"
#endif
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
@ -43,6 +39,15 @@
#include <QtWidgets/QStyleFactory>
#include <cmath>
#ifdef WITH_CHEEVOS
#include "frontend-common/achievements.h"
#endif
#ifdef _WIN32
#include "common/windows_headers.h"
#include <Dbt.h>
#endif
Log_SetChannel(MainWindow);
static constexpr char DISC_IMAGE_FILTER[] = QT_TRANSLATE_NOOP(
@ -101,6 +106,10 @@ MainWindow::~MainWindow()
// we compare here, since recreate destroys the window later
if (g_main_window == this)
g_main_window = nullptr;
#ifdef _WIN32
unregisterForDeviceNotifications();
#endif
}
void MainWindow::updateApplicationTheme()
@ -129,6 +138,10 @@ void MainWindow::initialize()
if (Achievements::IsUsingRAIntegration())
Achievements::RAIntegration::MainWindowChanged((void*)winId());
#endif
#ifdef _WIN32
registerForDeviceNotifications();
#endif
}
void MainWindow::reportError(const QString& title, const QString& message)
@ -143,6 +156,48 @@ bool MainWindow::confirmMessage(const QString& title, const QString& message)
return (QMessageBox::question(this, title, message) == QMessageBox::Yes);
}
void MainWindow::registerForDeviceNotifications()
{
#ifdef _WIN32
// We use these notifications to detect when a controller is connected or disconnected.
DEV_BROADCAST_DEVICEINTERFACE_W filter = {sizeof(DEV_BROADCAST_DEVICEINTERFACE_W), DBT_DEVTYP_DEVICEINTERFACE};
m_device_notification_handle = RegisterDeviceNotificationW(
(HANDLE)winId(), &filter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
#endif
}
void MainWindow::unregisterForDeviceNotifications()
{
#ifdef _WIN32
if (!m_device_notification_handle)
return;
UnregisterDeviceNotification(static_cast<HDEVNOTIFY>(m_device_notification_handle));
m_device_notification_handle = nullptr;
#endif
}
#ifdef _WIN32
bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
{
static constexpr const char win_type[] = "windows_generic_MSG";
if (eventType == QByteArray(win_type, sizeof(win_type) - 1))
{
const MSG* msg = static_cast<const MSG*>(message);
if (msg->message == WM_DEVICECHANGE && msg->wParam == DBT_DEVNODES_CHANGED)
{
g_emu_thread->reloadInputDevices();
*result = 1;
return true;
}
}
return QMainWindow::nativeEvent(eventType, message, result);
}
#endif
bool MainWindow::createDisplay(bool fullscreen, bool render_to_main)
{
Log_DevPrintf("createDisplay(%u, %u)", static_cast<u32>(fullscreen), static_cast<u32>(render_to_main));
@ -650,6 +705,9 @@ void MainWindow::recreate()
if (s_system_valid)
requestShutdown(false, true, true);
// We need to close input sources, because e.g. DInput uses our window handle.
g_emu_thread->closeInputSources();
close();
g_main_window = nullptr;
@ -657,6 +715,9 @@ void MainWindow::recreate()
new_main_window->initialize();
new_main_window->show();
deleteLater();
// Reload the sources we just closed.
g_emu_thread->reloadInputSources();
}
void MainWindow::populateGameListContextMenu(const GameList::Entry* entry, QWidget* parent_window, QMenu* menu)
@ -1658,7 +1719,7 @@ void MainWindow::updateWindowState(bool force_visible)
return;
const bool hide_window = !isRenderingToMain() && shouldHideMainWindow();
const bool disable_resize = Host::GetBaseBoolSettingValue("Main", "DisableWindowResize", false);
const bool disable_resize = Host::GetBoolSettingValue("Main", "DisableWindowResize", false);
const bool has_window = s_system_valid || m_display_widget;
// Need to test both valid and display widget because of startup (vm invalid while window is created).
@ -1730,8 +1791,8 @@ bool MainWindow::shouldHideMouseCursor() const
bool MainWindow::shouldHideMainWindow() const
{
return Host::GetBaseBoolSettingValue("Main", "HideMainWindowWhenRunning", false) || isRenderingFullscreen() ||
QtHost::InNoGUIMode();
return Host::GetBaseBoolSettingValue("Main", "HideMainWindowWhenRunning", false) ||
(g_emu_thread->shouldRenderToMain() && isRenderingFullscreen()) || QtHost::InNoGUIMode();
}
void MainWindow::switchToGameListView()
@ -2412,7 +2473,7 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav
// reshow the main window during display updates, because otherwise fullscreen transitions and renderer switches
// would briefly show and then hide the main window. So instead, we do it on shutdown, here. Except if we're in
// batch mode, when we're going to exit anyway.
if (!isRenderingToMain() && isHidden() && !QtHost::InBatchMode())
if (!isRenderingToMain() && isHidden() && !QtHost::InBatchMode() && !g_emu_thread->isRunningFullscreenUI())
updateWindowState(true);
// Now we can actually shut down the VM.

View File

@ -169,6 +169,10 @@ protected:
void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent* event) override;
#ifdef _WIN32
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
#endif
private:
static void setStyleFromSettings();
static void setIconThemeFromSettings();
@ -218,6 +222,9 @@ private:
void setTheme(const QString& theme);
void recreate();
void registerForDeviceNotifications();
void unregisterForDeviceNotifications();
/// Fills menu with save state info and handlers.
void populateGameListContextMenu(const GameList::Entry* entry, QWidget* parent_window, QMenu* menu);
@ -271,6 +278,10 @@ private:
bool m_is_closing = false;
GDBServer* m_gdb_server = nullptr;
#ifdef _WIN32
void* m_device_notification_handle = nullptr;
#endif
};
extern MainWindow* g_main_window;

View File

@ -376,7 +376,7 @@ void QtHost::SetDefaultSettings(SettingsInterface& si, bool system, bool control
bool EmuThread::shouldRenderToMain() const
{
return !Host::GetBaseBoolSettingValue("Main", "RenderToSeparateWindow", false) && !QtHost::InNoGUIMode();
return !Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) && !QtHost::InNoGUIMode();
}
void Host::RequestResizeHostDisplay(s32 new_window_width, s32 new_window_height)
@ -895,6 +895,28 @@ void EmuThread::reloadInputBindings()
InputManager::ReloadBindings(*si, *bindings_si);
}
void EmuThread::reloadInputDevices()
{
if (!isOnThread())
{
QMetaObject::invokeMethod(this, &EmuThread::reloadInputDevices, Qt::QueuedConnection);
return;
}
InputManager::ReloadDevices();
}
void EmuThread::closeInputSources()
{
if (!isOnThread())
{
QMetaObject::invokeMethod(this, &EmuThread::reloadInputDevices, Qt::BlockingQueuedConnection);
return;
}
InputManager::CloseSources();
}
void EmuThread::enumerateInputDevices()
{
if (!isOnThread())

View File

@ -148,6 +148,8 @@ public Q_SLOTS:
void updateEmuFolders();
void reloadInputSources();
void reloadInputBindings();
void reloadInputDevices();
void closeInputSources();
void enumerateInputDevices();
void enumerateVibrationMotors();
void startFullscreenUI();