touch: shift taps past the car's cropped margin, so buttons land where they're pressed

This commit is contained in:
Seb3thehacker committed 2026-10-12 23:50:24 -07:00
1 parent ceed61def9
commit 6d4389c7ab
1 file changed
+11 -4
@@ -660,8 +660,8 @@ class GearslipRunner(
* right-hand third of the screen away entirely - taps on a right-edge button landed on
* the middle one. The head unit maps its own panel onto our video before reporting.
*
* So: inject as-is, clamped to the video bounds. The advertised touchscreen size is kept
* only for diagnostics.
* So: inject them unscaled, shifted past the cropped margin (see below) and clamped to the
* video. The advertised touchscreen size is kept only for diagnostics.
*/
private fun onInputMessage(messageId: Int, body: ByteArray) {
when (messageId) {
@@ -692,13 +692,20 @@ class GearslipRunner(
val action = Wire.varint(touchFields, 3)?.toInt() ?: 0
val pointers = Wire.allBytes(touchFields, 1)
if (pointers.isEmpty()) return
val size = videoConfigs.getOrNull(selectedConfigIndex ?: 0)?.pixelSize()
val config = videoConfigs.getOrNull(selectedConfigIndex ?: 0)
val size = config?.pixelSize()
// The car crops its margin off the frame and measures taps from the corner of what
// it shows, so they come in short by half the margin: the 2024 VW (margin 240) sent
// y=6, which is inside the cropped band, and the Uconnect's never passed 351 on a
// 480-high frame with a 130 margin. Without this every tap landed 120 px too high
// and the VW couldn't press past its first screen.
val shift = config?.marginInsets() ?: Insets.NONE
val points = pointers.mapIndexedNotNull { index, pointer ->
val fields = Wire.fields(pointer)
val rawX = Wire.varint(fields, 1)?.toInt() ?: return@mapIndexedNotNull null
val rawY = Wire.varint(fields, 2)?.toInt() ?: return@mapIndexedNotNull null
val id = Wire.varint(fields, 3)?.toInt() ?: index
TouchPoint(id, clamp(rawX, size?.first), clamp(rawY, size?.second))
TouchPoint(id, clamp(rawX + shift.left, size?.first), clamp(rawY + shift.top, size?.second))
}
if (points.isEmpty()) return
val actionIndex = (Wire.varint(touchFields, 2)?.toInt() ?: 0).coerceIn(0, points.size - 1)