[OpenDocString] kdeconnect-kde (cpp)
pointerlockerwayland.cpp
PointerLockerWayland::PointerLockerWayland(QObject *parent)
    : AbstractPointerLocker(parent)
{
    m_pointerConstraints = new PointerConstraints;
}
This constructor builds a pointer locking object and its constraints.
PointerLockerWayland::~PointerLockerWayland()
{
    delete m_pointerConstraints;
}
This removes the constraints object upon destruction.
bool PointerLockerWayland::isLockEffective() const
{
    return m_lockedPointer;
}
This implements checking if the pointer is locked.
wl_pointer *PointerLockerWayland::getPointer()
{
    QPlatformNativeInterface *native = qGuiApp->platformNativeInterface();
    if (!native) {
        return nullptr;
    }

    window()->create();

    return reinterpret_cast(native->nativeResourceForIntegration(QByteArrayLiteral("wl_pointer")));
}
Returns a pointer to the native object of the current thread.
void PointerLockerWayland::enforceLock()
{
    if (!m_isLocked) {
        return;
    }

    wl_surface *wlSurface = [](QWindow *window) -> wl_surface * {
        if (!window) {
            return nullptr;
        }

        QPlatformNativeInterface *native = qGuiApp->platformNativeInterface();
        if (!native) {
            return nullptr;
        }
        window->create();
        return reinterpret_cast(native->nativeResourceForWindow(QByteArrayLiteral("surface"), window));
    }(m_window);

    m_lockedPointer =
        new LockedPointer(m_pointerConstraints->lock_pointer(wlSurface, getPointer(), nullptr, PointerConstraints::lifetime::lifetime_persistent), this);

    if (!m_lockedPointer) {
        qDebug() << "ERROR when receiving locked pointer!";
        return;
    }

    connect(m_lockedPointer, &LockedPointer::locked, this, [this] {
        Q_EMIT lockEffectiveChanged(true);
    });
    connect(m_lockedPointer, &LockedPointer::unlocked, this, [this] {
        Q_EMIT lockEffectiveChanged(false);
    });
}
This takes the window object of the current thread and creates a locked pointer. It first checks that the window is locked, and if it is a native window, it creates a wl_surface object of the given type, and connects the lock events to the locked pointer.
void PointerLockerWayland::setLocked(bool lock)
{
    if (m_isLocked == lock) {
        return;
    }

    if (!isSupported()) {
        qWarning() << "Locking before having our interfaces announced";
        return;
    }

    m_isLocked = lock;
    if (lock) {
        enforceLock();
    } else {
        cleanupLock();
    }
    Q_EMIT lockedChanged(lock);
}
This sets the lock value on or off. It makes sure the device is locked before having our interfaces announced. If the device is not supported by the library, it logs a warning. If the device is disabled, it cleans the device before having our interfaces announced.
void PointerLockerWayland::cleanupLock()
{
    if (!m_lockedPointer) {
        return;
    }
    m_lockedPointer->destroy();
    m_lockedPointer->deleteLater();
    m_lockedPointer = nullptr;
    Q_EMIT lockEffectiveChanged(false);
}
This removes the locked pointer object and marks it for deletion. It also marks the effective change signal as well.
void PointerLockerWayland::setWindow(QWindow *window)
{
    if (m_window == window) {
        return;
    }
    cleanupLock();

    if (m_window) {
        disconnect(m_window, &QWindow::visibleChanged, this, &PointerLockerWayland::enforceLock);
    }
    AbstractPointerLocker::setWindow(window);
    connect(m_window, &QWindow::visibleChanged, this, &PointerLockerWayland::enforceLock);

    if (m_isLocked) {
        enforceLock();
    }
}
This sets the window object within the pointer locking mechanism. It disconnects the previous window, and connects the window to the visibleChanged signal. Then it enforces the lock.