mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-19 00:20:12 +00:00
Qt: Refactor and remove multiple sources of truth for render-to-main
This commit is contained in:
parent
0f2ef98747
commit
6b969a0b94
@ -25,6 +25,9 @@ public:
|
|||||||
explicit DisplayWidget(QWidget* parent);
|
explicit DisplayWidget(QWidget* parent);
|
||||||
~DisplayWidget();
|
~DisplayWidget();
|
||||||
|
|
||||||
|
ALWAYS_INLINE const char* windowPositionKey() const { return m_window_position_key; }
|
||||||
|
ALWAYS_INLINE void setWindowPositionKey(const char* key) { m_window_position_key = key; }
|
||||||
|
|
||||||
QPaintEngine* paintEngine() const override;
|
QPaintEngine* paintEngine() const override;
|
||||||
|
|
||||||
int scaledWindowWidth() const;
|
int scaledWindowWidth() const;
|
||||||
@ -67,6 +70,8 @@ private:
|
|||||||
u32 m_last_window_width = 0;
|
u32 m_last_window_width = 0;
|
||||||
u32 m_last_window_height = 0;
|
u32 m_last_window_height = 0;
|
||||||
float m_last_window_scale = 1.0f;
|
float m_last_window_scale = 1.0f;
|
||||||
|
|
||||||
|
const char* m_window_position_key = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DisplayContainer final : public QStackedWidget
|
class DisplayContainer final : public QStackedWidget
|
||||||
|
@ -251,13 +251,13 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::optional<WindowInfo> MainWindow::acquireRenderWindow(RenderAPI render_api, bool fullscreen,
|
std::optional<WindowInfo> MainWindow::acquireRenderWindow(RenderAPI render_api, bool fullscreen,
|
||||||
bool exclusive_fullscreen, bool render_to_main,
|
bool exclusive_fullscreen, bool surfaceless, Error* error)
|
||||||
bool surfaceless, bool use_main_window_pos, Error* error)
|
|
||||||
{
|
{
|
||||||
DEV_LOG("acquireRenderWindow() fullscreen={} exclusive_fullscreen={}, render_to_main={} surfaceless={} "
|
const bool render_to_main =
|
||||||
"use_main_window_pos={}",
|
QtHost::CanRenderToMainWindow() && !fullscreen && (s_system_locked.load(std::memory_order_relaxed) == 0);
|
||||||
fullscreen ? "true" : "false", exclusive_fullscreen ? "true" : "false", render_to_main ? "true" : "false",
|
|
||||||
surfaceless ? "true" : "false", use_main_window_pos ? "true" : "false");
|
DEV_LOG("acquireRenderWindow() fullscreen={} exclusive_fullscreen={}, render_to_main={}, surfaceless={} ", fullscreen,
|
||||||
|
exclusive_fullscreen, render_to_main, surfaceless);
|
||||||
|
|
||||||
QWidget* container =
|
QWidget* container =
|
||||||
m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget);
|
m_display_container ? static_cast<QWidget*>(m_display_container) : static_cast<QWidget*>(m_display_widget);
|
||||||
@ -279,6 +279,9 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(RenderAPI render_api,
|
|||||||
DEV_LOG("Toggling to {} without recreating surface", (fullscreen ? "fullscreen" : "windowed"));
|
DEV_LOG("Toggling to {} without recreating surface", (fullscreen ? "fullscreen" : "windowed"));
|
||||||
m_exclusive_fullscreen_requested = exclusive_fullscreen;
|
m_exclusive_fullscreen_requested = exclusive_fullscreen;
|
||||||
|
|
||||||
|
// ensure it's resizable when changing size, we'll fix it up later in updateWindowState()
|
||||||
|
QtUtils::SetWindowResizeable(container, true);
|
||||||
|
|
||||||
// since we don't destroy the display widget, we need to save it here
|
// since we don't destroy the display widget, we need to save it here
|
||||||
if (!is_fullscreen && !is_rendering_to_main)
|
if (!is_fullscreen && !is_rendering_to_main)
|
||||||
saveDisplayWindowGeometryToConfig();
|
saveDisplayWindowGeometryToConfig();
|
||||||
@ -290,9 +293,6 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(RenderAPI render_api,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
container->showNormal();
|
container->showNormal();
|
||||||
if (use_main_window_pos)
|
|
||||||
container->setGeometry(geometry());
|
|
||||||
else
|
|
||||||
restoreDisplayWindowGeometryFromConfig();
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(RenderAPI render_api,
|
|||||||
std::optional<WindowInfo> wi;
|
std::optional<WindowInfo> wi;
|
||||||
if (!surfaceless)
|
if (!surfaceless)
|
||||||
{
|
{
|
||||||
createDisplayWidget(fullscreen, render_to_main, use_main_window_pos);
|
createDisplayWidget(fullscreen, render_to_main);
|
||||||
|
|
||||||
wi = m_display_widget->getWindowInfo(render_api, error);
|
wi = m_display_widget->getWindowInfo(render_api, error);
|
||||||
if (!wi.has_value())
|
if (!wi.has_value())
|
||||||
@ -343,7 +343,7 @@ bool MainWindow::hasDisplayWidget() const
|
|||||||
return m_display_widget != nullptr;
|
return m_display_widget != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main, bool use_main_window_pos)
|
void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
|
||||||
{
|
{
|
||||||
// If we're rendering to main and were hidden (e.g. coming back from fullscreen),
|
// If we're rendering to main and were hidden (e.g. coming back from fullscreen),
|
||||||
// make sure we're visible before trying to add ourselves. Otherwise Wayland breaks.
|
// make sure we're visible before trying to add ourselves. Otherwise Wayland breaks.
|
||||||
@ -384,9 +384,6 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main, bool
|
|||||||
}
|
}
|
||||||
else if (!render_to_main)
|
else if (!render_to_main)
|
||||||
{
|
{
|
||||||
if (use_main_window_pos)
|
|
||||||
container->setGeometry(geometry());
|
|
||||||
else
|
|
||||||
restoreDisplayWindowGeometryFromConfig();
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
container->showNormal();
|
container->showNormal();
|
||||||
|
|
||||||
@ -441,7 +438,7 @@ void MainWindow::releaseRenderWindow()
|
|||||||
// Now we can safely destroy the display window.
|
// Now we can safely destroy the display window.
|
||||||
destroyDisplayWidget(true);
|
destroyDisplayWidget(true);
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
updateWindowState(false);
|
updateWindowState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::destroyDisplayWidget(bool show_game_list)
|
void MainWindow::destroyDisplayWidget(bool show_game_list)
|
||||||
@ -809,7 +806,7 @@ void MainWindow::recreate()
|
|||||||
{
|
{
|
||||||
g_emu_thread->setSurfaceless(false);
|
g_emu_thread->setSurfaceless(false);
|
||||||
if (was_fullscreen)
|
if (was_fullscreen)
|
||||||
g_emu_thread->setFullscreen(true, true);
|
g_emu_thread->setFullscreen(true);
|
||||||
g_main_window->updateEmulationActions(false, s_system_valid, s_achievements_hardcore_mode);
|
g_main_window->updateEmulationActions(false, s_system_valid, s_achievements_hardcore_mode);
|
||||||
g_main_window->onFullscreenUIStartedOrStopped(s_fullscreen_ui_started);
|
g_main_window->onFullscreenUIStartedOrStopped(s_fullscreen_ui_started);
|
||||||
}
|
}
|
||||||
@ -2035,22 +2032,20 @@ void MainWindow::updateWindowTitle()
|
|||||||
g_log_window->updateWindowTitle();
|
g_log_window->updateWindowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateWindowState(bool force_visible)
|
void MainWindow::updateWindowState()
|
||||||
{
|
{
|
||||||
// Skip all of this when we're closing, since we don't want to make ourselves visible and cancel it.
|
// Skip all of this when we're closing, since we don't want to make ourselves visible and cancel it.
|
||||||
if (m_is_closing)
|
if (m_is_closing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool hide_window = shouldHideMainWindow();
|
const bool visible = !shouldHideMainWindow();
|
||||||
const bool disable_resize = (Host::GetBoolSettingValue("Main", "DisableWindowResize", false) && wantsDisplayWidget());
|
const bool resizeable = (!Host::GetBoolSettingValue("Main", "DisableWindowResize", false) || !wantsDisplayWidget() ||
|
||||||
|
isRenderingFullscreen());
|
||||||
|
|
||||||
// Need to test both valid and display widget because of startup (vm invalid while window is created).
|
|
||||||
const bool visible = force_visible || !hide_window;
|
|
||||||
if (isVisible() != visible)
|
if (isVisible() != visible)
|
||||||
setVisible(visible);
|
setVisible(visible);
|
||||||
|
|
||||||
// No point changing realizability if we're not visible.
|
// No point changing realizability if we're not visible.
|
||||||
const bool resizeable = force_visible || !disable_resize;
|
|
||||||
if (visible)
|
if (visible)
|
||||||
QtUtils::SetWindowResizeable(this, resizeable);
|
QtUtils::SetWindowResizeable(this, resizeable);
|
||||||
|
|
||||||
@ -2108,12 +2103,12 @@ bool MainWindow::shouldHideMouseCursor() const
|
|||||||
bool MainWindow::shouldHideMainWindow() const
|
bool MainWindow::shouldHideMainWindow() const
|
||||||
{
|
{
|
||||||
// CanRenderToMain check is for temporary unfullscreens.
|
// CanRenderToMain check is for temporary unfullscreens.
|
||||||
return !isRenderingToMain() && wantsDisplayWidget() &&
|
return (!isRenderingToMain() && wantsDisplayWidget() &&
|
||||||
((Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) &&
|
((Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) &&
|
||||||
Host::GetBoolSettingValue("Main", "HideMainWindowWhenRunning", false)) ||
|
Host::GetBoolSettingValue("Main", "HideMainWindowWhenRunning", false)) ||
|
||||||
(QtHost::CanRenderToMainWindow() &&
|
(QtHost::CanRenderToMainWindow() &&
|
||||||
(isRenderingFullscreen() || s_system_locked.load(std::memory_order_relaxed))) ||
|
(isRenderingFullscreen() || s_system_locked.load(std::memory_order_relaxed))))) ||
|
||||||
QtHost::InNoGUIMode());
|
QtHost::InNoGUIMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::switchToGameListView()
|
void MainWindow::switchToGameListView()
|
||||||
@ -2434,7 +2429,7 @@ void MainWindow::saveStateToConfig()
|
|||||||
if (!isVisible() || ((windowState() & Qt::WindowFullScreen) != Qt::WindowNoState))
|
if (!isVisible() || ((windowState() & Qt::WindowFullScreen) != Qt::WindowNoState))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool changed = QtUtils::SaveWindowGeometry("MainWindow", this, false);
|
bool changed = false;
|
||||||
|
|
||||||
const QByteArray state(saveState());
|
const QByteArray state(saveState());
|
||||||
const QByteArray state_b64(state.toBase64());
|
const QByteArray state_b64(state.toBase64());
|
||||||
@ -2445,14 +2440,14 @@ void MainWindow::saveStateToConfig()
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changed |= QtUtils::SaveWindowGeometry("MainWindow", this, false);
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
Host::CommitBaseSettingChanges();
|
Host::CommitBaseSettingChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::restoreStateFromConfig()
|
void MainWindow::restoreStateFromConfig()
|
||||||
{
|
{
|
||||||
QtUtils::RestoreWindowGeometry("MainWindow", this);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const std::string state_b64 = Host::GetBaseStringSettingValue("UI", "MainWindowState");
|
const std::string state_b64 = Host::GetBaseStringSettingValue("UI", "MainWindowState");
|
||||||
const QByteArray state = QByteArray::fromBase64(QByteArray::fromStdString(state_b64));
|
const QByteArray state = QByteArray::fromBase64(QByteArray::fromStdString(state_b64));
|
||||||
@ -2473,6 +2468,8 @@ void MainWindow::restoreStateFromConfig()
|
|||||||
m_ui.actionViewStatusBar->setChecked(!m_ui.statusBar->isHidden());
|
m_ui.actionViewStatusBar->setChecked(!m_ui.statusBar->isHidden());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QtUtils::RestoreWindowGeometry("MainWindow", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::saveDisplayWindowGeometryToConfig()
|
void MainWindow::saveDisplayWindowGeometryToConfig()
|
||||||
@ -2484,13 +2481,29 @@ void MainWindow::saveDisplayWindowGeometryToConfig()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QtUtils::SaveWindowGeometry("DisplayWindow", container);
|
const char* key = m_display_widget->windowPositionKey();
|
||||||
|
if (key)
|
||||||
|
QtUtils::SaveWindowGeometry(key, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::restoreDisplayWindowGeometryFromConfig()
|
void MainWindow::restoreDisplayWindowGeometryFromConfig()
|
||||||
{
|
{
|
||||||
QWidget* const container = getDisplayContainer();
|
QWidget* const container = getDisplayContainer();
|
||||||
if (!QtUtils::RestoreWindowGeometry("DisplayWindow", container))
|
DebugAssert(m_display_widget);
|
||||||
|
|
||||||
|
// just sync it with the main window if we're not using nogui modem, config will be stale
|
||||||
|
if (QtHost::CanRenderToMainWindow())
|
||||||
|
{
|
||||||
|
container->setGeometry(geometry());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't want the temporary windowed window to be positioned on a different monitor, so use the main window
|
||||||
|
// coordinates... unless you're on wayland, too fucking bad, broken by design.
|
||||||
|
const bool use_main_window_pos = QtHost::UseMainWindowGeometryForDisplayWindow();
|
||||||
|
m_display_widget->setWindowPositionKey(use_main_window_pos ? "MainWindow" : "DisplayWindow");
|
||||||
|
|
||||||
|
if (!QtUtils::RestoreWindowGeometry(m_display_widget->windowPositionKey(), container))
|
||||||
{
|
{
|
||||||
// default size
|
// default size
|
||||||
container->resize(640, 480);
|
container->resize(640, 480);
|
||||||
@ -2641,7 +2654,7 @@ void MainWindow::changeEvent(QEvent* event)
|
|||||||
static_cast<QWindowStateChangeEvent*>(event)->oldState() & Qt::WindowMinimized)
|
static_cast<QWindowStateChangeEvent*>(event)->oldState() & Qt::WindowMinimized)
|
||||||
{
|
{
|
||||||
// TODO: This should check the render-to-main option.
|
// TODO: This should check the render-to-main option.
|
||||||
if (m_display_widget)
|
if (isRenderingToMain())
|
||||||
g_emu_thread->redrawDisplayWindow();
|
g_emu_thread->redrawDisplayWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2785,6 +2798,10 @@ bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, b
|
|||||||
lock.cancelResume();
|
lock.cancelResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're running in batch mode, don't show the main window after shutting down.
|
||||||
|
if (QtHost::InBatchMode())
|
||||||
|
m_is_closing = true;
|
||||||
|
|
||||||
// Now we can actually shut down the VM.
|
// Now we can actually shut down the VM.
|
||||||
g_emu_thread->shutdownSystem(save_state, check_memcard_busy);
|
g_emu_thread->shutdownSystem(save_state, check_memcard_busy);
|
||||||
return true;
|
return true;
|
||||||
@ -2824,6 +2841,13 @@ void MainWindow::checkForSettingChanges()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't change state if temporary unfullscreened
|
||||||
|
if (m_display_widget && !QtHost::IsSystemLocked() && !isRenderingFullscreen())
|
||||||
|
{
|
||||||
|
if (QtHost::CanRenderToMainWindow() != isRenderingToMain())
|
||||||
|
g_emu_thread->updateDisplayWindow();
|
||||||
|
}
|
||||||
|
|
||||||
LogWindow::updateSettings();
|
LogWindow::updateSettings();
|
||||||
updateWindowState();
|
updateWindowState();
|
||||||
}
|
}
|
||||||
@ -2986,7 +3010,7 @@ void MainWindow::onToolsCoverDownloaderTriggered()
|
|||||||
// This can be invoked via big picture, so exit fullscreen.
|
// This can be invoked via big picture, so exit fullscreen.
|
||||||
if (isRenderingFullscreen())
|
if (isRenderingFullscreen())
|
||||||
{
|
{
|
||||||
g_emu_thread->setFullscreen(false, true);
|
g_emu_thread->setFullscreen(false);
|
||||||
|
|
||||||
// wait for the fullscreen request to actually go through, otherwise the downloader appears behind the main window.
|
// wait for the fullscreen request to actually go through, otherwise the downloader appears behind the main window.
|
||||||
QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() { return isRenderingFullscreen(); });
|
QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() { return isRenderingFullscreen(); });
|
||||||
@ -3181,14 +3205,10 @@ MainWindow::SystemLock MainWindow::pauseAndLockSystem()
|
|||||||
// However, we do not want to switch back to render-to-main, the window might have generated this event.
|
// However, we do not want to switch back to render-to-main, the window might have generated this event.
|
||||||
if (was_fullscreen)
|
if (was_fullscreen)
|
||||||
{
|
{
|
||||||
g_emu_thread->setFullscreen(false, false);
|
g_emu_thread->setFullscreen(false);
|
||||||
|
|
||||||
// Container could change... thanks Wayland.
|
// Container could change... thanks Wayland.
|
||||||
QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() {
|
QtUtils::ProcessEventsWithSleep(QEventLoop::ExcludeUserInputEvents, [this]() { return isRenderingFullscreen(); });
|
||||||
QWidget* container;
|
|
||||||
return (s_system_valid &&
|
|
||||||
(g_emu_thread->isFullscreen() || !(container = getDisplayContainer()) || container->isFullScreen()));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!was_paused)
|
if (!was_paused)
|
||||||
@ -3228,7 +3248,7 @@ MainWindow::SystemLock::~SystemLock()
|
|||||||
DebugAssert(s_system_locked.load(std::memory_order_relaxed) > 0);
|
DebugAssert(s_system_locked.load(std::memory_order_relaxed) > 0);
|
||||||
s_system_locked.fetch_sub(1, std::memory_order_release);
|
s_system_locked.fetch_sub(1, std::memory_order_release);
|
||||||
if (m_was_fullscreen)
|
if (m_was_fullscreen)
|
||||||
g_emu_thread->setFullscreen(true, true);
|
g_emu_thread->setFullscreen(true);
|
||||||
if (!m_was_paused)
|
if (!m_was_paused)
|
||||||
g_emu_thread->setSystemPaused(false);
|
g_emu_thread->setSystemPaused(false);
|
||||||
}
|
}
|
||||||
|
@ -138,8 +138,7 @@ private Q_SLOTS:
|
|||||||
void onStatusMessage(const QString& message);
|
void onStatusMessage(const QString& message);
|
||||||
|
|
||||||
std::optional<WindowInfo> acquireRenderWindow(RenderAPI render_api, bool fullscreen, bool exclusive_fullscreen,
|
std::optional<WindowInfo> acquireRenderWindow(RenderAPI render_api, bool fullscreen, bool exclusive_fullscreen,
|
||||||
bool render_to_main, bool surfaceless, bool use_main_window_pos,
|
bool surfaceless, Error* error);
|
||||||
Error* error);
|
|
||||||
void displayResizeRequested(qint32 width, qint32 height);
|
void displayResizeRequested(qint32 width, qint32 height);
|
||||||
void releaseRenderWindow();
|
void releaseRenderWindow();
|
||||||
void focusDisplayWidget();
|
void focusDisplayWidget();
|
||||||
@ -250,7 +249,7 @@ private:
|
|||||||
void updateShortcutActions(bool starting);
|
void updateShortcutActions(bool starting);
|
||||||
void updateStatusBarWidgetVisibility();
|
void updateStatusBarWidgetVisibility();
|
||||||
void updateWindowTitle();
|
void updateWindowTitle();
|
||||||
void updateWindowState(bool force_visible = false);
|
void updateWindowState();
|
||||||
|
|
||||||
void setProgressBar(int current, int total);
|
void setProgressBar(int current, int total);
|
||||||
void clearProgressBar();
|
void clearProgressBar();
|
||||||
@ -269,7 +268,7 @@ private:
|
|||||||
void saveDisplayWindowGeometryToConfig();
|
void saveDisplayWindowGeometryToConfig();
|
||||||
void restoreDisplayWindowGeometryFromConfig();
|
void restoreDisplayWindowGeometryFromConfig();
|
||||||
bool wantsDisplayWidget() const;
|
bool wantsDisplayWidget() const;
|
||||||
void createDisplayWidget(bool fullscreen, bool render_to_main, bool use_main_window_pos);
|
void createDisplayWidget(bool fullscreen, bool render_to_main);
|
||||||
void destroyDisplayWidget(bool show_game_list);
|
void destroyDisplayWidget(bool show_game_list);
|
||||||
void updateDisplayWidgetCursor();
|
void updateDisplayWidgetCursor();
|
||||||
void updateDisplayRelatedActions(bool has_surface, bool fullscreen);
|
void updateDisplayRelatedActions(bool has_surface, bool fullscreen);
|
||||||
|
@ -568,27 +568,11 @@ void Host::LoadSettings(const SettingsInterface& si, std::unique_lock<std::mutex
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::checkForSettingsChanges(const Settings& old_settings)
|
|
||||||
{
|
|
||||||
if (g_main_window)
|
|
||||||
QMetaObject::invokeMethod(g_main_window, &MainWindow::checkForSettingChanges, Qt::QueuedConnection);
|
|
||||||
|
|
||||||
// don't mess with fullscreen while locked
|
|
||||||
if (!QtHost::IsSystemLocked())
|
|
||||||
{
|
|
||||||
const bool render_to_main = QtHost::CanRenderToMainWindow();
|
|
||||||
if (m_is_rendering_to_main != render_to_main && !m_is_fullscreen)
|
|
||||||
{
|
|
||||||
m_is_rendering_to_main = render_to_main;
|
|
||||||
if (g_gpu_device)
|
|
||||||
GPUThread::UpdateDisplayWindow(m_is_fullscreen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Host::CheckForSettingsChanges(const Settings& old_settings)
|
void Host::CheckForSettingsChanges(const Settings& old_settings)
|
||||||
{
|
{
|
||||||
g_emu_thread->checkForSettingsChanges(old_settings);
|
// NOTE: emu thread, push to UI thread
|
||||||
|
if (g_main_window)
|
||||||
|
QMetaObject::invokeMethod(g_main_window, &MainWindow::checkForSettingChanges, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::setDefaultSettings(bool system /* = true */, bool controller /* = true */)
|
void EmuThread::setDefaultSettings(bool system /* = true */, bool controller /* = true */)
|
||||||
@ -649,6 +633,12 @@ bool QtHost::CanRenderToMainWindow()
|
|||||||
return !Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) && !InNoGUIMode();
|
return !Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) && !InNoGUIMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QtHost::UseMainWindowGeometryForDisplayWindow()
|
||||||
|
{
|
||||||
|
// nogui _or_ main window mode, since we want to use it for temporary unfullscreens
|
||||||
|
return !Host::GetBoolSettingValue("Main", "RenderToSeparateWindow", false) || InNoGUIMode();
|
||||||
|
}
|
||||||
|
|
||||||
void Host::RequestResizeHostDisplay(s32 new_window_width, s32 new_window_height)
|
void Host::RequestResizeHostDisplay(s32 new_window_width, s32 new_window_height)
|
||||||
{
|
{
|
||||||
if (g_emu_thread->isFullscreen())
|
if (g_emu_thread->isFullscreen())
|
||||||
@ -729,7 +719,6 @@ void EmuThread::startFullscreenUI()
|
|||||||
// we want settings loaded so we choose the correct renderer
|
// we want settings loaded so we choose the correct renderer
|
||||||
// this also sorts out input sources.
|
// this also sorts out input sources.
|
||||||
System::LoadSettings(false);
|
System::LoadSettings(false);
|
||||||
m_is_rendering_to_main = QtHost::CanRenderToMainWindow();
|
|
||||||
|
|
||||||
// borrow the game start fullscreen flag
|
// borrow the game start fullscreen flag
|
||||||
const bool start_fullscreen =
|
const bool start_fullscreen =
|
||||||
@ -799,8 +788,6 @@ void EmuThread::bootSystem(std::shared_ptr<SystemBootParameters> params)
|
|||||||
if (System::IsValidOrInitializing())
|
if (System::IsValidOrInitializing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_is_rendering_to_main = QtHost::CanRenderToMainWindow();
|
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!System::BootSystem(std::move(*params), &error))
|
if (!System::BootSystem(std::move(*params), &error))
|
||||||
{
|
{
|
||||||
@ -913,15 +900,14 @@ void EmuThread::toggleFullscreen()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setFullscreen(!m_is_fullscreen, true);
|
setFullscreen(!m_is_fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::setFullscreen(bool fullscreen, bool allow_render_to_main)
|
void EmuThread::setFullscreen(bool fullscreen)
|
||||||
{
|
{
|
||||||
if (!isCurrentThread())
|
if (!isCurrentThread())
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, "setFullscreen", Qt::QueuedConnection, Q_ARG(bool, fullscreen),
|
QMetaObject::invokeMethod(this, "setFullscreen", Qt::QueuedConnection, Q_ARG(bool, fullscreen));
|
||||||
Q_ARG(bool, allow_render_to_main));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,7 +915,6 @@ void EmuThread::setFullscreen(bool fullscreen, bool allow_render_to_main)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_is_fullscreen = fullscreen;
|
m_is_fullscreen = fullscreen;
|
||||||
m_is_rendering_to_main = allow_render_to_main && QtHost::CanRenderToMainWindow();
|
|
||||||
GPUThread::UpdateDisplayWindow(fullscreen);
|
GPUThread::UpdateDisplayWindow(fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,7 +929,7 @@ void Host::SetFullscreen(bool enabled)
|
|||||||
if (QtHost::IsSystemLocked())
|
if (QtHost::IsSystemLocked())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_emu_thread->setFullscreen(enabled, true);
|
g_emu_thread->setFullscreen(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::setSurfaceless(bool surfaceless)
|
void EmuThread::setSurfaceless(bool surfaceless)
|
||||||
@ -962,6 +947,17 @@ void EmuThread::setSurfaceless(bool surfaceless)
|
|||||||
GPUThread::UpdateDisplayWindow(false);
|
GPUThread::UpdateDisplayWindow(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmuThread::updateDisplayWindow()
|
||||||
|
{
|
||||||
|
if (!isCurrentThread())
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(this, &EmuThread::updateDisplayWindow, Qt::QueuedConnection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPUThread::UpdateDisplayWindow(m_is_fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
void EmuThread::requestDisplaySize(float scale)
|
void EmuThread::requestDisplaySize(float scale)
|
||||||
{
|
{
|
||||||
if (!isCurrentThread())
|
if (!isCurrentThread())
|
||||||
@ -983,12 +979,8 @@ std::optional<WindowInfo> EmuThread::acquireRenderWindow(RenderAPI render_api, b
|
|||||||
|
|
||||||
m_is_fullscreen = fullscreen;
|
m_is_fullscreen = fullscreen;
|
||||||
|
|
||||||
const bool window_fullscreen = m_is_fullscreen && !exclusive_fullscreen;
|
return emit onAcquireRenderWindowRequested(render_api, m_is_fullscreen, exclusive_fullscreen, m_is_surfaceless,
|
||||||
const bool render_to_main = !fullscreen && m_is_rendering_to_main;
|
error);
|
||||||
const bool use_main_window_pos = QtHost::CanRenderToMainWindow();
|
|
||||||
|
|
||||||
return emit onAcquireRenderWindowRequested(render_api, window_fullscreen, exclusive_fullscreen, render_to_main,
|
|
||||||
m_is_surfaceless, use_main_window_pos, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::releaseRenderWindow()
|
void EmuThread::releaseRenderWindow()
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class QActionGroup;
|
class QActionGroup;
|
||||||
class QEventLoop;
|
class QEventLoop;
|
||||||
@ -97,7 +97,6 @@ public:
|
|||||||
ALWAYS_INLINE QEventLoop* getEventLoop() const { return m_event_loop; }
|
ALWAYS_INLINE QEventLoop* getEventLoop() const { return m_event_loop; }
|
||||||
|
|
||||||
ALWAYS_INLINE bool isFullscreen() const { return m_is_fullscreen; }
|
ALWAYS_INLINE bool isFullscreen() const { return m_is_fullscreen; }
|
||||||
ALWAYS_INLINE bool isRenderingToMain() const { return m_is_rendering_to_main; }
|
|
||||||
ALWAYS_INLINE bool isSurfaceless() const { return m_is_surfaceless; }
|
ALWAYS_INLINE bool isSurfaceless() const { return m_is_surfaceless; }
|
||||||
|
|
||||||
ALWAYS_INLINE InputDeviceListModel* getInputDeviceListModel() const { return m_input_device_list_model.get(); }
|
ALWAYS_INLINE InputDeviceListModel* getInputDeviceListModel() const { return m_input_device_list_model.get(); }
|
||||||
@ -111,8 +110,6 @@ public:
|
|||||||
void stopBackgroundControllerPollTimer();
|
void stopBackgroundControllerPollTimer();
|
||||||
void wakeThread();
|
void wakeThread();
|
||||||
|
|
||||||
void checkForSettingsChanges(const Settings& old_settings);
|
|
||||||
|
|
||||||
void bootOrLoadState(std::string path);
|
void bootOrLoadState(std::string path);
|
||||||
|
|
||||||
void updatePerformanceCounters(const GPUBackend* gpu_backend);
|
void updatePerformanceCounters(const GPUBackend* gpu_backend);
|
||||||
@ -146,8 +143,7 @@ Q_SIGNALS:
|
|||||||
void gameListRefreshed();
|
void gameListRefreshed();
|
||||||
void gameListRowsChanged(const QList<int>& rows_changed);
|
void gameListRowsChanged(const QList<int>& rows_changed);
|
||||||
std::optional<WindowInfo> onAcquireRenderWindowRequested(RenderAPI render_api, bool fullscreen,
|
std::optional<WindowInfo> onAcquireRenderWindowRequested(RenderAPI render_api, bool fullscreen,
|
||||||
bool exclusive_fullscreen, bool render_to_main,
|
bool exclusive_fullscreen, bool surfaceless, Error* error);
|
||||||
bool surfaceless, bool use_main_window_pos, Error* error);
|
|
||||||
void onResizeRenderWindowRequested(qint32 width, qint32 height);
|
void onResizeRenderWindowRequested(qint32 width, qint32 height);
|
||||||
void onReleaseRenderWindowRequested();
|
void onReleaseRenderWindowRequested();
|
||||||
void focusDisplayWidgetRequested();
|
void focusDisplayWidgetRequested();
|
||||||
@ -210,8 +206,9 @@ public Q_SLOTS:
|
|||||||
void saveScreenshot();
|
void saveScreenshot();
|
||||||
void redrawDisplayWindow();
|
void redrawDisplayWindow();
|
||||||
void toggleFullscreen();
|
void toggleFullscreen();
|
||||||
void setFullscreen(bool fullscreen, bool allow_render_to_main);
|
void setFullscreen(bool fullscreen);
|
||||||
void setSurfaceless(bool surfaceless);
|
void setSurfaceless(bool surfaceless);
|
||||||
|
void updateDisplayWindow();
|
||||||
void requestDisplaySize(float scale);
|
void requestDisplaySize(float scale);
|
||||||
void applyCheat(const QString& name);
|
void applyCheat(const QString& name);
|
||||||
void reloadPostProcessingShaders();
|
void reloadPostProcessingShaders();
|
||||||
@ -253,7 +250,6 @@ private:
|
|||||||
std::unique_ptr<InputDeviceListModel> m_input_device_list_model;
|
std::unique_ptr<InputDeviceListModel> m_input_device_list_model;
|
||||||
|
|
||||||
bool m_shutdown_flag = false;
|
bool m_shutdown_flag = false;
|
||||||
bool m_is_rendering_to_main = false;
|
|
||||||
bool m_is_fullscreen = false;
|
bool m_is_fullscreen = false;
|
||||||
bool m_is_fullscreen_ui_started = false;
|
bool m_is_fullscreen_ui_started = false;
|
||||||
bool m_gpu_thread_run_idle = false;
|
bool m_gpu_thread_run_idle = false;
|
||||||
@ -364,6 +360,9 @@ bool IsRunningOnWayland();
|
|||||||
/// Returns true if rendering to the main window should be allowed.
|
/// Returns true if rendering to the main window should be allowed.
|
||||||
bool CanRenderToMainWindow();
|
bool CanRenderToMainWindow();
|
||||||
|
|
||||||
|
/// Returns true if the separate-window display widget should use the main window coordinates.
|
||||||
|
bool UseMainWindowGeometryForDisplayWindow();
|
||||||
|
|
||||||
/// Default language for the platform.
|
/// Default language for the platform.
|
||||||
const char* GetDefaultLanguage();
|
const char* GetDefaultLanguage();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user