Qt: Add a container widget for render-outside-main

Fixes missing decorations on Wayland.
This commit is contained in:
Connor McLaughlin
2021-07-17 22:27:07 +10:00
parent 3cf12e8f0d
commit d6c4c2dda9
4 changed files with 162 additions and 22 deletions

View File

@ -120,23 +120,36 @@ QtDisplayWidget* MainWindow::createDisplay(QThread* worker_thread, bool fullscre
const std::string fullscreen_mode = m_host_interface->GetStringSettingValue("GPU", "FullscreenMode", "");
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty() && m_host_display->SupportsFullscreen());
m_display_widget = new QtDisplayWidget((!fullscreen && render_to_main) ? m_ui.mainContainer : nullptr);
m_display_widget->setWindowTitle(windowTitle());
m_display_widget->setWindowIcon(windowIcon());
QWidget* container;
if (QtDisplayContainer::IsNeeded(fullscreen, render_to_main))
{
m_display_container = new QtDisplayContainer();
m_display_widget = new QtDisplayWidget(m_display_container);
m_display_container->setDisplayWidget(m_display_widget);
container = m_display_container;
}
else
{
m_display_widget = new QtDisplayWidget((!fullscreen && render_to_main) ? m_ui.mainContainer : nullptr);
container = m_display_widget;
}
container->setWindowTitle(windowTitle());
container->setWindowIcon(windowIcon());
if (fullscreen)
{
if (!is_exclusive_fullscreen)
m_display_widget->showFullScreen();
container->showFullScreen();
else
m_display_widget->showNormal();
container->showNormal();
updateMouseMode(System::IsPaused());
}
else if (!render_to_main)
{
restoreDisplayWindowGeometryFromConfig();
m_display_widget->showNormal();
container->showNormal();
}
else
{
@ -182,7 +195,9 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
return m_display_widget;
// Skip recreating the surface if we're just transitioning between fullscreen and windowed with render-to-main off.
if (!is_rendering_to_main && !render_to_main && !is_exclusive_fullscreen)
const bool has_container = (m_display_container != nullptr);
const bool needs_container = QtDisplayContainer::IsNeeded(fullscreen, render_to_main);
if (!is_rendering_to_main && !render_to_main && !is_exclusive_fullscreen && has_container == needs_container)
{
qDebug() << "Toggling to" << (fullscreen ? "fullscreen" : "windowed") << "without recreating surface";
if (m_host_display && m_host_display->IsFullscreen())
@ -206,23 +221,37 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
m_host_display->DestroyRenderSurface();
destroyDisplayWidget();
m_display_widget = new QtDisplayWidget((!fullscreen && render_to_main) ? m_ui.mainContainer : nullptr);
m_display_widget->setWindowTitle(windowTitle());
m_display_widget->setWindowIcon(windowIcon());
QWidget* container;
if (QtDisplayContainer::IsNeeded(fullscreen, render_to_main))
{
m_display_container = new QtDisplayContainer();
m_display_widget = new QtDisplayWidget(m_display_container);
m_display_container->setDisplayWidget(m_display_widget);
container = m_display_container;
}
else
{
m_display_widget = new QtDisplayWidget((!fullscreen && render_to_main) ? m_ui.mainContainer : nullptr);
container = m_display_widget;
}
container->setWindowTitle(windowTitle());
container->setWindowIcon(windowIcon());
if (fullscreen)
{
if (!is_exclusive_fullscreen)
m_display_widget->showFullScreen();
container->showFullScreen();
else
m_display_widget->showNormal();
container->showNormal();
updateMouseMode(System::IsPaused());
}
else if (!render_to_main)
{
restoreDisplayWindowGeometryFromConfig();
m_display_widget->showNormal();
container->showNormal();
}
else
{
@ -281,10 +310,10 @@ void MainWindow::displaySizeRequested(qint32 width, qint32 height)
if (!m_display_widget)
return;
if (!m_display_widget->parent())
if (m_display_container || !m_display_widget->parent())
{
// no parent - rendering to separate window. easy.
m_display_widget->resize(QSize(std::max<qint32>(width, 1), std::max<qint32>(height, 1)));
getDisplayContainer()->resize(QSize(std::max<qint32>(width, 1), std::max<qint32>(height, 1)));
return;
}
@ -308,18 +337,23 @@ void MainWindow::destroyDisplayWidget()
if (!m_display_widget)
return;
if (m_display_container || (!m_display_widget->parent() && !m_display_widget->isFullScreen()))
saveDisplayWindowGeometryToConfig();
if (m_display_container)
m_display_container->removeDisplayWidget();
if (m_display_widget->parent())
{
switchToGameListView();
m_ui.mainContainer->removeWidget(m_display_widget);
}
else if (!m_display_widget->isFullScreen())
{
saveDisplayWindowGeometryToConfig();
}
delete m_display_widget;
m_display_widget = nullptr;
delete m_display_container;
m_display_container = nullptr;
}
void MainWindow::focusDisplayWidget()
@ -1367,7 +1401,7 @@ void MainWindow::restoreStateFromConfig()
void MainWindow::saveDisplayWindowGeometryToConfig()
{
const QByteArray geometry = m_display_widget->saveGeometry();
const QByteArray geometry = getDisplayContainer()->saveGeometry();
const QByteArray geometry_b64 = geometry.toBase64();
const std::string old_geometry_b64 = m_host_interface->GetStringSettingValue("UI", "DisplayWindowGeometry");
if (old_geometry_b64 != geometry_b64.constData())
@ -1378,8 +1412,11 @@ void MainWindow::restoreDisplayWindowGeometryFromConfig()
{
const std::string geometry_b64 = m_host_interface->GetStringSettingValue("UI", "DisplayWindowGeometry");
const QByteArray geometry = QByteArray::fromBase64(QByteArray::fromStdString(geometry_b64));
QWidget* container = getDisplayContainer();
if (!geometry.isEmpty())
m_display_widget->restoreGeometry(geometry);
container->restoreGeometry(geometry);
else
container->resize(640, 480);
}
SettingsDialog* MainWindow::getSettingsDialog()