-
-
Notifications
You must be signed in to change notification settings - Fork 84
feat(controller): DS5 touchpad touch events over USB driver #513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6b5035c
011613a
a7181da
0067134
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2407,6 +2407,13 @@ class ControllerHandler( | |
| context: UsbDeviceContext, | ||
| update: UsbControllerShortcutStateMachine.Update | ||
| ) { | ||
| val captureStarted = update.consumeAllInput && !context.touchCaptureActive | ||
| val captureEnded = !update.consumeAllInput && context.touchCaptureActive | ||
| context.touchCaptureActive = update.consumeAllInput | ||
| if (captureStarted || captureEnded) { | ||
| cancelForwardedUsbTouches(context) | ||
| context.device?.resetTouchState() | ||
| } | ||
| for (action in update.actions) { | ||
| when (action) { | ||
| UsbControllerShortcutStateMachine.Action.SCHEDULE_LONG_PRESS -> { | ||
|
|
@@ -2485,6 +2492,13 @@ class ControllerHandler( | |
| } | ||
| } | ||
|
|
||
| internal fun onUsbLocalCaptureEnded(context: UsbDeviceContext) { | ||
| if (!context.touchCaptureActive) return | ||
| context.touchCaptureActive = false | ||
| cancelForwardedUsbTouches(context) | ||
| context.device?.resetTouchState() | ||
| } | ||
|
|
||
| fun onExternalGameMenuOpened() { | ||
| synchronized(usbDeviceContextsLifecycleLock) { | ||
| if (stopped) return | ||
|
|
@@ -2724,6 +2738,58 @@ class ControllerHandler( | |
| } | ||
| } | ||
|
|
||
| override fun reportControllerTouch( | ||
| controllerId: Int, | ||
| eventType: Byte, | ||
| pointerId: Int, | ||
| x: Float, | ||
| y: Float | ||
| ) { | ||
| val context = usbDeviceContexts[controllerId] ?: return | ||
| if (prefConfig.multiController && !context.assignedControllerNumber) return | ||
| if (context.shortcutState.isLocalInputCaptureActive()) { | ||
| cancelForwardedUsbTouches(context) | ||
| return | ||
| } | ||
|
|
||
| // The Linux DS5 backend distinguishes contact/release via pressure. | ||
| val pressure = when (eventType) { | ||
| MoonBridge.LI_TOUCH_EVENT_DOWN, MoonBridge.LI_TOUCH_EVENT_MOVE -> 1f | ||
| else -> 0f | ||
| } | ||
| val result = conn.sendControllerTouchEvent( | ||
| context.controllerNumber.toByte(), eventType, pointerId, x, y, pressure | ||
| ) | ||
| if (result == MoonBridge.LI_ERR_UNSUPPORTED) return | ||
|
|
||
| when (eventType) { | ||
| MoonBridge.LI_TOUCH_EVENT_DOWN, MoonBridge.LI_TOUCH_EVENT_MOVE -> | ||
| context.forwardedTouchPointerIds[pointerId] = true | ||
| MoonBridge.LI_TOUCH_EVENT_UP, MoonBridge.LI_TOUCH_EVENT_CANCEL -> | ||
| context.forwardedTouchPointerIds.remove(pointerId) | ||
| MoonBridge.LI_TOUCH_EVENT_CANCEL_ALL -> context.forwardedTouchPointerIds.clear() | ||
| } | ||
| } | ||
|
|
||
| private fun cancelForwardedUsbTouches(context: UsbDeviceContext) { | ||
| if (context.forwardedTouchPointerIds.isNotEmpty()) { | ||
| context.forwardedTouchPointerIds.keys.toList().forEach { pointerId -> | ||
| conn.sendControllerTouchEvent( | ||
| context.controllerNumber.toByte(), MoonBridge.LI_TOUCH_EVENT_CANCEL, | ||
| pointerId, 0f, 0f, 0f | ||
| ) | ||
| } | ||
| } | ||
| context.forwardedTouchPointerIds.clear() | ||
|
Comment on lines
+2760
to
+2783
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- target file map ---'
ast-grep outline app/src/main/java/com/limelight/binding/input/ControllerHandler.kt --match 'sendControllerTouchEvent' --view expanded || true
printf '%s\n' '--- target lines ---'
sed -n '2700,2825p' app/src/main/java/com/limelight/binding/input/ControllerHandler.kt
printf '%s\n' '--- sendControllerTouchEvent call sites ---'
rg -n -C 5 'sendControllerTouchEvent|forwardedTouchPointerIds|cancelForwardedUsbTouches' app/src/main/java app/src/test test 2>/dev/null || true
printf '%s\n' '--- native result constants and wrappers ---'
rg -n -C 6 'LI_ERR_UNSUPPORTED|sendControllerTouchEvent' app/src/main/java app/src/test test 2>/dev/null || trueRepository: qiin2333/moonlight-vplus Length of output: 50380 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- focused ControllerHandler touch paths ---'
sed -n '1780,1970p' app/src/main/java/com/limelight/binding/input/ControllerHandler.kt
printf '%s\n' '--- focused USB touch producer path ---'
rg -n -C 12 'reportControllerTouch|forwardedTouchPointerIds|sendControllerTouchEvent' app/src/main/java/com/limelight/binding/input --glob '*.kt'
printf '%s\n' '--- DualSense stationary MOVE handling ---'
rg -n -C 12 'stationary|MOVE|touch|Touch' app/src/main/java/com/limelight/binding/input --glob '*DualSense*.kt' --glob '*.kt' | rg -n -C 4 'DualSense|stationary|forwarded|reportControllerTouch|LI_TOUCH_EVENT_MOVE' | head -240
printf '%s\n' '--- native implementations and declarations ---'
rg -n -C 16 'sendControllerTouchEvent|LI_ERR_UNSUPPORTED|controller.*touch|touch.*controller' . --glob '*.{c,cc,cpp,h,hpp,kt,java}' | head -300Repository: qiin2333/moonlight-vplus Length of output: 50380 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- complete DualSense touch state machine ---'
sed -n '140,205p' app/src/main/java/com/limelight/binding/input/driver/DualSenseController.kt
printf '%s\n' '--- all repository files related to native touch sending ---'
git ls-files | rg '(^|/)(.*MoonBridge.*|.*Limelight.*|.*connection.*|.*input.*)\.(c|cc|cpp|h|hpp|kt|java)$' | head -200
printf '%s\n' '--- exact result handling in native-adjacent sources ---'
rg -n -C 10 'sendControllerTouchEvent|LI_ERR_UNSUPPORTED|controllerTouch' app/src/main cpp lib native moonlight 2>/dev/null | head -300 || true
printf '%s\n' '--- git-tracked tests and fakes for NvConnection/MoonBridge ---'
git ls-files | rg '(^|/)(test|tests|androidTest|.*Test.*|.*Fake.*|.*Mock.*)' | head -200
rg -n -C 8 'sendControllerTouchEvent|reportControllerTouch|forwardedTouchPointerIds' app/src/test app/src/androidTest 2>/dev/null || trueRepository: qiin2333/moonlight-vplus Length of output: 47765 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- JNI controller touch implementation ---'
rg -n -C 20 'sendControllerTouchEvent|LiSendControllerTouchEvent' app/src/main/jni
printf '%s\n' '--- core API declarations and implementation references ---'
rg -n -C 12 'LiSendControllerTouchEvent|LI_ERR_UNSUPPORTED' app/src/main/jni --glob '*.{c,h,cc,cpp}' | head -300
printf '%s\n' '--- build/native source inventory ---'
git ls-files app/src/main/jni | sed -n '1,160p'Repository: qiin2333/moonlight-vplus Length of output: 17652 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- embedded core source linkage ---'
sed -n '1,180p' app/src/main/jni/moonlight-core/Build.txt
sed -n '1,220p' app/src/main/jni/moonlight-core/Android.mk
printf '%s\n' '--- submodule metadata and pinned core revision ---'
git submodule status 2>/dev/null || true
git ls-files -s app/src/main/jni/moonlight-core/moonlight-common-c
find app/src/main/jni/moonlight-core/moonlight-common-c -maxdepth 3 -type f 2>/dev/null | head -80
printf '%s\n' '--- repository references to core source URL/version ---'
rg -n -C 4 'moonlight-common-c|LiSendControllerTouchEvent|moonlight-common' . --glob '!app/src/main/jni/moonlight-core/openssl/**' --glob '!app/src/main/jni/moonlight-core/libopus/**' | head -240Repository: qiin2333/moonlight-vplus Length of output: 24434 🌐 Web query:
💡 Result: The Citations:
🏁 Script executed: #!/bin/bash
set -e
base='https://raw.githubusercontent.com/moonlight-stream/moonlight-common-c/72733e3a47fc7823e7e0b1b0cef2e3d101b0399b'
printf '%s\n' '--- pinned Limelight declarations ---'
curl -fsSL "$base/src/Limelight.h" | rg -n -C 8 'LI_ERR_UNSUPPORTED|LI_FF_CONTROLLER_TOUCH_EVENTS|LiSendControllerTouchEvent'
printf '%s\n' '--- pinned InputStream implementation ---'
curl -fsSL "$base/src/InputStream.c" | rg -n -C 24 'LiSendControllerTouchEvent|LI_FF_CONTROLLER_TOUCH_EVENTS|LBQ_BOUND_EXCEEDED|LBQ_SUCCESS'
printf '%s\n' '--- pinned queue result definitions ---'
curl -fsSL "$base/src/LinkedBlockingQueue.h" | rg -n -C 8 'LBQ_' || trueRepository: qiin2333/moonlight-vplus Length of output: 50380 Commit touch-pointer state only when
🤖 Prompt for AI Agents |
||
| context.device?.resetTouchState() | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| override fun isUsbControllerReady(controllerId: Int): Boolean { | ||
| val context = usbDeviceContexts[controllerId] ?: return false | ||
| if (prefConfig.multiController && !context.assignedControllerNumber) return false | ||
| return context.controllerArrival.isReported | ||
| } | ||
|
|
||
| // ========== Sensor Management ========== | ||
|
|
||
| fun handleSetMotionEventState(controllerNumber: Short, motionType: Byte, reportRateHz: Short) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Serialize capture transitions with touch forwarding.
Both paths set
touchCaptureActivetofalsebeforecancelForwardedUsbTouches(). After the shortcut state becomes inactive,reportControllerTouch()can send a new event while cancellation snapshots or clears the pointer set. The new contact can then remain active on the host without a tracked ID.Serialize capture transitions and
reportControllerTouch()with one per-context lock. Keep forwarding blocked until cancellation and tracking cleanup finish.Also applies to: 2495-2500
🤖 Prompt for AI Agents