Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 62 additions & 7 deletions pcsx2-qt/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2549,6 +2549,9 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
}

m_display_surface = new DisplaySurface();
const int monitor_index = Host::GetBaseIntSettingValue("UI", "DisplayMonitor", 0);
const QList<QScreen*> screens = QGuiApplication::screens();
QScreen* target_screen = (monitor_index > 0 && monitor_index <= screens.size()) ? screens[monitor_index - 1] : QGuiApplication::primaryScreen();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why -1 on the index? isn't the combobox index (which gets saved to the settings) zero-based?

Copy link
Copy Markdown
Author

@jasaaved jasaaved Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the default monitor takes up two slots in the combo box (default and monitor 1, in this case monitor 1 is my default). For example, monitor 2 is index 2 in the combo box but monitor 2 is in index 1 in what Qt returns in screens. That's why I subtract 1.

In my setup, my combobox looks like: Default, Monitor 1, Monitor 2. Default is always at index 0.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I missed the first addItem() on line 126. That explains it, thanks.

if (fullscreen || !render_to_main)
{
#ifdef DISPLAY_SURFACE_WINDOW
Expand All @@ -2569,10 +2572,12 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
{
// On Wayland, while move/restoreGeometry can't position the window, it can influence which screen they show up on.
// Other platforms can position windows fine, but the only thing that matters here is the screen.
m_display_surface->setScreen(target_screen);

#ifdef DISPLAY_SURFACE_WINDOW
if (isVisible() && g_emu_thread->shouldRenderToMain())
m_display_surface->setPosition(screen()->availableGeometry().topLeft());
m_display_surface->create();
if (monitor_index > 0 || (isVisible() && g_emu_thread->shouldRenderToMain()))
m_display_surface->setPosition(target_screen->availableGeometry().topLeft());
else
restoreDisplayWindowGeometryFromConfig();

Expand All @@ -2581,8 +2586,8 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
else
m_display_surface->showNormal();
#else
if (isVisible() && g_emu_thread->shouldRenderToMain())
m_display_container->move(screen()->availableGeometry().topLeft());
if (monitor_index > 0 || (isVisible() && g_emu_thread->shouldRenderToMain()))
m_display_container->move(target_screen->availableGeometry().topLeft());
else
restoreDisplayWindowGeometryFromConfig();

Expand All @@ -2598,18 +2603,33 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
m_display_surface->setGeometry(geometry());
else
restoreDisplayWindowGeometryFromConfig();
restoreDisplayWindowGeometryFromConfig(monitor_index > 0 ? target_screen : nullptr);
m_display_surface->showNormal();
#else
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
m_display_container->setGeometry(geometry());
else
restoreDisplayWindowGeometryFromConfig();
restoreDisplayWindowGeometryFromConfig(monitor_index > 0 ? target_screen : nullptr);
m_display_container->showNormal();
#endif
}
else
{
if (monitor_index > 0)
{
if (screen() != target_screen)
m_pre_game_main_window_geometry = saveGeometry();

if (!m_target_screen_main_window_geometry.isEmpty())
restoreGeometry(m_target_screen_main_window_geometry);
else
{
const QRect screenGeo = target_screen->availableGeometry();
const QPoint center(screenGeo.x() + (screenGeo.width() - width()) / 2,
screenGeo.y() + (screenGeo.height() - height()) / 2);
move(center);
}
}
Comment on lines +2618 to +2632
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above

pxAssertRel(m_ui.mainContainer->count() == 1, "Has no display widget");
m_ui.mainContainer->addWidget(m_display_container);
m_ui.mainContainer->setCurrentIndex(1);
Expand Down Expand Up @@ -2716,6 +2736,18 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
{
pxAssertRel(m_ui.mainContainer->indexOf(m_display_container) == 1, "Display widget in stack");
m_ui.mainContainer->removeWidget(m_display_container);
if (!m_pre_game_main_window_geometry.isEmpty())
{
const int monitor_index = Host::GetBaseIntSettingValue("UI", "DisplayMonitor", 0);
const QList<QScreen*> screens = QGuiApplication::screens();
QScreen* target_screen = (monitor_index > 0 && monitor_index <= screens.size()) ? screens[monitor_index - 1] : nullptr;
if (target_screen && screen() == target_screen)
m_target_screen_main_window_geometry = saveGeometry();
else
m_target_screen_main_window_geometry.clear();
restoreGeometry(m_pre_game_main_window_geometry);
m_pre_game_main_window_geometry.clear();
}
if (show_game_list)
{
m_ui.mainContainer->setCurrentIndex(0);
Expand Down Expand Up @@ -2827,10 +2859,11 @@ void MainWindow::saveDisplayWindowGeometryToConfig()
}
}

void MainWindow::restoreDisplayWindowGeometryFromConfig()
void MainWindow::restoreDisplayWindowGeometryFromConfig(QScreen* target_screen)
{
const std::string geometry_b64 = Host::GetBaseStringSettingValue("UI", "DisplayWindowGeometry");
const QByteArray geometry = QByteArray::fromBase64(QByteArray::fromStdString(geometry_b64));

if (!geometry.isEmpty())
{
m_display_surface->restoreGeometry(geometry);
Expand All @@ -2849,6 +2882,28 @@ void MainWindow::restoreDisplayWindowGeometryFromConfig()
m_display_surface->resize(640, 480);
#else
m_display_container->resize(640, 480);
#endif
}

// if a target screen is specified and the window is not on it, center on it
if (target_screen)
{
#ifdef DISPLAY_SURFACE_WINDOW
if (!target_screen->availableGeometry().contains(m_display_surface->geometry()))
{
const QRect screenGeo = target_screen->availableGeometry();
const QPoint center(screenGeo.x() + (screenGeo.width() - m_display_surface->width()) / 2,
screenGeo.y() + (screenGeo.height() - m_display_surface->height()) / 2);
m_display_surface->setGeometry(QRect(center, m_display_surface->size()));
}
#else
if (!target_screen->availableGeometry().contains(m_display_container->geometry()))
{
const QRect screenGeo = target_screen->availableGeometry();
const QPoint center(screenGeo.x() + (screenGeo.width() - m_display_container->width()) / 2,
screenGeo.y() + (screenGeo.height() - m_display_container->height()) / 2);
m_display_container->setGeometry(QRect(center, m_display_container->size()));
}
#endif
}
}
Expand Down
4 changes: 3 additions & 1 deletion pcsx2-qt/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ private Q_SLOTS:

QWidget* getContentParent();
void saveDisplayWindowGeometryToConfig();
void restoreDisplayWindowGeometryFromConfig();
void restoreDisplayWindowGeometryFromConfig(QScreen* target_screen = nullptr);
void createDisplayWidget(bool fullscreen, bool render_to_main);
void destroyDisplayWidget(bool show_game_list);
void updateDisplayWidgetCursor();
Expand Down Expand Up @@ -320,6 +320,8 @@ private Q_SLOTS:
bool m_was_disc_change_request = false;
bool m_is_closing = false;
bool m_is_temporarily_windowed = false;
QByteArray m_pre_game_main_window_geometry;
QByteArray m_target_screen_main_window_geometry;

QString m_last_fps_status;

Expand Down
11 changes: 11 additions & 0 deletions pcsx2-qt/Settings/InterfaceSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "QtHost.h"

#include <QtCore/QLocale>
#include <QtGui/QScreen>

const char* InterfaceSettingsWidget::THEME_NAMES[] = {
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Native"),
Expand Down Expand Up @@ -122,6 +123,16 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsWindow* settings_dialog
m_ui.mouseLock->setEnabled(false);
}

m_ui.displayMonitor->addItem(tr("Primary Monitor"));
const QList<QScreen*> screens = QGuiApplication::screens();
for (int i = 0; i < screens.size(); i++)
m_ui.displayMonitor->addItem(tr("Monitor %1: %2").arg(i + 1).arg(screens[i]->name()));
m_ui.displayMonitor->setCurrentIndex(Host::GetBaseIntSettingValue("UI", "DisplayMonitor", 0));
connect(m_ui.displayMonitor, &QComboBox::currentIndexChanged, this, [](int index) {
Host::SetBaseIntSettingValue("UI", "DisplayMonitor", index);
Host::CommitBaseSettingChanges();
});

SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.startFullscreen, "UI", "StartFullscreen", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.doubleClickTogglesFullscreen, "UI", "DoubleClickTogglesFullscreen", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.hideMouseCursor, "UI", "HideMouseCursor", false);
Expand Down
14 changes: 14 additions & 0 deletions pcsx2-qt/Settings/InterfaceSettingsWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="displayMonitorLabel">
<property name="text">
<string>Display Monitor:</string>
</property>
<property name="buddy">
<cstring>displayMonitor</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="displayMonitor"/>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -403,6 +416,7 @@
<tabstop>disableWindowResizing</tabstop>
<tabstop>hideMouseCursor</tabstop>
<tabstop>startFullscreenUI</tabstop>
<tabstop>displayMonitor</tabstop>
<tabstop>language</tabstop>
<tabstop>theme</tabstop>
<tabstop>backgroundBrowse</tabstop>
Expand Down
Loading