phone: delay touchpad tap click by 100 ms; second finger cancels it

This commit is contained in:
2026-09-25 20:20:39 +03:00
parent fe95d249e9
commit 05daf3fc7b
@@ -37,6 +37,8 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import pw.binom.rayneovm.phone.protocol.VmPhoneController
import pw.binom.rayneovm.shared.VmDisplay
@@ -46,6 +48,9 @@ private const val KEYCODE_BACK = 4
private const val KEYCODE_MEDIA_PLAY = 126
private const val KEYCODE_MEDIA_PAUSE = 127
/** Сколько ждать перед кликом-тапом: если за это время коснулись снова — это был скролл. */
private const val CLICK_GRACE_MS = 100L
/**
* Пульт управления гостевым приложением на очках:
* - тачпад-мышь: движение одного пальца → курсор (отыгрывается на очках в обоих глазах),
@@ -62,10 +67,9 @@ fun RemoteScreen(
val scope = rememberCoroutineScope()
// Позиция курсора в координатах VirtualDisplay гостя.
var cursor by remember { mutableStateOf(Offset(VmDisplay.WIDTH / 2f, VmDisplay.HEIGHT / 2f)) }
fun click() {
scope.launch { controller.clickCursor() }
}
// Отложенный клик: два пальца кладут не одновременно, и первый палец успевает «щёлкнуть»
// до начала скролла. Клик ждёт [CLICK_GRACE_MS]; касание за это время его отменяет.
val pendingClick = remember { mutableStateOf<Job?>(null) }
Column(
modifier = modifier.fillMaxSize().background(Color.Black).padding(16.dp),
@@ -87,6 +91,9 @@ fun RemoteScreen(
var travel = 0f
awaitFirstDown(requireUnconsumed = false)
// Палец реально коснулся — значит предыдущий тап был началом скролла.
pendingClick.value?.cancel()
pendingClick.value = null
while (true) {
val event = awaitPointerEvent()
val pressed = event.changes.filter { it.pressed }
@@ -126,7 +133,12 @@ fun RemoteScreen(
event.changes.forEach { it.consume() }
}
// Отпустили, не сдвинув палец, — это тап (клик по курсору).
if (mode != PadMode.SCROLL && travel < viewConfiguration.touchSlop) click()
if (mode != PadMode.SCROLL && travel < viewConfiguration.touchSlop) {
pendingClick.value = scope.launch {
delay(CLICK_GRACE_MS)
controller.clickCursor()
}
}
}
},
contentAlignment = Alignment.Center,