summaryrefslogtreecommitdiffstats
path: root/src/yuzu/bootmanager.cpp
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2023-11-27 17:56:24 +0100
committerGitHub <noreply@github.com>2023-11-27 17:56:24 +0100
commit5a96c525e31797cb9dd69f693fb1746e865964f1 (patch)
tree57543645f9c3dd1ea72e1f9bd7ea81792de3de28 /src/yuzu/bootmanager.cpp
parentMerge pull request #11535 from GPUCode/upload_cmdbuf (diff)
parentyuzu: Constrain mouse in render window when emulated (diff)
downloadyuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar.gz
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar.bz2
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar.lz
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar.xz
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.tar.zst
yuzu-5a96c525e31797cb9dd69f693fb1746e865964f1.zip
Diffstat (limited to 'src/yuzu/bootmanager.cpp')
-rw-r--r--src/yuzu/bootmanager.cpp56
1 files changed, 55 insertions, 1 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 2afa72140..ed5750155 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -30,7 +30,6 @@
#include <QSize>
#include <QStringLiteral>
#include <QSurfaceFormat>
-#include <QTimer>
#include <QWindow>
#include <QtCore/qobjectdefs.h>
@@ -66,6 +65,8 @@ class QObject;
class QPaintEngine;
class QSurface;
+constexpr int default_mouse_constrain_timeout = 10;
+
EmuThread::EmuThread(Core::System& system) : m_system{system} {}
EmuThread::~EmuThread() = default;
@@ -304,6 +305,9 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
Qt::QueuedConnection);
connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
+
+ mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
+ connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
}
void GRenderWindow::ExecuteProgram(std::size_t program_index) {
@@ -393,6 +397,22 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
QWidget::closeEvent(event);
}
+void GRenderWindow::leaveEvent(QEvent* event) {
+ if (Settings::values.mouse_panning) {
+ const QRect& rect = QWidget::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_constrain_timer.start();
+ }
+ event->accept();
+ }
+}
+
int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) {
static constexpr std::array<std::pair<Qt::Key, Settings::NativeKeyboard::Keys>, 106> key_map = {
std::pair<Qt::Key, Settings::NativeKeyboard::Keys>{Qt::Key_A, Settings::NativeKeyboard::A},
@@ -658,10 +678,19 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
+ // Center mouse for mouse panning
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
}
+ // Constrain mouse for mouse emulation with mouse panning
+ if (Settings::values.mouse_panning && Settings::values.mouse_enabled) {
+ const auto [clamped_mouse_x, clamped_mouse_y] = ClipToTouchScreen(x, y);
+ QCursor::setPos(mapToGlobal(
+ QPoint{static_cast<int>(clamped_mouse_x), static_cast<int>(clamped_mouse_y)}));
+ }
+
+ mouse_constrain_timer.stop();
emit MouseActivity();
}
@@ -675,6 +704,31 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
input_subsystem->GetMouse()->ReleaseButton(button);
}
+void GRenderWindow::ConstrainMouse() {
+ if (emu_thread == nullptr || !Settings::values.mouse_panning) {
+ mouse_constrain_timer.stop();
+ return;
+ }
+ if (!this->isActiveWindow()) {
+ mouse_constrain_timer.stop();
+ return;
+ }
+
+ if (Settings::values.mouse_enabled) {
+ const auto pos = mapFromGlobal(QCursor::pos());
+ const int new_pos_x = std::clamp(pos.x(), 0, width());
+ const int new_pos_y = std::clamp(pos.y(), 0, height());
+
+ QCursor::setPos(mapToGlobal(QPoint{new_pos_x, new_pos_y}));
+ return;
+ }
+
+ const int center_x = width() / 2;
+ const int center_y = height() / 2;
+
+ QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
+}
+
void GRenderWindow::wheelEvent(QWheelEvent* event) {
const int x = event->angleDelta().x();
const int y = event->angleDelta().y();