Multiple screens working, but filter down to just glasses for now

Attempt to stop input capture
This commit is contained in:
wheaney 2025-07-02 15:45:31 -07:00
parent 021b0f4cc0
commit f691d156b6
3 changed files with 57 additions and 142 deletions

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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();
}