File indexing completed on 2024-04-14 04:51:42

0001 /*
0002     SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
0003     SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "pointerlocker.h"
0009 
0010 #include <QCursor>
0011 #include <QGuiApplication>
0012 #include <QQmlContext>
0013 #include <QQmlEngine>
0014 
0015 #include <QDebug>
0016 
0017 void AbstractPointerLocker::setWindow(QWindow *window)
0018 {
0019     if (m_window == window) {
0020         return;
0021     }
0022     m_window = window;
0023     Q_EMIT windowChanged();
0024 }
0025 
0026 PointerLockerQt::PointerLockerQt(QObject *parent)
0027     : AbstractPointerLocker(parent)
0028 {
0029 }
0030 
0031 PointerLockerQt::~PointerLockerQt() = default;
0032 
0033 void PointerLockerQt::setLocked(bool lock)
0034 {
0035     if (m_isLocked == lock) {
0036         return;
0037     }
0038     m_isLocked = lock;
0039 
0040     if (lock) {
0041         /* Cursor needs to be hidden such that Xwayland emulates warps. */
0042         QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
0043         m_originalPosition = QCursor::pos();
0044         m_window->installEventFilter(this);
0045         Q_EMIT lockedChanged(true);
0046         Q_EMIT lockEffectiveChanged(true);
0047     } else {
0048         m_window->removeEventFilter(this);
0049         QGuiApplication::restoreOverrideCursor();
0050         Q_EMIT lockedChanged(false);
0051         Q_EMIT lockEffectiveChanged(false);
0052     }
0053 }
0054 
0055 bool PointerLockerQt::isLocked() const
0056 {
0057     return m_isLocked;
0058 }
0059 
0060 bool PointerLockerQt::eventFilter(QObject *watched, QEvent *event)
0061 {
0062     if (watched != m_window || event->type() != QEvent::MouseMove || !isLocked()) {
0063         return false;
0064     }
0065 
0066     const auto newPos = QCursor::pos();
0067     const QPointF dist = newPos - m_originalPosition;
0068     Q_EMIT pointerMoved({dist.x(), dist.y()});
0069     QCursor::setPos(m_originalPosition);
0070 
0071     return true;
0072 }
0073 
0074 #include "moc_pointerlocker.cpp"