mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-12 02:08:45 +00:00
Add a variable to keep track if the window was in exclusive fullscreen. This helps prevent saving geometry to config which is for windows rendered separate from main. The variable is set back to false when render window is released.
336 lines
11 KiB
C++
336 lines
11 KiB
C++
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
|
|
#pragma once
|
|
|
|
#include "common/WindowInfo.h"
|
|
|
|
#include <QtWidgets/QLabel>
|
|
#include <QtWidgets/QMainWindow>
|
|
#include <QtWidgets/QMenu>
|
|
#include <functional>
|
|
#include <optional>
|
|
|
|
#include "Tools/InputRecording/InputRecordingViewer.h"
|
|
#include "Settings/ControllerSettingsWindow.h"
|
|
#include "Settings/SettingsWindow.h"
|
|
#include "Debugger/DebuggerWindow.h"
|
|
#include "ui_MainWindow.h"
|
|
|
|
class QProgressBar;
|
|
|
|
class AutoUpdaterDialog;
|
|
class DisplaySurface;
|
|
class DisplayContainer;
|
|
class GameListWidget;
|
|
class ControllerSettingsWindow;
|
|
|
|
class EmuThread;
|
|
|
|
namespace Achievements
|
|
{
|
|
enum class LoginRequestReason;
|
|
}
|
|
|
|
namespace GameList
|
|
{
|
|
struct Entry;
|
|
}
|
|
|
|
enum class CDVD_SourceType : uint8_t;
|
|
|
|
class MainWindow final : public QMainWindow
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/// This class is a scoped lock on the VM, which prevents it from running while
|
|
/// the object exists. Its purpose is to be used for blocking/modal popup boxes,
|
|
/// where the VM needs to exit fullscreen temporarily.
|
|
class VMLock
|
|
{
|
|
public:
|
|
VMLock(VMLock&& lock);
|
|
VMLock(const VMLock&) = delete;
|
|
~VMLock();
|
|
|
|
VMLock& operator=(VMLock&& lock);
|
|
VMLock& operator=(const VMLock&) = delete;
|
|
|
|
/// Returns the parent widget, which can be used for any popup dialogs.
|
|
__fi QWidget* getDialogParent() const { return m_dialog_parent; }
|
|
|
|
/// Cancels any pending unpause/fullscreen transition.
|
|
/// Call when you're going to destroy the VM anyway.
|
|
void cancelResume();
|
|
|
|
private:
|
|
VMLock(QWidget* dialog_parent, bool was_paused, bool was_exclusive_fullscreen, bool owns_parent);
|
|
friend MainWindow;
|
|
|
|
QWidget* m_dialog_parent;
|
|
bool m_has_lock;
|
|
bool m_was_paused;
|
|
bool m_was_fullscreen;
|
|
bool m_owns_dialog_parent;
|
|
};
|
|
|
|
/// Default filter for opening a file.
|
|
static const char* OPEN_FILE_FILTER;
|
|
|
|
/// Default filter for opening a disc image.
|
|
static const char* DISC_IMAGE_FILTER;
|
|
|
|
public:
|
|
MainWindow();
|
|
~MainWindow();
|
|
|
|
void initialize();
|
|
void connectVMThreadSignals(EmuThread* thread);
|
|
void startupUpdateCheck();
|
|
void resetSettings(bool ui);
|
|
void quit();
|
|
|
|
/// Locks the VM by pausing it, while a popup dialog is displayed.
|
|
VMLock pauseAndLockVM();
|
|
|
|
/// Accessors for the status bar widgets, updated by the emulation thread.
|
|
__fi QLabel* getStatusVerboseWidget() const { return m_status_verbose_widget; }
|
|
__fi QLabel* getStatusRendererWidget() const { return m_status_renderer_widget; }
|
|
__fi QLabel* getStatusResolutionWidget() const { return m_status_resolution_widget; }
|
|
__fi QLabel* getStatusFPSWidget() const { return m_status_fps_widget; }
|
|
__fi QLabel* getStatusVPSWidget() const { return m_status_vps_widget; }
|
|
__fi QLabel* getStatusSpeedWidget() const { return m_status_speed_widget; }
|
|
|
|
/// Rescans a single file. NOTE: Happens on UI thread.
|
|
void rescanFile(const std::string& path);
|
|
|
|
/// Start a file from a user action (e.g. dragging a file onto the main window or with macOS open with)
|
|
bool startFile(const QString& path);
|
|
|
|
void doSettings(const char* category = nullptr);
|
|
void doGameSettings(const char* category = nullptr);
|
|
|
|
void openDebugger();
|
|
void checkMousePosition(int x, int y);
|
|
public Q_SLOTS:
|
|
void checkForUpdates(bool display_message, bool force_check);
|
|
void refreshGameList(bool invalidate_cache, bool popup_on_error);
|
|
void cancelGameListRefresh();
|
|
void updateGameListBackground();
|
|
void reportInfo(const QString& title, const QString& message);
|
|
void reportError(const QString& title, const QString& message);
|
|
bool confirmMessage(const QString& title, const QString& message);
|
|
void onStatusMessage(const QString& message);
|
|
void reportStateLoadError(const QString& message, std::optional<s32> slot, bool backup);
|
|
void reportStateSaveError(const QString& message, std::optional<s32> slot);
|
|
|
|
void runOnUIThread(const std::function<void()>& func);
|
|
void requestReset();
|
|
bool requestShutdown(bool allow_confirm = true, bool allow_save_to_state = true, bool default_save_to_state = true);
|
|
void requestExit(bool allow_confirm = true);
|
|
void checkForSettingChanges();
|
|
std::optional<WindowInfo> getWindowInfo();
|
|
|
|
private Q_SLOTS:
|
|
void onUpdateCheckComplete();
|
|
|
|
std::optional<WindowInfo> acquireRenderWindow(bool recreate_window, bool fullscreen, bool render_to_main, bool surfaceless);
|
|
void displayResizeRequested(qint32 width, qint32 height);
|
|
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
|
void mouseLockRequested(bool state);
|
|
void releaseRenderWindow();
|
|
void setupMouseMoveHandler();
|
|
void onGameListRefreshComplete();
|
|
void onGameListRefreshProgress(const QString& status, int current, int total);
|
|
void onGameListSelectionChanged();
|
|
void onGameListEntryActivated();
|
|
void onGameListEntryContextMenuRequested(const QPoint& point);
|
|
|
|
void onStartFileActionTriggered();
|
|
void onStartDiscActionTriggered();
|
|
void onStartBIOSActionTriggered();
|
|
void onChangeDiscFromFileActionTriggered();
|
|
void onChangeDiscFromGameListActionTriggered();
|
|
void onChangeDiscFromDeviceActionTriggered();
|
|
void onRemoveDiscActionTriggered();
|
|
void onChangeDiscMenuAboutToShow();
|
|
void onChangeDiscMenuAboutToHide();
|
|
void onLoadStateMenuAboutToShow();
|
|
void onSaveStateMenuAboutToShow();
|
|
void onStartFullscreenUITriggered();
|
|
void onFullscreenUIStateChange(bool running);
|
|
void onViewToolbarActionToggled(bool checked);
|
|
void onViewLockToolbarActionToggled(bool checked);
|
|
void onViewStatusBarActionToggled(bool checked);
|
|
void onViewGameListActionTriggered();
|
|
void onViewGameGridActionTriggered();
|
|
void onViewSystemDisplayTriggered();
|
|
void onViewGamePropertiesActionTriggered();
|
|
void onGitHubRepositoryActionTriggered();
|
|
void onSupportForumsActionTriggered();
|
|
void onWikiActionTriggered();
|
|
void onDocumentationActionTriggered();
|
|
void onDiscordServerActionTriggered();
|
|
void onAboutActionTriggered();
|
|
void onToolsOpenDataDirectoryTriggered();
|
|
void onToolsCoverDownloaderTriggered();
|
|
#if !defined(__APPLE__)
|
|
void onCreateGameShortcutTriggered();
|
|
#endif
|
|
void onToolsEditCheatsPatchesTriggered(bool cheats);
|
|
void onCreateMemoryCardOpenRequested();
|
|
void updateTheme();
|
|
void reloadThemeSpecificImages();
|
|
void updateLanguage();
|
|
void onThemeChanged();
|
|
void onLanguageChanged();
|
|
void onScreenshotActionTriggered();
|
|
void onSaveGSDumpActionTriggered();
|
|
void onBlockDumpActionToggled(bool checked);
|
|
void onShowAdvancedSettingsToggled(bool checked);
|
|
void onVideoCaptureToggled(bool checked);
|
|
void onSettingsTriggeredFromToolbar();
|
|
|
|
// Input Recording
|
|
void onInputRecNewActionTriggered();
|
|
void onInputRecPlayActionTriggered();
|
|
void onInputRecStopActionTriggered();
|
|
void onInputRecOpenViewer();
|
|
void onVMStarting();
|
|
void onVMStarted();
|
|
void onVMPaused();
|
|
void onVMResumed();
|
|
void onVMStopped();
|
|
|
|
void onGameChanged(const QString& title, const QString& elf_override, const QString& disc_path,
|
|
const QString& serial, quint32 disc_crc, quint32 crc);
|
|
|
|
void onCaptureStarted(const QString& filename);
|
|
void onCaptureStopped();
|
|
|
|
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
|
|
void onAchievementsHardcoreModeChanged(bool enabled);
|
|
|
|
protected:
|
|
void showEvent(QShowEvent* event) override;
|
|
void closeEvent(QCloseEvent* event) override;
|
|
void changeEvent(QEvent* event) override;
|
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
|
void dropEvent(QDropEvent* event) override;
|
|
void moveEvent(QMoveEvent* event) override;
|
|
void resizeEvent(QResizeEvent* event) override;
|
|
|
|
#ifdef _WIN32
|
|
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
|
|
#endif
|
|
|
|
private:
|
|
void setupAdditionalUi();
|
|
void connectSignals();
|
|
void createRendererSwitchMenu();
|
|
void recreate();
|
|
void recreateSettings();
|
|
void destroySubWindows();
|
|
|
|
void registerForDeviceNotifications();
|
|
void unregisterForDeviceNotifications();
|
|
|
|
void saveStateToConfig();
|
|
void restoreStateFromConfig();
|
|
|
|
void updateEmulationActions(bool starting, bool running, bool stopping);
|
|
void updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen);
|
|
void updateGameDependentActions();
|
|
void updateGameGridActions(const bool show_game_grid);
|
|
void updateStatusBarWidgetVisibility();
|
|
void updateAdvancedSettingsVisibility();
|
|
void updateWindowTitle();
|
|
void updateWindowState(bool force_visible = false);
|
|
void setProgressBar(int current, int total);
|
|
void clearProgressBar();
|
|
|
|
bool isShowingGameList() const;
|
|
bool isRenderingFullscreen() const;
|
|
bool isRenderingToMain() const;
|
|
bool shouldHideMouseCursor() const;
|
|
bool shouldHideMainWindow() const;
|
|
bool shouldMouseLock() const;
|
|
void switchToGameListView();
|
|
void switchToEmulationView();
|
|
|
|
bool shouldAbortForMemcardBusy(const VMLock& lock);
|
|
|
|
QWidget* getContentParent();
|
|
void saveDisplayWindowGeometryToConfig();
|
|
void restoreDisplayWindowGeometryFromConfig();
|
|
void createDisplayWidget(bool fullscreen, bool render_to_main);
|
|
void destroyDisplayWidget(bool show_game_list);
|
|
void updateDisplayWidgetCursor();
|
|
|
|
SettingsWindow* getSettingsWindow();
|
|
|
|
InputRecordingViewer* getInputRecordingViewer();
|
|
void updateInputRecordingActions(bool started);
|
|
|
|
void doControllerSettings(ControllerSettingsWindow::Category category = ControllerSettingsWindow::Category::Count);
|
|
|
|
QString getDiscDevicePath(const QString& title);
|
|
|
|
void startGameListEntry(
|
|
const GameList::Entry& entry, std::optional<s32> save_slot = std::nullopt, std::optional<bool> fast_boot = std::nullopt, bool load_backup = false);
|
|
void setGameListEntryCoverImage(const GameList::Entry& entry);
|
|
void clearGameListEntryPlayTime(const GameList::Entry& entry, const time_t entry_played_time);
|
|
void goToWikiPage(const GameList::Entry& entry);
|
|
void openMemoryCardFolder();
|
|
void openSnapshotsFolderForGame(const GameList::Entry& entry);
|
|
void openTextureFolderForGame(const GameList::Entry& entry);
|
|
void openVideoCaptureFolder(const GameList::Entry& entry);
|
|
|
|
std::optional<bool> promptForResumeState(const QString& save_state_path);
|
|
void loadSaveStateSlot(s32 slot, bool load_backup = false);
|
|
void loadSaveStateFile(const QString& filename, const QString& state_filename);
|
|
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
|
|
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
|
|
void doStartFile(std::optional<CDVD_SourceType> source, const QString& path);
|
|
void doDiscChange(CDVD_SourceType source, const QString& path);
|
|
|
|
Ui::MainWindow m_ui;
|
|
|
|
GameListWidget* m_game_list_widget = nullptr;
|
|
DisplaySurface* m_display_surface = nullptr;
|
|
QWidget* m_display_container = nullptr;
|
|
|
|
SettingsWindow* m_settings_window = nullptr;
|
|
ControllerSettingsWindow* m_controller_settings_window = nullptr;
|
|
InputRecordingViewer* m_input_recording_viewer = nullptr;
|
|
AutoUpdaterDialog* m_auto_updater_dialog = nullptr;
|
|
|
|
QProgressBar* m_status_progress_widget = nullptr;
|
|
QLabel* m_status_verbose_widget = nullptr;
|
|
QLabel* m_status_renderer_widget = nullptr;
|
|
QLabel* m_status_fps_widget = nullptr;
|
|
QLabel* m_status_vps_widget = nullptr;
|
|
QLabel* m_status_speed_widget = nullptr;
|
|
QLabel* m_status_resolution_widget = nullptr;
|
|
|
|
QMenu* m_settings_toolbar_menu = nullptr;
|
|
|
|
bool m_display_created = false;
|
|
bool m_display_is_exclusive_fullscreen = false;
|
|
bool m_relative_mouse_mode = false;
|
|
bool m_hide_mouse_cursor = false;
|
|
bool m_was_paused_on_surface_loss = false;
|
|
bool m_was_disc_change_request = false;
|
|
bool m_is_closing = false;
|
|
bool m_is_temporarily_windowed = false;
|
|
|
|
QString m_last_fps_status;
|
|
|
|
#ifdef _WIN32
|
|
void* m_device_notification_handle = nullptr;
|
|
#endif
|
|
};
|
|
|
|
extern MainWindow* g_main_window;
|