Qt: Implement mouse locking when rendering to separate window

This commit is contained in:
Ty Lamontagne 2025-10-18 12:56:35 -04:00 committed by Ty
parent 1021199512
commit 773f6968a4

View File

@ -1137,11 +1137,19 @@ bool MainWindow::shouldMouseLock() const
if (!Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false)) if (!Host::GetBoolSettingValue("EmuCore", "EnableMouseLock", false))
return false; return false;
if(m_display_created == false || m_display_widget == nullptr && !isRenderingToMain())
return false;
bool windowsHidden = (!g_debugger_window || g_debugger_window->isHidden()) && 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());
return windowsHidden && (isActiveWindow() || isRenderingFullscreen()); auto* displayWindow = isRenderingToMain() ? window() : m_display_widget->window();
if(displayWindow == nullptr)
return false;
return windowsHidden && (displayWindow->isActiveWindow() || displayWindow->isFullScreen());
} }
bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock) bool MainWindow::shouldAbortForMemcardBusy(const VMLock& lock)
@ -2641,29 +2649,35 @@ void MainWindow::setupMouseMoveHandler()
void MainWindow::checkMousePosition(int x, int y) void MainWindow::checkMousePosition(int x, int y)
{ {
if (!shouldMouseLock()) // This function is called from a different thread on Linux/macOS
return; // kaboom can happen when the widget is destroyed after shouldMouseLock is called, so queue everything to the UI thread
QtHost::RunOnUIThread([this, x, y]() {
if (!shouldMouseLock())
return;
// physical mouse position // physical mouse position
const QPoint physicalPos(x, y); const QPoint physicalPos(x, y);
// logical (DIP) frame rect const auto* displayWindow = getDisplayContainer()->window();
QRectF logicalBounds = isRenderingFullscreen() ? screen()->geometry() : geometry();
// physical frame rect // logical (DIP) frame rect
const qreal scale = window()->devicePixelRatioF(); QRectF logicalBounds = displayWindow->geometry();
QRectF physicalBounds(
logicalBounds.x() * scale,
logicalBounds.y() * scale,
logicalBounds.width() * scale,
logicalBounds.height() * scale);
if (physicalBounds.contains(physicalPos)) // physical frame rect
return; const qreal scale = displayWindow->devicePixelRatioF();
QRectF physicalBounds(
logicalBounds.x() * scale,
logicalBounds.y() * scale,
logicalBounds.width() * scale,
logicalBounds.height() * scale);
Common::SetMousePosition( if (physicalBounds.contains(physicalPos))
std::clamp(physicalPos.x(), (int)physicalBounds.left(), (int)physicalBounds.right()), return;
std::clamp(physicalPos.y(), (int)physicalBounds.top(), (int)physicalBounds.bottom()));
Common::SetMousePosition(
std::clamp(physicalPos.x(), (int)physicalBounds.left(), (int)physicalBounds.right()),
std::clamp(physicalPos.y(), (int)physicalBounds.top(), (int)physicalBounds.bottom()));
});
} }
void MainWindow::saveDisplayWindowGeometryToConfig() void MainWindow::saveDisplayWindowGeometryToConfig()