Add monitor selector functionality for windowed

When using windowed mode, the game will launch on the monitor selected in the Display Monitor setting.

  If rendering to the main window and the selected monitor differs from the current one, the main window will be moved there and restored to its     original position when the game ends.
This commit is contained in:
jasaaved
2026-03-25 00:39:19 -07:00
parent cfb944b0ca
commit d0108b3572
6 changed files with 44 additions and 10 deletions

View File

@@ -294,7 +294,7 @@ const Info<std::string> MAIN_WII_NUS_SHOP_URL{{System::Main, "Core", "WiiNusShop
const Info<std::string> MAIN_FULLSCREEN_DISPLAY_RES{
{System::Main, "Display", "FullscreenDisplayRes"}, "Auto"};
const Info<bool> MAIN_FULLSCREEN{{System::Main, "Display", "Fullscreen"}, false};
const Info<int> MAIN_FULLSCREEN_MONITOR{{System::Main, "Display", "FullscreenMonitor"}, 0};
const Info<int> MAIN_DISPLAY_MONITOR{{System::Main, "Display", "DisplayMonitor"}, 0};
const Info<bool> MAIN_RENDER_TO_MAIN{{System::Main, "Display", "RenderToMain"}, false};
const Info<int> MAIN_RENDER_WINDOW_XPOS{{System::Main, "Display", "RenderWindowXPos"}, -1};
const Info<int> MAIN_RENDER_WINDOW_YPOS{{System::Main, "Display", "RenderWindowYPos"}, -1};

View File

@@ -191,7 +191,7 @@ bool ShouldUseDPL2Decoder();
extern const Info<std::string> MAIN_FULLSCREEN_DISPLAY_RES;
extern const Info<bool> MAIN_FULLSCREEN;
extern const Info<int> MAIN_FULLSCREEN_MONITOR;
extern const Info<int> MAIN_DISPLAY_MONITOR;
extern const Info<bool> MAIN_RENDER_TO_MAIN;
extern const Info<int> MAIN_RENDER_WINDOW_XPOS;
extern const Info<int> MAIN_RENDER_WINDOW_YPOS;

View File

@@ -98,11 +98,11 @@ void GeneralWidget::CreateWidgets()
const QList<QScreen*> screens = QGuiApplication::screens();
for (int i = 0; i < screens.size(); i++)
m_monitor_combo->addItem(tr("Monitor %1: %2").arg(i + 1).arg(screens[i]->name()));
const int monitor_index = Config::Get(Config::MAIN_FULLSCREEN_MONITOR);
const int monitor_index = Config::Get(Config::MAIN_DISPLAY_MONITOR);
if (monitor_index < m_monitor_combo->count())
m_monitor_combo->setCurrentIndex(monitor_index);
video_layout->addWidget(new QLabel(tr("Fullscreen Monitor:")), 4, 0);
video_layout->addWidget(new QLabel(tr("Display Monitor:")), 4, 0);
video_layout->addWidget(m_monitor_combo, 4, 1, 1, -1);
auto* const basic_grid = new QGridLayout;
@@ -171,7 +171,7 @@ void GeneralWidget::ConnectWidgets()
emit BackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
});
connect(m_monitor_combo, &QComboBox::currentIndexChanged, this, [](int index) {
Config::SetBaseOrCurrent(Config::MAIN_FULLSCREEN_MONITOR, index);
Config::SetBaseOrCurrent(Config::MAIN_DISPLAY_MONITOR, index);
});
connect(m_aspect_combo, &QComboBox::currentIndexChanged, this,
&GeneralWidget::ToggleCustomAspectRatio);
@@ -325,9 +325,10 @@ void GeneralWidget::AddDescriptions()
m_adapter_combo->SetTitle(tr("Adapter"));
m_monitor_combo->SetTitle(tr("Fullscreen Monitor"));
m_monitor_combo->SetTitle(tr("Display Monitor"));
m_monitor_combo->SetDescription(
tr("Selects which display to use for fullscreen.<br><br>"
tr("Selects which display to use when rendering.<br><br>"
"When rendering to the main window, the main window will be moved to this display.<br><br>"
"<dolphin_emphasis>If unsure, select Primary Monitor.</dolphin_emphasis>"));
m_aspect_combo->SetTitle(tr("Aspect Ratio"));

View File

@@ -13,6 +13,7 @@
#include <QFileInfo>
#include <QIcon>
#include <QMimeData>
#include <QScreen>
#include <QStackedWidget>
#include <QStyleHints>
#include <QVBoxLayout>
@@ -900,6 +901,12 @@ void MainWindow::OnStopComplete()
{
m_stop_requested = false;
HideRenderWidget(!m_exit_requested, m_exit_requested);
if (!m_pre_game_main_window_geometry.isEmpty())
{
restoreGeometry(m_pre_game_main_window_geometry);
m_pre_game_main_window_geometry.clear();
}
#ifdef USE_DISCORD_PRESENCE
if (!m_netplay_dialog->isVisible())
Discord::UpdateDiscordPresence();
@@ -1244,8 +1251,24 @@ void MainWindow::ShowRenderWidget()
SetFullScreenResolution(false);
Host::GetInstance()->SetRenderFullscreen(false);
const int monitor_index = Config::Get(Config::MAIN_DISPLAY_MONITOR);
const QList<QScreen*> screens = QGuiApplication::screens();
QScreen* const target_screen = (monitor_index > 0 && monitor_index <= screens.size())
? screens[monitor_index - 1]
: QGuiApplication::primaryScreen();
if (Config::Get(Config::MAIN_RENDER_TO_MAIN))
{
// Move the main window to the selected monitor if it isn't already there.
// Guard with isEmpty() so fullscreen toggles don't overwrite the saved geometry.
if (monitor_index > 0 && screen() != target_screen &&
m_pre_game_main_window_geometry.isEmpty())
{
m_pre_game_main_window_geometry = saveGeometry();
const QRect geo = target_screen->availableGeometry();
move(geo.x() + (geo.width() - width()) / 2, geo.y() + (geo.height() - height()) / 2);
}
// If we're rendering to main, add it to the stack and update our title when necessary.
m_rendering_to_main = true;
@@ -1258,11 +1281,17 @@ void MainWindow::ShowRenderWidget()
}
else
{
// Otherwise, just show it.
// Separate window: restore saved size, then center on the selected monitor if one is set.
m_rendering_to_main = false;
m_render_widget->showNormal();
m_render_widget->restoreGeometry(m_render_widget_geometry);
if (monitor_index > 0)
{
const QRect geo = target_screen->availableGeometry();
m_render_widget->move(geo.x() + (geo.width() - m_render_widget->width()) / 2,
geo.y() + (geo.height() - m_render_widget->height()) / 2);
}
}
}

View File

@@ -291,4 +291,5 @@ private:
WatchWidget* m_watch_widget;
CheatsManager* m_cheats_manager{};
QByteArray m_render_widget_geometry;
QByteArray m_pre_game_main_window_geometry;
};

View File

@@ -206,13 +206,16 @@ void RenderWidget::HandleCursorTimer()
void RenderWidget::showFullScreen()
{
const int monitor_index = Config::Get(Config::MAIN_FULLSCREEN_MONITOR);
const int monitor_index = Config::Get(Config::MAIN_DISPLAY_MONITOR);
const QList<QScreen*> screens = QGuiApplication::screens();
QScreen* const target_screen = (monitor_index > 0 && monitor_index <= screens.size())
? screens[monitor_index - 1]
: QGuiApplication::primaryScreen();
if (monitor_index > 0)
move(target_screen->availableGeometry().topLeft());
{
const QRect geo = target_screen->geometry();
move(geo.x() + (geo.width() - width()) / 2, geo.y() + (geo.height() - height()) / 2);
}
QWidget::showFullScreen();