Qt: Fix fullscreening in Wayland

This commit is contained in:
Connor McLaughlin 2022-04-15 18:45:41 +10:00 committed by refractionpcsx2
parent 06beadba74
commit 7194542029
4 changed files with 25 additions and 21 deletions

View File

@ -24,6 +24,7 @@
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
#include <QtGui/QKeyEvent>
#include <QtGui/QResizeEvent>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtGui/QWindowStateChangeEvent>
@ -208,7 +209,12 @@ bool DisplayWidget::event(QEvent* event)
{
QWidget::event(event);
emit windowResizedEvent(scaledWindowWidth(), scaledWindowHeight(), devicePixelRatioFromScreen());
const qreal dpr = devicePixelRatioFromScreen();
const QSize size = static_cast<QResizeEvent*>(event)->size();
const int width = static_cast<int>(std::ceil(static_cast<qreal>(size.width()) * devicePixelRatioFromScreen()));
const int height = static_cast<int>(std::ceil(static_cast<qreal>(size.height()) * devicePixelRatioFromScreen()));
emit windowResizedEvent(width, height, dpr);
return true;
}
@ -262,7 +268,7 @@ bool DisplayContainer::IsNeeded(bool fullscreen, bool render_to_main)
#if defined(_WIN32) || defined(__APPLE__)
return false;
#else
if (fullscreen || render_to_main)
if (!fullscreen && render_to_main)
return false;
// We only need this on Wayland because of client-side decorations...

View File

@ -603,9 +603,6 @@ void EmuThread::updateDisplay()
pxFailRel("Failed to recreate context after updating");
return;
}
// this is always a new widget, so reconnect it
connectDisplaySignals(widget);
}
HostDisplay* EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)

View File

@ -47,6 +47,7 @@ public:
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
HostDisplay* acquireHostDisplay(HostDisplay::RenderAPI api);
void connectDisplaySignals(DisplayWidget* widget);
void releaseHostDisplay();
void updateDisplay();
@ -127,7 +128,6 @@ private:
static constexpr u32 BACKGROUND_CONTROLLER_POLLING_INTERVAL =
100; /// Interval at which the controllers are polled when the system is not active.
void connectDisplaySignals(DisplayWidget* widget);
void destroyVM();
void executeVM();
void checkForSettingChanges();

View File

@ -1140,8 +1140,6 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
container->showFullScreen();
else
container->showNormal();
// updateMouseMode(System::IsPaused());
}
else if (!render_to_main)
{
@ -1150,7 +1148,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
}
else
{
m_ui.mainContainer->insertWidget(1, m_display_widget);
m_ui.mainContainer->insertWidget(1, container);
switchToEmulationView();
}
@ -1165,6 +1163,8 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
return nullptr;
}
g_emu_thread->connectDisplaySignals(m_display_widget);
if (!host_display->CreateRenderDevice(wi.value(), Host::GetStringSettingValue("EmuCore/GS", "Adapter", ""), EmuConfig.GetEffectiveVsyncMode(),
Host::GetBoolSettingValue("EmuCore/GS", "ThreadedPresentation", false), Host::GetBoolSettingValue("EmuCore/GS", "UseDebugDevice", false)))
{
@ -1183,34 +1183,35 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main)
{
HostDisplay* host_display = Host::GetHostDisplay();
const bool is_fullscreen = m_display_widget->isFullScreen();
const bool is_rendering_to_main = (!is_fullscreen && m_display_widget->parent());
QWidget* container = m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget);
const bool is_fullscreen = container->isFullScreen();
const bool is_rendering_to_main = (!is_fullscreen && container->parent());
const std::string fullscreen_mode(QtHost::GetBaseStringSettingValue("EmuCore/GS", "FullscreenMode", ""));
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && host_display->SupportsFullscreen());
if (fullscreen == is_fullscreen && is_rendering_to_main == render_to_main)
return m_display_widget;
// Skip recreating the surface if we're just transitioning between fullscreen and windowed with render-to-main off.
// .. except on Wayland, where everything tends to break if you don't recreate.
const bool has_container = (m_display_container != nullptr);
const bool needs_container = DisplayContainer::IsNeeded(fullscreen, render_to_main);
if (!is_rendering_to_main && !render_to_main && !is_exclusive_fullscreen && has_container == needs_container)
if (!is_rendering_to_main && !render_to_main && !is_exclusive_fullscreen && has_container == needs_container && !needs_container)
{
qDebug() << "Toggling to" << (fullscreen ? "fullscreen" : "windowed") << "without recreating surface";
Console.WriteLn("Toggling to %s without recreating surface", (fullscreen ? "fullscreen" : "windowed"));
if (host_display->IsFullscreen())
host_display->SetFullscreen(false, 0, 0, 0.0f);
if (fullscreen)
{
m_display_widget->showFullScreen();
container->showFullScreen();
}
else
{
restoreDisplayWindowGeometryFromConfig();
m_display_widget->showNormal();
container->showNormal();
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
// updateMouseMode(System::IsPaused());
return m_display_widget;
}
@ -1218,7 +1219,6 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main)
destroyDisplayWidget();
QWidget* container;
if (DisplayContainer::IsNeeded(fullscreen, render_to_main))
{
m_display_container = new DisplayContainer();
@ -1241,8 +1241,6 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main)
container->showFullScreen();
else
container->showNormal();
// updateMouseMode(System::IsPaused());
}
else if (!render_to_main)
{
@ -1251,7 +1249,7 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main)
}
else
{
m_ui.mainContainer->insertWidget(1, m_display_widget);
m_ui.mainContainer->insertWidget(1, container);
switchToEmulationView();
}
@ -1266,6 +1264,8 @@ DisplayWidget* MainWindow::updateDisplay(bool fullscreen, bool render_to_main)
return nullptr;
}
g_emu_thread->connectDisplaySignals(m_display_widget);
if (!host_display->ChangeRenderWindow(wi.value()))
pxFailRel("Failed to recreate surface on new widget.");
@ -1344,7 +1344,8 @@ void MainWindow::destroyDisplayWidget()
if (!m_display_widget)
return;
if (m_display_container || (!m_display_widget->parent() && !m_display_widget->isFullScreen()))
const QWidget* container = m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget);
if (!container->parent() && !container->isFullScreen())
saveDisplayWindowGeometryToConfig();
if (m_display_container)