| 3056 | } |
| 3057 | |
| 3058 | void MainWindow::checkMousePosition(int x, int y) |
| 3059 | { |
| 3060 | // This function is called from a different thread on Linux/macOS |
| 3061 | // kaboom can happen when the widget is destroyed after shouldMouseLock is called, so queue everything to the UI thread |
| 3062 | QtHost::RunOnUIThread([this, x, y]() { |
| 3063 | if (!shouldMouseLock()) |
| 3064 | return; |
| 3065 | |
| 3066 | // physical mouse position |
| 3067 | const QPoint physicalPos(x, y); |
| 3068 | |
| 3069 | const auto* displayWindow = m_display_surface; |
| 3070 | |
| 3071 | // logical (DIP) frame rect |
| 3072 | const QSize logicalSize = displayWindow->size(); |
| 3073 | #ifdef DISPLAY_SURFACE_WINDOW |
| 3074 | const QPoint logicalPosition = isRenderingToMain() ? (displayWindow->position() + displayWindow->parent()->position()) : displayWindow->position(); |
| 3075 | #else |
| 3076 | const QPoint logicalPosition = displayWindow->position() + displayWindow->parent()->position(); |
| 3077 | #endif |
| 3078 | |
| 3079 | // The offset to the origin of the current screen is in device-independent pixels while the origin itself is native! |
| 3080 | // The logicalPosition is the sum of these two values, so we need to separate them and only scale the offset |
| 3081 | const QScreen* screen = displayWindow->screen(); |
| 3082 | |
| 3083 | // If we fail to get the screen associated with the window, avoid mouse locking as it's probably in an unexpected position. |
| 3084 | if (!screen) |
| 3085 | return; |
| 3086 | |
| 3087 | const QPoint screenPosition = screen->geometry().topLeft(); |
| 3088 | |
| 3089 | // physical frame rect |
| 3090 | const qreal scale = displayWindow->devicePixelRatio(); |
| 3091 | const QRectF physicalBounds( |
| 3092 | screenPosition.x() + (logicalPosition.x() - screenPosition.x()) * scale, |
| 3093 | screenPosition.y() + (logicalPosition.y() - screenPosition.y()) * scale, |
| 3094 | logicalSize.width() * scale, |
| 3095 | logicalSize.height() * scale); |
| 3096 | |
| 3097 | if (physicalBounds.contains(physicalPos)) |
| 3098 | return; |
| 3099 | |
| 3100 | Common::SetMousePosition( |
| 3101 | std::clamp(physicalPos.x(), (int)physicalBounds.left(), (int)physicalBounds.right()), |
| 3102 | std::clamp(physicalPos.y(), (int)physicalBounds.top(), (int)physicalBounds.bottom())); |
| 3103 | }); |
| 3104 | } |
| 3105 | |
| 3106 | void MainWindow::saveDisplayWindowGeometryToConfig() |
| 3107 | { |
no test coverage detected