void AbstractPointerLocker::setWindow(QWindow *window)
{
if (m_window == window) {
return;
}
m_window = window;
Q_EMIT windowChanged();
}
PointerLockerQt::PointerLockerQt(QObject *parent)
: AbstractPointerLocker(parent)
{
}
PointerLockerQt::~PointerLockerQt() = default;
void PointerLockerQt::setLocked(bool lock)
{
if (m_isLocked == lock) {
return;
}
m_isLocked = lock;
if (lock) {
/* Cursor needs to be hidden such that Xwayland emulates warps. */
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
m_originalPosition = QCursor::pos();
m_window->installEventFilter(this);
Q_EMIT lockedChanged(true);
Q_EMIT lockEffectiveChanged(true);
} else {
m_window->removeEventFilter(this);
QGuiApplication::restoreOverrideCursor();
Q_EMIT lockedChanged(false);
Q_EMIT lockEffectiveChanged(false);
}
}
bool PointerLockerQt::isLocked() const
{
return m_isLocked;
}
bool PointerLockerQt::eventFilter(QObject *watched, QEvent *event)
{
if (watched != m_window || event->type() != QEvent::MouseMove || !isLocked()) {
return false;
}
const auto newPos = QCursor::pos();
const QPointF dist = newPos - m_originalPosition;
Q_EMIT pointerMoved({dist.x(), dist.y()});
QCursor::setPos(m_originalPosition);
return true;
}