From 75e31f3f16dee54ded749a8536a06baed20ef212 Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Thu, 29 May 2025 14:04:38 -0700 Subject: [PATCH] WIP - initial XR effect stuff --- kwin/src/cubeeffect.cpp | 28 ++++++++++++++++++++++++++- kwin/src/cubeeffect.h | 9 ++++++++- kwin/src/qml/CubeCameraController.qml | 14 +++++++++++--- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/kwin/src/cubeeffect.cpp b/kwin/src/cubeeffect.cpp index 5c436b7..dbce20b 100644 --- a/kwin/src/cubeeffect.cpp +++ b/kwin/src/cubeeffect.cpp @@ -8,6 +8,7 @@ #include "cubeconfig.h" #include +#include #include #include @@ -46,6 +47,11 @@ CubeEffect::CubeEffect() reconfigure(ReconfigureAll); + + m_xrRotationTimer = new QTimer(this); + m_xrRotationTimer->setInterval(16); // ~60Hz + connect(m_xrRotationTimer, &QTimer::timeout, this, &CubeEffect::updateXrRotation); + m_xrRotationTimer->start(); } void CubeEffect::reconfigure(ReconfigureFlags) @@ -272,4 +278,24 @@ void CubeEffect::setBackgroundColor(const QColor &color) } } -} // namespace KWin \ No newline at end of file +QQuaternion CubeEffect::xrRotation() const { + return m_xrRotation; +} + +void CubeEffect::updateXrRotation() { + // Example: Read quaternion from /dev/shm/breezy_xr_quat (float32[4], binary) + QFile shmFile("/dev/shm/breezy_xr_quat"); + if (shmFile.open(QIODevice::ReadOnly)) { + float data[4]; + if (shmFile.read(reinterpret_cast(data), sizeof(data)) == sizeof(data)) { + QQuaternion quat(data[3], data[0], data[1], data[2]); // w, x, y, z + if (quat != m_xrRotation) { + m_xrRotation = quat; + Q_EMIT xrRotationChanged(); + } + } + shmFile.close(); + } +} + +} // namespace KWin diff --git a/kwin/src/cubeeffect.h b/kwin/src/cubeeffect.h index 9c09567..13b5802 100644 --- a/kwin/src/cubeeffect.h +++ b/kwin/src/cubeeffect.h @@ -25,6 +25,7 @@ class CubeEffect : public QuickSceneEffect Q_PROPERTY(QUrl skybox READ skybox NOTIFY skyboxChanged) Q_PROPERTY(BackgroundMode backgroundMode READ backgroundMode NOTIFY backgroundModeChanged) Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundColorChanged) + Q_PROPERTY(QQuaternion xrRotation READ xrRotation NOTIFY xrRotationChanged) public: enum class BackgroundMode { @@ -64,10 +65,13 @@ public: QColor backgroundColor() const; void setBackgroundColor(const QColor &color); + QQuaternion xrRotation() const; + public Q_SLOTS: void activate(); void deactivate(); void toggle(); + void updateXrRotation(); Q_SIGNALS: void cubeFaceDisplacementChanged(); @@ -78,6 +82,7 @@ Q_SIGNALS: void skyboxChanged(); void backgroundModeChanged(); void backgroundColorChanged(); + void xrRotationChanged(); protected: QVariantMap initialProperties(EffectScreen *screen) override; @@ -98,6 +103,8 @@ private: int m_animationDuration = 200; bool m_mouseInvertedX = true; bool m_mouseInvertedY = true; + QQuaternion m_xrRotation; + QTimer *m_xrRotationTimer = nullptr; }; -} // namespace KWin \ No newline at end of file +} // namespace KWin diff --git a/kwin/src/qml/CubeCameraController.qml b/kwin/src/qml/CubeCameraController.qml index 473ca01..5bef1d7 100644 --- a/kwin/src/qml/CubeCameraController.qml +++ b/kwin/src/qml/CubeCameraController.qml @@ -93,12 +93,20 @@ Item { camera.rotation = root.rotation; } + // Add property to receive XR rotation from effect + property quaternion xrRotation: effect.xrRotation + property bool useXrRotation: true // Set to true to use XR rotation when available + Timer { interval: 16 repeat: true - running: root.busy + running: true onTriggered: { - processInputs(); + if (useXrRotation && xrRotation.length() > 0) { + root.rotation = xrRotation; + } else if (root.busy) { + processInputs(); + } } } @@ -143,4 +151,4 @@ Item { } } } -} \ No newline at end of file +}