mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
Merge f1928a75a5 into 7fab935c2d
This commit is contained in:
commit
3571782840
@ -133,7 +133,7 @@ void DisplaySurface::handleCloseEvent(QCloseEvent* event)
|
|||||||
// In the latter case, it's going to destroy us, so don't let Qt do it first.
|
// In the latter case, it's going to destroy us, so don't let Qt do it first.
|
||||||
// Treat a close event while fullscreen as an exit, that way ALT+F4 closes PCSX2,
|
// Treat a close event while fullscreen as an exit, that way ALT+F4 closes PCSX2,
|
||||||
// rather than just the game.
|
// rather than just the game.
|
||||||
if (QtHost::IsVMValid() && !isActuallyFullscreen())
|
if (QtHost::IsVMValid() && !isFullScreen())
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Q_ARG(bool, true),
|
QMetaObject::invokeMethod(g_main_window, "requestShutdown", Q_ARG(bool, true),
|
||||||
Q_ARG(bool, true), Q_ARG(bool, false));
|
Q_ARG(bool, true), Q_ARG(bool, false));
|
||||||
@ -147,10 +147,44 @@ void DisplaySurface::handleCloseEvent(QCloseEvent* event)
|
|||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisplaySurface::isActuallyFullscreen() const
|
bool DisplaySurface::isFullScreen() const
|
||||||
{
|
{
|
||||||
// DisplaySurface is always in a container, so we need to check parent window
|
// DisplaySurface may be in a container
|
||||||
return parent()->windowState() & Qt::WindowFullScreen;
|
return (parent() ? parent()->windowState() : windowState()) & Qt::WindowFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplaySurface::setFocus()
|
||||||
|
{
|
||||||
|
if (m_container)
|
||||||
|
m_container->setFocus();
|
||||||
|
else
|
||||||
|
requestActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray DisplaySurface::saveGeometry() const
|
||||||
|
{
|
||||||
|
if (m_container)
|
||||||
|
return m_container->saveGeometry();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// QWindow lacks saveGeometry, so create a dummy widget and copy geometry across.
|
||||||
|
QWidget dummy = QWidget();
|
||||||
|
dummy.setGeometry(geometry());
|
||||||
|
return dummy.saveGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplaySurface::restoreGeometry(const QByteArray& geometry)
|
||||||
|
{
|
||||||
|
if (m_container)
|
||||||
|
m_container->restoreGeometry(geometry);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// QWindow lacks restoreGeometry, so create a dummy widget and copy geometry across.
|
||||||
|
QWidget dummy = QWidget();
|
||||||
|
dummy.restoreGeometry(geometry);
|
||||||
|
setGeometry(dummy.geometry());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplaySurface::updateCenterPos()
|
void DisplaySurface::updateCenterPos()
|
||||||
@ -393,10 +427,18 @@ bool DisplaySurface::event(QEvent* event)
|
|||||||
return event->isAccepted();
|
return event->isAccepted();
|
||||||
|
|
||||||
case QEvent::Move:
|
case QEvent::Move:
|
||||||
{
|
|
||||||
updateCenterPos();
|
updateCenterPos();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
// These events only work on the top level control.
|
||||||
|
// Which is this container when render to seperate or fullscreen is active (Windows).
|
||||||
|
case QEvent::Close:
|
||||||
|
handleCloseEvent(static_cast<QCloseEvent*>(event));
|
||||||
|
return true;
|
||||||
|
case QEvent::WindowStateChange:
|
||||||
|
if (static_cast<QWindowStateChangeEvent*>(event)->oldState() & Qt::WindowMinimized)
|
||||||
|
emit windowRestoredEvent();
|
||||||
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QWindow::event(event);
|
return QWindow::event(event);
|
||||||
@ -418,7 +460,7 @@ bool DisplaySurface::eventFilter(QObject* object, QEvent* event)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// These events only work on the top level control.
|
// These events only work on the top level control.
|
||||||
// Which is this container when render to seperate or fullscreen is active.
|
// Which is this container when render to seperate or fullscreen is active (Non-Windows).
|
||||||
case QEvent::Close:
|
case QEvent::Close:
|
||||||
handleCloseEvent(static_cast<QCloseEvent*>(event));
|
handleCloseEvent(static_cast<QCloseEvent*>(event));
|
||||||
return true;
|
return true;
|
||||||
@ -427,8 +469,8 @@ bool DisplaySurface::eventFilter(QObject* object, QEvent* event)
|
|||||||
emit windowRestoredEvent();
|
emit windowRestoredEvent();
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case QEvent::ChildRemoved:
|
case QEvent::ChildWindowRemoved:
|
||||||
if (static_cast<QChildEvent*>(event)->child() == m_container)
|
if (static_cast<QChildWindowEvent*>(event)->child() == this)
|
||||||
{
|
{
|
||||||
object->removeEventFilter(this);
|
object->removeEventFilter(this);
|
||||||
m_container = nullptr;
|
m_container = nullptr;
|
||||||
|
|||||||
@ -30,6 +30,12 @@ public:
|
|||||||
void updateRelativeMode(bool enabled);
|
void updateRelativeMode(bool enabled);
|
||||||
void updateCursor(bool hidden);
|
void updateCursor(bool hidden);
|
||||||
|
|
||||||
|
bool isFullScreen() const;
|
||||||
|
void setFocus();
|
||||||
|
|
||||||
|
QByteArray saveGeometry() const;
|
||||||
|
void restoreGeometry(const QByteArray& geometry);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void windowResizedEvent(int width, int height, float scale);
|
void windowResizedEvent(int width, int height, float scale);
|
||||||
void windowRestoredEvent();
|
void windowRestoredEvent();
|
||||||
@ -47,7 +53,6 @@ private Q_SLOTS:
|
|||||||
void onResizeDebounceTimer();
|
void onResizeDebounceTimer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isActuallyFullscreen() const;
|
|
||||||
void updateCenterPos();
|
void updateCenterPos();
|
||||||
|
|
||||||
QPoint m_relative_mouse_start_pos{};
|
QPoint m_relative_mouse_start_pos{};
|
||||||
|
|||||||
@ -100,6 +100,13 @@ static quint32 s_current_running_crc;
|
|||||||
static bool s_record_on_start = false;
|
static bool s_record_on_start = false;
|
||||||
static QString s_path_to_recording_for_record_on_start;
|
static QString s_path_to_recording_for_record_on_start;
|
||||||
|
|
||||||
|
// DX cannot fullscreen when the display surface is in a container.
|
||||||
|
// QWindow, however, seems to lack CSD under wayland, so needs the container.
|
||||||
|
// MAC is unknown
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define DISPLAY_SURFACE_WINDOW
|
||||||
|
#endif
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
pxAssert(!g_main_window);
|
pxAssert(!g_main_window);
|
||||||
@ -1008,10 +1015,15 @@ void MainWindow::updateWindowTitle()
|
|||||||
if (windowTitle() != main_title)
|
if (windowTitle() != main_title)
|
||||||
setWindowTitle(main_title);
|
setWindowTitle(main_title);
|
||||||
|
|
||||||
if (m_display_container && !isRenderingToMain())
|
if (m_display_surface && !isRenderingToMain())
|
||||||
{
|
{
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (m_display_surface->title() != display_title)
|
||||||
|
m_display_surface->setTitle(display_title);
|
||||||
|
#else
|
||||||
if (m_display_container->windowTitle() != display_title)
|
if (m_display_container->windowTitle() != display_title)
|
||||||
m_display_container->setWindowTitle(display_title);
|
m_display_container->setWindowTitle(display_title);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_log_window)
|
if (g_log_window)
|
||||||
@ -1040,7 +1052,13 @@ void MainWindow::updateWindowState(bool force_visible)
|
|||||||
|
|
||||||
// Update the display widget too if rendering separately.
|
// Update the display widget too if rendering separately.
|
||||||
if (m_display_surface && !isRenderingToMain())
|
if (m_display_surface && !isRenderingToMain())
|
||||||
|
{
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
QtUtils::SetWindowResizeable(m_display_surface, resizeable);
|
||||||
|
#else
|
||||||
QtUtils::SetWindowResizeable(m_display_container, resizeable);
|
QtUtils::SetWindowResizeable(m_display_container, resizeable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setProgressBar(int current, int total)
|
void MainWindow::setProgressBar(int current, int total)
|
||||||
@ -1075,12 +1093,12 @@ bool MainWindow::isRenderingFullscreen() const
|
|||||||
if (!MTGS::IsOpen() || !m_display_surface)
|
if (!MTGS::IsOpen() || !m_display_surface)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return m_display_container->isFullScreen();
|
return m_display_surface->isFullScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::isRenderingToMain() const
|
bool MainWindow::isRenderingToMain() const
|
||||||
{
|
{
|
||||||
return (m_display_surface && m_ui.mainContainer->indexOf(m_display_container) == 1);
|
return (m_display_container && m_ui.mainContainer->indexOf(m_display_container) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::shouldHideMouseCursor() const
|
bool MainWindow::shouldHideMouseCursor() const
|
||||||
@ -1108,16 +1126,25 @@ bool MainWindow::shouldMouseLock() const
|
|||||||
if (m_display_created == false || m_display_surface == nullptr)
|
if (m_display_created == false || m_display_surface == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool windowsHidden = (!g_debugger_window || g_debugger_window->isHidden()) &&
|
const bool windowsHidden = (!g_debugger_window || g_debugger_window->isHidden()) &&
|
||||||
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
|
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
|
||||||
(!m_settings_window || m_settings_window->isHidden());
|
(!m_settings_window || m_settings_window->isHidden());
|
||||||
|
|
||||||
auto* displayWindow = isRenderingToMain() ? window() : m_display_container->window();
|
if (!windowsHidden)
|
||||||
|
|
||||||
if (displayWindow == nullptr)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return windowsHidden && (displayWindow->isActiveWindow() || displayWindow->isFullScreen());
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (isRenderingToMain())
|
||||||
|
{
|
||||||
|
const auto* displayWindow = window();
|
||||||
|
return displayWindow ? (displayWindow->isActiveWindow() || displayWindow->isFullScreen()) : false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return m_display_surface->isActive() || m_display_surface->isFullScreen();
|
||||||
|
#else
|
||||||
|
const auto* displayWindow = isRenderingToMain() ? window() : m_display_container->window();
|
||||||
|
return displayWindow ? (displayWindow->isActiveWindow() || displayWindow->isFullScreen()) : false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
|
bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
|
||||||
@ -1180,7 +1207,7 @@ void MainWindow::switchToEmulationView()
|
|||||||
g_emu_thread->setVMPaused(false);
|
g_emu_thread->setVMPaused(false);
|
||||||
|
|
||||||
if (m_display_surface)
|
if (m_display_surface)
|
||||||
m_display_container->setFocus();
|
m_display_surface->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshGameList(bool invalidate_cache, bool popup_on_error)
|
void MainWindow::refreshGameList(bool invalidate_cache, bool popup_on_error)
|
||||||
@ -2129,7 +2156,7 @@ void MainWindow::onVMResumed()
|
|||||||
if (m_display_surface)
|
if (m_display_surface)
|
||||||
{
|
{
|
||||||
updateDisplayWidgetCursor();
|
updateDisplayWidgetCursor();
|
||||||
m_display_container->setFocus();
|
m_display_surface->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2449,21 +2476,25 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(bool recreate_window,
|
|||||||
if (!is_fullscreen && !is_rendering_to_main)
|
if (!is_fullscreen && !is_rendering_to_main)
|
||||||
saveDisplayWindowGeometryToConfig();
|
saveDisplayWindowGeometryToConfig();
|
||||||
|
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
auto* displayWindow = m_display_surface;
|
||||||
|
#else
|
||||||
|
auto* displayWindow = m_display_container;
|
||||||
|
#endif
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
{
|
displayWindow->showFullScreen();
|
||||||
m_display_container->showFullScreen();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Needs to exit fullscreen before resizing
|
||||||
|
displayWindow->showNormal();
|
||||||
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
|
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
|
||||||
m_display_container->setGeometry(geometry());
|
displayWindow->setGeometry(geometry());
|
||||||
else
|
else
|
||||||
restoreDisplayWindowGeometryFromConfig();
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
m_display_container->showNormal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDisplayWidgetCursor();
|
updateDisplayWidgetCursor();
|
||||||
m_display_container->setFocus();
|
m_display_surface->setFocus();
|
||||||
updateWindowState();
|
updateWindowState();
|
||||||
|
|
||||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
@ -2500,7 +2531,7 @@ std::optional<WindowInfo> MainWindow::acquireRenderWindow(bool recreate_window,
|
|||||||
updateWindowState();
|
updateWindowState();
|
||||||
|
|
||||||
updateDisplayWidgetCursor();
|
updateDisplayWidgetCursor();
|
||||||
m_display_container->setFocus();
|
m_display_surface->setFocus();
|
||||||
return wi;
|
return wi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2517,9 +2548,14 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
|
|||||||
m_display_surface = new DisplaySurface();
|
m_display_surface = new DisplaySurface();
|
||||||
if (fullscreen || !render_to_main)
|
if (fullscreen || !render_to_main)
|
||||||
{
|
{
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
m_display_surface->setTitle(windowTitle());
|
||||||
|
m_display_surface->setIcon(windowIcon());
|
||||||
|
#else
|
||||||
m_display_container = m_display_surface->createWindowContainer();
|
m_display_container = m_display_surface->createWindowContainer();
|
||||||
m_display_container->setWindowTitle(windowTitle());
|
m_display_container->setWindowTitle(windowTitle());
|
||||||
m_display_container->setWindowIcon(windowIcon());
|
m_display_container->setWindowIcon(windowIcon());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2528,20 +2564,38 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main)
|
|||||||
|
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
{
|
{
|
||||||
// On Wayland, while move/restoreGeometry can't position the window, it can influence which screen they show up on
|
// 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.
|
||||||
|
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (isVisible() && g_emu_thread->shouldRenderToMain())
|
||||||
|
m_display_surface->setFramePosition(pos());
|
||||||
|
else
|
||||||
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
|
m_display_surface->showFullScreen();
|
||||||
|
#else
|
||||||
if (isVisible() && g_emu_thread->shouldRenderToMain())
|
if (isVisible() && g_emu_thread->shouldRenderToMain())
|
||||||
m_display_container->move(pos());
|
m_display_container->move(pos());
|
||||||
else
|
else
|
||||||
restoreDisplayWindowGeometryFromConfig();
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
m_display_container->showFullScreen();
|
m_display_container->showFullScreen();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (!render_to_main)
|
else if (!render_to_main)
|
||||||
{
|
{
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
|
||||||
|
m_display_surface->setGeometry(geometry());
|
||||||
|
else
|
||||||
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
|
m_display_surface->showNormal();
|
||||||
|
#else
|
||||||
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
|
if (m_is_temporarily_windowed && g_emu_thread->shouldRenderToMain())
|
||||||
m_display_container->setGeometry(geometry());
|
m_display_container->setGeometry(geometry());
|
||||||
else
|
else
|
||||||
restoreDisplayWindowGeometryFromConfig();
|
restoreDisplayWindowGeometryFromConfig();
|
||||||
m_display_container->showNormal();
|
m_display_container->showNormal();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2570,12 +2624,21 @@ void MainWindow::displayResizeRequested(qint32 width, qint32 height)
|
|||||||
width = static_cast<qint32>(std::max(static_cast<int>(std::lroundf(static_cast<float>(width) / dpr)), 1));
|
width = static_cast<qint32>(std::max(static_cast<int>(std::lroundf(static_cast<float>(width) / dpr)), 1));
|
||||||
height = static_cast<qint32>(std::max(static_cast<int>(std::lroundf(static_cast<float>(height) / dpr)), 1));
|
height = static_cast<qint32>(std::max(static_cast<int>(std::lroundf(static_cast<float>(height) / dpr)), 1));
|
||||||
|
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (!m_display_container)
|
||||||
|
{
|
||||||
|
// no parent - rendering to separate window. easy.
|
||||||
|
QtUtils::ResizePotentiallyFixedSizeWindow(m_display_surface, width, height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!m_display_container->parent())
|
if (!m_display_container->parent())
|
||||||
{
|
{
|
||||||
// no parent - rendering to separate window. easy.
|
// no parent - rendering to separate window. easy.
|
||||||
QtUtils::ResizePotentiallyFixedSizeWindow(m_display_container, width, height);
|
QtUtils::ResizePotentiallyFixedSizeWindow(m_display_container, width, height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// we are rendering to the main window. we have to add in the extra height from the toolbar/status bar.
|
// we are rendering to the main window. we have to add in the extra height from the toolbar/status bar.
|
||||||
const s32 extra_height = this->height() - m_display_container->height();
|
const s32 extra_height = this->height() - m_display_container->height();
|
||||||
@ -2608,7 +2671,7 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
|
|||||||
if (!m_display_surface)
|
if (!m_display_surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!isRenderingFullscreen() && !isRenderingToMain())
|
if (!m_display_surface->isFullScreen() && !isRenderingToMain())
|
||||||
saveDisplayWindowGeometryToConfig();
|
saveDisplayWindowGeometryToConfig();
|
||||||
|
|
||||||
if (isRenderingToMain())
|
if (isRenderingToMain())
|
||||||
@ -2622,12 +2685,18 @@ void MainWindow::destroyDisplayWidget(bool show_game_list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// displau surface is always in a container
|
if (m_display_container)
|
||||||
pxAssert(m_display_container != nullptr);
|
{
|
||||||
m_display_container->deleteLater();
|
m_display_container->deleteLater();
|
||||||
m_display_container = nullptr;
|
m_display_container = nullptr;
|
||||||
// m_display_surface will be destroyed by the container's dtor
|
// m_display_surface will be destroyed by the container's dtor
|
||||||
m_display_surface = nullptr;
|
m_display_surface = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_display_surface->deleteLater();
|
||||||
|
m_display_surface = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
updateDisplayRelatedActions(false, false, false);
|
updateDisplayRelatedActions(false, false, false);
|
||||||
}
|
}
|
||||||
@ -2639,14 +2708,6 @@ void MainWindow::updateDisplayWidgetCursor()
|
|||||||
m_display_surface->updateCursor(s_vm_valid && !s_vm_paused && shouldHideMouseCursor());
|
m_display_surface->updateCursor(s_vm_valid && !s_vm_paused && shouldHideMouseCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::focusDisplayWidget()
|
|
||||||
{
|
|
||||||
if (!m_display_surface || centralWidget() != m_display_container)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_display_container->setFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::setupMouseMoveHandler()
|
void MainWindow::setupMouseMoveHandler()
|
||||||
{
|
{
|
||||||
auto mouse_cb_fn = [](int x, int y) {
|
auto mouse_cb_fn = [](int x, int y) {
|
||||||
@ -2677,7 +2738,11 @@ void MainWindow::checkMousePosition(int x, int y)
|
|||||||
|
|
||||||
// logical (DIP) frame rect
|
// logical (DIP) frame rect
|
||||||
const QSize logicalSize = displayWindow->size();
|
const QSize logicalSize = displayWindow->size();
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
const QPoint logicalPosition = isRenderingToMain() ? (displayWindow->position() + displayWindow->parent()->position()) : displayWindow->position();
|
||||||
|
#else
|
||||||
const QPoint logicalPosition = displayWindow->position() + displayWindow->parent()->position();
|
const QPoint logicalPosition = displayWindow->position() + displayWindow->parent()->position();
|
||||||
|
#endif
|
||||||
|
|
||||||
// The offset to the origin of the current screen is in device-independent pixels while the origin itself is native!
|
// The offset to the origin of the current screen is in device-independent pixels while the origin itself is native!
|
||||||
// The logicalPosition is the sum of these two values, so we need to separate them and only scale the offset
|
// The logicalPosition is the sum of these two values, so we need to separate them and only scale the offset
|
||||||
@ -2708,13 +2773,13 @@ void MainWindow::checkMousePosition(int x, int y)
|
|||||||
|
|
||||||
void MainWindow::saveDisplayWindowGeometryToConfig()
|
void MainWindow::saveDisplayWindowGeometryToConfig()
|
||||||
{
|
{
|
||||||
if (m_display_container->windowState() & Qt::WindowFullScreen)
|
if (m_display_surface->isFullScreen())
|
||||||
{
|
{
|
||||||
// if we somehow ended up here, don't save the fullscreen state to the config
|
// if we somehow ended up here, don't save the fullscreen state to the config
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray geometry = m_display_container->saveGeometry();
|
const QByteArray geometry = m_display_surface->saveGeometry();
|
||||||
const QByteArray geometry_b64 = geometry.toBase64();
|
const QByteArray geometry_b64 = geometry.toBase64();
|
||||||
const std::string old_geometry_b64 = Host::GetBaseStringSettingValue("UI", "DisplayWindowGeometry");
|
const std::string old_geometry_b64 = Host::GetBaseStringSettingValue("UI", "DisplayWindowGeometry");
|
||||||
if (old_geometry_b64 != geometry_b64.constData())
|
if (old_geometry_b64 != geometry_b64.constData())
|
||||||
@ -2730,15 +2795,23 @@ void MainWindow::restoreDisplayWindowGeometryFromConfig()
|
|||||||
const QByteArray geometry = QByteArray::fromBase64(QByteArray::fromStdString(geometry_b64));
|
const QByteArray geometry = QByteArray::fromBase64(QByteArray::fromStdString(geometry_b64));
|
||||||
if (!geometry.isEmpty())
|
if (!geometry.isEmpty())
|
||||||
{
|
{
|
||||||
m_display_container->restoreGeometry(geometry);
|
m_display_surface->restoreGeometry(geometry);
|
||||||
|
|
||||||
// make sure we're not loading a dodgy config which had fullscreen set...
|
// make sure we're not loading a dodgy config which had fullscreen set...
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
m_display_surface->setWindowStates(m_display_surface->windowStates() & ~(Qt::WindowFullScreen | Qt::WindowActive));
|
||||||
|
#else
|
||||||
m_display_container->setWindowState(m_display_container->windowState() & ~(Qt::WindowFullScreen | Qt::WindowActive));
|
m_display_container->setWindowState(m_display_container->windowState() & ~(Qt::WindowFullScreen | Qt::WindowActive));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// default size
|
// default size
|
||||||
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
m_display_surface->resize(640, 480);
|
||||||
|
#else
|
||||||
m_display_container->resize(640, 480);
|
m_display_container->resize(640, 480);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3308,7 +3381,7 @@ MainWindow::VMLock MainWindow::pauseAndLockVM()
|
|||||||
g_emu_thread->setFullscreen(false, false);
|
g_emu_thread->setFullscreen(false, false);
|
||||||
|
|
||||||
// Process events untill both EmuThread and Qt have finished exiting fullscreen
|
// Process events untill both EmuThread and Qt have finished exiting fullscreen
|
||||||
while (QtHost::IsVMValid() && (g_emu_thread->isFullscreen() || m_display_container->isFullScreen()))
|
while (QtHost::IsVMValid() && (g_emu_thread->isFullscreen() || m_display_surface->isFullScreen()))
|
||||||
{
|
{
|
||||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
}
|
}
|
||||||
@ -3320,7 +3393,27 @@ MainWindow::VMLock MainWindow::pauseAndLockVM()
|
|||||||
g_main_window->raise();
|
g_main_window->raise();
|
||||||
g_main_window->activateWindow();
|
g_main_window->activateWindow();
|
||||||
|
|
||||||
return VMLock(m_display_container, was_paused, was_fullscreen);
|
#ifdef DISPLAY_SURFACE_WINDOW
|
||||||
|
if (!m_display_container)
|
||||||
|
{
|
||||||
|
// Create a temporary parent for the dialog.
|
||||||
|
QWidget* dialog_parent = new QWidget();
|
||||||
|
dialog_parent->setAttribute(Qt::WA_NativeWindow);
|
||||||
|
QWindow* window_handle = dialog_parent->windowHandle();
|
||||||
|
|
||||||
|
// Set the transient parent to the display surface.
|
||||||
|
// This will position the dialog_parent over the display surface (and thus so will any dialogs)
|
||||||
|
// and also enforces the focus lock of modal dialogs against the display surface.
|
||||||
|
// This works even without showing the dialog_parent window.
|
||||||
|
window_handle->setTransientParent(m_display_surface);
|
||||||
|
|
||||||
|
return VMLock(dialog_parent, was_paused, was_fullscreen, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return VMLock(m_display_container, was_paused, was_fullscreen, false);
|
||||||
|
#else
|
||||||
|
return VMLock(m_display_container, was_paused, was_fullscreen, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::rescanFile(const std::string& path)
|
void MainWindow::rescanFile(const std::string& path)
|
||||||
@ -3328,11 +3421,12 @@ void MainWindow::rescanFile(const std::string& path)
|
|||||||
m_game_list_widget->rescanFile(path);
|
m_game_list_widget->rescanFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::VMLock::VMLock(QWidget* dialog_parent, bool was_paused, bool was_fullscreen)
|
MainWindow::VMLock::VMLock(QWidget* dialog_parent, bool was_paused, bool was_fullscreen, bool owns_parent)
|
||||||
: m_dialog_parent(dialog_parent)
|
: m_dialog_parent(dialog_parent)
|
||||||
, m_has_lock(true)
|
, m_has_lock(true)
|
||||||
, m_was_paused(was_paused)
|
, m_was_paused(was_paused)
|
||||||
, m_was_fullscreen(was_fullscreen)
|
, m_was_fullscreen(was_fullscreen)
|
||||||
|
, m_owns_dialog_parent(owns_parent)
|
||||||
{
|
{
|
||||||
QtHost::LockVMWithDialog();
|
QtHost::LockVMWithDialog();
|
||||||
}
|
}
|
||||||
@ -3342,11 +3436,13 @@ MainWindow::VMLock::VMLock(VMLock&& lock)
|
|||||||
, m_has_lock(lock.m_has_lock)
|
, m_has_lock(lock.m_has_lock)
|
||||||
, m_was_paused(lock.m_was_paused)
|
, m_was_paused(lock.m_was_paused)
|
||||||
, m_was_fullscreen(lock.m_was_fullscreen)
|
, m_was_fullscreen(lock.m_was_fullscreen)
|
||||||
|
, m_owns_dialog_parent(lock.m_owns_dialog_parent)
|
||||||
{
|
{
|
||||||
lock.m_dialog_parent = nullptr;
|
lock.m_dialog_parent = nullptr;
|
||||||
lock.m_has_lock = false;
|
lock.m_has_lock = false;
|
||||||
lock.m_was_paused = true;
|
lock.m_was_paused = true;
|
||||||
lock.m_was_fullscreen = false;
|
lock.m_was_fullscreen = false;
|
||||||
|
lock.m_owns_dialog_parent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::VMLock::~VMLock()
|
MainWindow::VMLock::~VMLock()
|
||||||
@ -3354,6 +3450,12 @@ MainWindow::VMLock::~VMLock()
|
|||||||
if (m_has_lock)
|
if (m_has_lock)
|
||||||
QtHost::UnlockVMWithDialog();
|
QtHost::UnlockVMWithDialog();
|
||||||
|
|
||||||
|
if (m_owns_dialog_parent && m_dialog_parent)
|
||||||
|
{
|
||||||
|
m_dialog_parent->deleteLater();
|
||||||
|
m_dialog_parent = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_was_fullscreen)
|
if (m_was_fullscreen)
|
||||||
{
|
{
|
||||||
g_main_window->m_is_temporarily_windowed = false;
|
g_main_window->m_is_temporarily_windowed = false;
|
||||||
|
|||||||
@ -65,13 +65,14 @@ public:
|
|||||||
void cancelResume();
|
void cancelResume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMLock(QWidget* dialog_parent, bool was_paused, bool was_exclusive_fullscreen);
|
VMLock(QWidget* dialog_parent, bool was_paused, bool was_exclusive_fullscreen, bool owns_parent);
|
||||||
friend MainWindow;
|
friend MainWindow;
|
||||||
|
|
||||||
QWidget* m_dialog_parent;
|
QWidget* m_dialog_parent;
|
||||||
bool m_has_lock;
|
bool m_has_lock;
|
||||||
bool m_was_paused;
|
bool m_was_paused;
|
||||||
bool m_was_fullscreen;
|
bool m_was_fullscreen;
|
||||||
|
bool m_owns_dialog_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Default filter for opening a file.
|
/// Default filter for opening a file.
|
||||||
@ -138,7 +139,6 @@ private Q_SLOTS:
|
|||||||
void displayResizeRequested(qint32 width, qint32 height);
|
void displayResizeRequested(qint32 width, qint32 height);
|
||||||
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
void mouseModeRequested(bool relative_mode, bool hide_cursor);
|
||||||
void releaseRenderWindow();
|
void releaseRenderWindow();
|
||||||
void focusDisplayWidget();
|
|
||||||
void setupMouseMoveHandler();
|
void setupMouseMoveHandler();
|
||||||
void onGameListRefreshComplete();
|
void onGameListRefreshComplete();
|
||||||
void onGameListRefreshProgress(const QString& status, int current, int total);
|
void onGameListRefreshProgress(const QString& status, int current, int total);
|
||||||
|
|||||||
@ -366,6 +366,25 @@ namespace QtUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetWindowResizeable(QWindow* window, bool resizeable)
|
||||||
|
{
|
||||||
|
if (resizeable)
|
||||||
|
{
|
||||||
|
// Min/max numbers come from uic.
|
||||||
|
window->setMinimumWidth(1);
|
||||||
|
window->setMinimumHeight(1);
|
||||||
|
window->setMaximumWidth(16777215);
|
||||||
|
window->setMaximumHeight(16777215);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->setMinimumWidth(window->width());
|
||||||
|
window->setMinimumHeight(window->height());
|
||||||
|
window->setMaximumWidth(window->width());
|
||||||
|
window->setMaximumHeight(window->height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ResizePotentiallyFixedSizeWindow(QWidget* widget, int width, int height)
|
void ResizePotentiallyFixedSizeWindow(QWidget* widget, int width, int height)
|
||||||
{
|
{
|
||||||
width = std::max(width, 1);
|
width = std::max(width, 1);
|
||||||
@ -376,6 +395,22 @@ namespace QtUtils
|
|||||||
widget->resize(width, height);
|
widget->resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResizePotentiallyFixedSizeWindow(QWindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
width = std::max(width, 1);
|
||||||
|
height = std::max(height, 1);
|
||||||
|
|
||||||
|
if (window->minimumHeight() == window->maximumHeight())
|
||||||
|
{
|
||||||
|
window->setMinimumWidth(width);
|
||||||
|
window->setMinimumHeight(height);
|
||||||
|
window->setMaximumWidth(width);
|
||||||
|
window->setMaximumHeight(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
window->resize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
QString AbstractItemModelToCSV(QAbstractItemModel* model, int role, bool useQuotes)
|
QString AbstractItemModelToCSV(QAbstractItemModel* model, int role, bool useQuotes)
|
||||||
{
|
{
|
||||||
QString csv;
|
QString csv;
|
||||||
|
|||||||
@ -102,9 +102,11 @@ namespace QtUtils
|
|||||||
|
|
||||||
/// Changes whether a window is resizable.
|
/// Changes whether a window is resizable.
|
||||||
void SetWindowResizeable(QWidget* widget, bool resizeable);
|
void SetWindowResizeable(QWidget* widget, bool resizeable);
|
||||||
|
void SetWindowResizeable(QWindow* window, bool resizeable);
|
||||||
|
|
||||||
/// Adjusts the fixed size for a window if it's not resizeable.
|
/// Adjusts the fixed size for a window if it's not resizeable.
|
||||||
void ResizePotentiallyFixedSizeWindow(QWidget* widget, int width, int height);
|
void ResizePotentiallyFixedSizeWindow(QWidget* widget, int width, int height);
|
||||||
|
void ResizePotentiallyFixedSizeWindow(QWindow* window, int width, int height);
|
||||||
|
|
||||||
/// Returns the common window info structure for a Qt Window/Widget.
|
/// Returns the common window info structure for a Qt Window/Widget.
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user