From 9dfadc8b3074109dab8e47a24bc60e9ea956c579 Mon Sep 17 00:00:00 2001 From: Purple <38256064+IamSanjid@users.noreply.github.com> Date: Wed, 20 Apr 2022 02:22:51 +0600 Subject: [PATCH] Prevent the mouse cursor from leaving the window when mouse panning is enabled --- src/yuzu/main.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- src/yuzu/main.h | 3 +++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 52879a989..5e26aad29 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -152,7 +152,8 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif -constexpr int default_mouse_timeout = 2500; +constexpr int default_mouse_hide_timeout = 2500; +constexpr int default_mouse_center_timeout = 10; /** * "Callouts" are one-time instructional messages shown to the user. In the config settings, there @@ -287,10 +288,13 @@ GMainWindow::GMainWindow() ui->menubar->setCursor(QCursor()); statusBar()->setCursor(QCursor()); - mouse_hide_timer.setInterval(default_mouse_timeout); + mouse_hide_timer.setInterval(default_mouse_hide_timeout); connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor); + mouse_center_timer.setInterval(default_mouse_center_timeout); + connect(&mouse_center_timer, &QTimer::timeout, this, &GMainWindow::CenterMouseCursor); + MigrateConfigFiles(); #if defined(HAVE_SDL2) && !defined(_WIN32) @@ -3301,10 +3305,26 @@ void GMainWindow::ShowMouseCursor() { } } +void GMainWindow::CenterMouseCursor() { + if (emu_thread == nullptr || !Settings::values.mouse_panning) { + mouse_center_timer.stop(); + return; + } + if (!this->isActiveWindow()) { + mouse_center_timer.stop(); + return; + } + const int center_x = render_window->width() / 2; + const int center_y = render_window->height() / 2; + + QCursor::setPos(mapToGlobal({center_x, center_y})); +} + void GMainWindow::OnMouseActivity() { if (!Settings::values.mouse_panning) { ShowMouseCursor(); } + mouse_center_timer.stop(); } void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string details) { @@ -3577,6 +3597,22 @@ void GMainWindow::dragMoveEvent(QDragMoveEvent* event) { AcceptDropEvent(event); } +void GMainWindow::leaveEvent(QEvent* event) { + if (Settings::values.mouse_panning) { + const QRect& rect = geometry(); + QPoint position = QCursor::pos(); + + qint32 x = qBound(rect.left(), position.x(), rect.right()); + qint32 y = qBound(rect.top(), position.y(), rect.bottom()); + // Only start the timer if the mouse has left the window bound. + // The leave event is also triggered when the window looses focus. + if (x != position.x() || y != position.y()) { + mouse_center_timer.start(); + } + event->accept(); + } +} + bool GMainWindow::ConfirmChangeGame() { if (emu_thread == nullptr) return true; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index ab95a7518..b399e9b01 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -328,6 +328,7 @@ private: void UpdateUISettings(); void HideMouseCursor(); void ShowMouseCursor(); + void CenterMouseCursor(); void OpenURL(const QUrl& url); void LoadTranslation(); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); @@ -372,6 +373,7 @@ private: bool auto_paused = false; bool auto_muted = false; QTimer mouse_hide_timer; + QTimer mouse_center_timer; // FS std::shared_ptr vfs; @@ -418,4 +420,5 @@ protected: void dropEvent(QDropEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override; + void leaveEvent(QEvent* event) override; };