From f691d156b6a7e91c44a8cdf6cc3b49bfc1ee7f2f Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Wed, 2 Jul 2025 15:45:31 -0700 Subject: [PATCH] Multiple screens working, but filter down to just glasses for now Attempt to stop input capture --- kwin/src/qml/Cube.qml | 62 ++++++++++++++-- kwin/src/qml/CubeCameraController.qml | 101 -------------------------- kwin/src/qml/main.qml | 36 +-------- 3 files changed, 57 insertions(+), 142 deletions(-) diff --git a/kwin/src/qml/Cube.qml b/kwin/src/qml/Cube.qml index 537ad99..0d266eb 100644 --- a/kwin/src/qml/Cube.qml +++ b/kwin/src/qml/Cube.qml @@ -8,30 +8,78 @@ import QtQuick import QtQuick3D import org.kde.kwin as KWinComponents + Node { id: cube + readonly property var supportedModels: [ + "VITURE", + "nreal air", + "Air", + "Air 2", + "Air 2 Pro", + "Air 2 Ultra", + "SmartGlasses", // TCL/RayNeo + "Rokid Max", + "Rokid Air" + ] + required property real viewportFOVHorizontal required property real viewportWidth required property real viewportHeight property real distance: viewportWidth / (2 * Math.tan(Math.PI * viewportFOVHorizontal / 360)) + property var screens: KWinComponents.Workspace.screens.filter(function(screen) { + return supportedModels.includes(screen.model); + }) + + // x value for placing the viewport in the middle of all screens + property real screensXMid: { + let xMin = Number.MAX_VALUE; + let xMax = Number.MIN_VALUE; + + for (let i = 0; i < screens.length; i++) { + const geometry = screens[i].geometry; + xMin = Math.min(xMin, geometry.x); + xMax = Math.max(xMax, geometry.x + geometry.width); + } + + return (xMin + xMax) / 2 - (viewportWidth / 2); + } + + // y value for placing the viewport in the middle of all screens + property real screensYMid: { + let yMin = Number.MAX_VALUE; + let yMax = Number.MIN_VALUE; + + for (let i = 0; i < screens.length; i++) { + const geometry = screens[i].geometry; + yMin = Math.min(yMin, geometry.y); + yMax = Math.max(yMax, geometry.y + geometry.height); + } + + return (yMin + yMax) / 2 - (viewportHeight / 2); + } Repeater3D { id: faceRepeater - model: KWinComponents.Workspace.screens.length + model: screens.length delegate: CubeFace { - screen: KWinComponents.Workspace.screens[index] - + screen: screens[index] + property real screenRotation: { const geometry = screen.geometry; - const rot = (viewportFOVHorizontal / viewportWidth) * geometry.x + const rot = (viewportFOVHorizontal / viewportWidth) * (geometry.x - screensXMid); console.log(`\t\t\tBreezy - screenRotation ${geometry.x} ${geometry.width} ${rot}`); return -rot; } - - scale: Qt.vector3d(viewportWidth / 100, viewportHeight / 100, 1) + + property vector3d screenScale: { + const geometry = screen.geometry; + return Qt.vector3d(geometry.width / 100, geometry.height / 100, 1); + } + + scale: screenScale eulerRotation.y: screenRotation - position: { console.log(`\t\t\tBreezy - position ${distance} ${screenRotation}`); const transform = Qt.matrix4x4(); diff --git a/kwin/src/qml/CubeCameraController.qml b/kwin/src/qml/CubeCameraController.qml index 20ca795..c0f7c54 100644 --- a/kwin/src/qml/CubeCameraController.qml +++ b/kwin/src/qml/CubeCameraController.qml @@ -10,8 +10,6 @@ import QtQuick3D Item { id: root - readonly property bool busy: status.useMouse - required property Camera camera property quaternion rotation: Quaternion.fromEulerAngles(0, 0, 0) @@ -21,67 +19,12 @@ Item { property real xSpeed: 0.1 property real ySpeed: 0.1 - property bool xInvert: false - property bool yInvert: false - implicitWidth: parent.width implicitHeight: parent.height onRotationChanged: root.updateCamera(); onRadiusChanged: root.updateCamera(); - DragHandler { - id: dragHandler - target: null - acceptedModifiers: Qt.NoModifier - onCentroidChanged: { - mouseMoved(Qt.vector2d(centroid.position.x, centroid.position.y), false); - } - - onActiveChanged: { - if (active) { - mousePressed(Qt.vector2d(centroid.position.x, centroid.position.y)); - } else { - mouseReleased(Qt.vector2d(centroid.position.x, centroid.position.y)); - } - } - } - - WheelHandler { - id: wheelHandler - orientation: Qt.Vertical - target: null - onWheel: event => { - let delta = -event.angleDelta.y * 0.01; - root.radius += root.radius * 0.1 * delta - } - } - - TapHandler { - onTapped: root.forceActiveFocus() - } - - function mousePressed(newPos) { - root.forceActiveFocus() - status.currentPos = newPos - status.lastPos = newPos - status.useMouse = true; - } - - function mouseReleased(newPos) { - status.useMouse = false; - } - - function mouseMoved(newPos: vector2d) { - status.currentPos = newPos; - } - - function processInputs() { - if (root.busy) { - status.processInput(); - } - } - function updateCamera() { // convert NWU to EUS by passing root.rotation values: w, -y, z, -x let effectiveRotation = Qt.quaternion(root.rotation.scalar, -root.rotation.y, root.rotation.z, -root.rotation.x); @@ -107,50 +50,6 @@ Item { onTriggered: { if (useXrRotation && xrRotation.length() > 0) { root.rotation = xrRotation; - } else if (root.busy) { - processInputs(); - } - } - } - - QtObject { - id: status - - property bool useMouse: false - - property real minElevation: -30 - property real maxElevation: 30 - - property vector2d lastPos: Qt.vector2d(0, 0) - property vector2d currentPos: Qt.vector2d(0, 0) - - function processInput() { - if (useMouse) { - const eulerRotation = root.rotation.toEulerAngles(); - - const pixelDelta = Qt.vector2d(lastPos.x - currentPos.x, - lastPos.y - currentPos.y); - lastPos = currentPos; - - let azimuthDelta = pixelDelta.x * xSpeed - if (xInvert) { - azimuthDelta = -azimuthDelta; - } - let azimuth = (eulerRotation.y + azimuthDelta) % 360; - - let elevationDelta = pixelDelta.y * ySpeed - if (yInvert) { - elevationDelta = -elevationDelta; - } - - let elevation = eulerRotation.x + elevationDelta; - if (elevation < minElevation) { - elevation = minElevation; - } else if (elevation > maxElevation) { - elevation = maxElevation; - } - - root.rotation = Quaternion.fromEulerAngles(elevation, azimuth, 0); } } } diff --git a/kwin/src/qml/main.qml b/kwin/src/qml/main.qml index 64cf7c7..0352cc3 100644 --- a/kwin/src/qml/main.qml +++ b/kwin/src/qml/main.qml @@ -11,6 +11,7 @@ import org.kde.kwin.effect.cube Item { id: root + antialiasing: true focus: true required property QtObject effect @@ -19,14 +20,10 @@ Item { property bool animationEnabled: false function start() { - cameraController.rotateTo(KWinComponents.Workspace.currentDesktop); root.animationEnabled = true; - cameraController.state = "distant"; } function stop() { - cameraController.rotateTo(KWinComponents.Workspace.currentDesktop); - cameraController.state = "close"; } function switchToSelected() { @@ -84,27 +81,8 @@ Item { CubeCameraController { id: cameraController anchors.fill: parent - state: "close" camera: camera - xInvert: effect.mouseInvertedX - yInvert: effect.mouseInvertedY - - states: [ - State { - name: "close" - PropertyChanges { - target: cameraController - radius: 0.0 + 0.5 * cube.viewportHeight / Math.tan(0.5 * camera.fieldOfView * Math.PI / 180) - } - }, - State { - name: "distant" - PropertyChanges { - target: cameraController - radius: 0.0 * effect.distanceFactor + 0.5 * cube.viewportHeight / Math.tan(0.5 * camera.fieldOfView * Math.PI / 180) - } - } - ] + radius: 0.5 * cube.viewportHeight / Math.tan(camera.fieldOfView * Math.PI / 360) Behavior on rotation { enabled: !cameraController.busy && root.animationEnabled @@ -130,15 +108,5 @@ Item { } } - MouseArea { - anchors.fill: view - onClicked: root.switchToSelected(); - } - - Keys.onEscapePressed: effect.deactivate(); - Keys.onEnterPressed: root.switchToSelected(); - Keys.onReturnPressed: root.switchToSelected(); - Keys.onSpacePressed: root.switchToSelected(); - Component.onCompleted: start(); }