Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerButtons
import androidx.compose.ui.input.pointer.PointerEvent
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerEventType
Expand Down Expand Up @@ -107,6 +108,44 @@ class BaseComposeSceneTest {
}
}

@Test
fun orphanPointerMoveEvents() {
val scenes: List<ComposeScene> = listOf(
PlatformLayersComposeScene(size = IntSize(100, 100)),
CanvasLayersComposeScene(size = IntSize(100, 100))
)

scenes.forEach { scene ->
var clicksCount = 0
scene.setContent {
Box(modifier = Modifier.fillMaxSize().clickable {
clicksCount++
})
}

assertEquals(0, clicksCount)

// this sequence of events triggers click since homogenous "move" events does not affect release
scene.sendPointerEvent(PointerEventType.Press, Offset(10f, 10f))
scene.sendPointerEvent(PointerEventType.Move, Offset(10f, 10f), buttons = PointerButtons(packedValue = 1))
scene.sendPointerEvent(PointerEventType.Move, Offset(10f, 10f), buttons = PointerButtons(packedValue = 1))
scene.sendPointerEvent(PointerEventType.Release, Offset(10f, 10f))

assertEquals(1, clicksCount)

// this sequence of events triggers click since heterogenous "move" events does not affect release
// this never suppose to happen but actually happens
// see https://youtrack.jetbrains.com/issue/CMP-8430/Sequence-of-Move-PointerInputEvents-cancel-out-press-PointerInputEvent-under-certain-conditions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd create a fix without postponing instead of adding the test for current behaviour.

It should be simple - we already have such logic for pointers inside SyntheticEventSender, so you just need to add buttons field check there

scene.sendPointerEvent(PointerEventType.Press, Offset(10f, 10f))
scene.sendPointerEvent(PointerEventType.Move, Offset(10f, 10f), buttons = PointerButtons(packedValue = 1))
scene.sendPointerEvent(PointerEventType.Move, Offset(10f, 10f), buttons = PointerButtons(packedValue = 0))
scene.sendPointerEvent(PointerEventType.Release, Offset(10f, 10f))

assertEquals(1, clicksCount)
}

}

@Test
fun cancelAllPointersShouldCancelClicks() = runTest(StandardTestDispatcher()) {
val scenes: List<ComposeScene> = listOf(
Expand Down