diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index 1fccc00fb8..3601a14274 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -135,13 +135,42 @@ void gs_frame::paintEvent(QPaintEvent *event) void gs_frame::showEvent(QShowEvent *event) { - // We have to calculate new window positions, since the frame is only known once the window was created - const QRect available_geometry = screen()->availableGeometry(); - QPoint pos = m_initial_geometry.topLeft(); - pos.setX(std::min(std::max(pos.x() - ((frameGeometry().width() - width()) / 2), available_geometry.left()), - available_geometry.left() + available_geometry.width() - frameGeometry().width())); - pos.setY(std::min(std::max(pos.y() - ((frameGeometry().height() - height()) / 2), available_geometry.top()), - available_geometry.top() + available_geometry.height() - frameGeometry().height())); + // We have to calculate new window positions, since the frame is only known once the window was created. + // We will try to find the originally requested dimensions if possible by moving the frame. + + // NOTES: The parameter m_initial_geometry is not necessarily equal to our actual geometry() at this point. + // That's why we use m_initial_geometry instead of the frameGeometry() in some places. + // All of these values, including the screen geometry, can also be negative numbers. + + const QRect available_geometry = screen()->availableGeometry(); // The available screen geometry + const QRect inner_geometry = geometry(); // The current inner geometry + const QRect outer_geometry = frameGeometry(); // The current outer geometry + + // Calculate the left and top frame borders (this will include window handles) + const int left_border = inner_geometry.left() - outer_geometry.left(); + const int top_border = inner_geometry.top() - outer_geometry.top(); + + // Calculate the initially expected frame origin + const QPoint expected_pos(m_initial_geometry.left() - left_border, + m_initial_geometry.top() - top_border); + + // Make sure that the expected position is inside the screen (check left and top borders) + QPoint pos(std::max(expected_pos.x(), available_geometry.left()), + std::max(expected_pos.y(), available_geometry.top())); + + // Find the maximum position that still ensures that the frame is completely visible inside the screen (check right and bottom borders) + QPoint max_pos(available_geometry.left() + available_geometry.width() - frameGeometry().width(), + available_geometry.top() + available_geometry.height() - frameGeometry().height()); + + // Make sure that the "maximum" position is inside the screen (check left and top borders) + max_pos.setX(std::max(max_pos.x(), available_geometry.left())); + max_pos.setY(std::max(max_pos.y(), available_geometry.top())); + + // Adjust the expected position accordingly + pos.setX(std::min(pos.x(), max_pos.x())); + pos.setY(std::min(pos.y(), max_pos.y())); + + // Set the new position setFramePosition(pos); QWindow::showEvent(event);