diff --git a/app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModel.kt b/app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModel.kt index d421a4ea..405df677 100644 --- a/app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModel.kt +++ b/app/src/main/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModel.kt @@ -142,7 +142,7 @@ class PcMouseControlViewModel( isDragging = when (commandToSend) { is PcControlCommand.DragStart -> true is PcControlCommand.DragEnd -> false - else -> it.isDragging + else -> if (it.isDragging && commandToSend.endsActiveDragWithClick()) false else it.isDragging }, isBusy = false, busyCommand = null, @@ -1134,6 +1134,12 @@ class PcMouseControlViewModel( } } +private fun PcControlCommand.endsActiveDragWithClick(): Boolean { + return this is PcControlCommand.LeftClick || + this is PcControlCommand.DoubleClick || + this is PcControlCommand.RightClick +} + private class InMemoryControlSurfaceStore : PcControlSurfaceStore { private var surface = PcControlSurface.Mouse diff --git a/app/src/test/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModelTest.kt b/app/src/test/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModelTest.kt index 45fa0969..d621f2d0 100644 --- a/app/src/test/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModelTest.kt +++ b/app/src/test/java/com/enaboapps/switchify/screens/pc/PcMouseControlViewModelTest.kt @@ -1469,6 +1469,107 @@ class PcMouseControlViewModelTest { assertEquals(PcMouseControlViewModel.COMMAND_FAILED_MESSAGE, viewModel.uiState.value.message) } + @Test + fun leftClickClearsDraggingAfterSuccessfulSend() = runTest(dispatcher) { + val connector = FakeConnector() + val controller = connectedController(connector = connector) + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.LeftClick) + advanceUntilIdle() + + assertEquals( + listOf(PcControlCommand.DragStart(), PcControlCommand.LeftClick), + connector.realtimeCommands + ) + assertFalse(viewModel.uiState.value.isDragging) + } + + @Test + fun rightClickClearsDraggingAfterSuccessfulSend() = runTest(dispatcher) { + val controller = connectedController() + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.RightClick) + advanceUntilIdle() + + assertFalse(viewModel.uiState.value.isDragging) + } + + @Test + fun doubleClickClearsDraggingAfterSuccessfulSend() = runTest(dispatcher) { + val controller = connectedController() + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.DoubleClick) + advanceUntilIdle() + + assertFalse(viewModel.uiState.value.isDragging) + } + + @Test + fun failedClickDoesNotClearDraggingMirror() = runTest(dispatcher) { + val connector = FakeConnector( + realtimeResults = mutableListOf(PcCommandResult.Ack, PcCommandResult.Failed()) + ) + val controller = connectedController(connector = connector) + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.LeftClick) + advanceUntilIdle() + + assertTrue(viewModel.uiState.value.isDragging) + assertEquals(PcMouseControlViewModel.COMMAND_FAILED_MESSAGE, viewModel.uiState.value.message) + } + + @Test + fun moveDoesNotClearDragging() = runTest(dispatcher) { + val controller = connectedController() + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.Move(dx = 10, dy = 0)) + advanceUntilIdle() + + assertTrue(viewModel.uiState.value.isDragging) + } + + @Test + fun scrollDoesNotClearDragging() = runTest(dispatcher) { + val controller = connectedController() + val viewModel = viewModel(controller) + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.send(PcControlCommand.Scroll(dx = 0, dy = -1)) + advanceUntilIdle() + + assertTrue(viewModel.uiState.value.isDragging) + } + + @Test + fun modifierToggleDoesNotClearDragging() = runTest(dispatcher) { + val controller = connectedController(pointerProfile = modifierPointerProfile()) + val viewModel = viewModel(controller) + advanceUntilIdle() + + viewModel.send(PcControlCommand.DragStart()) + advanceUntilIdle() + viewModel.toggleModifier(PcKeyboardModifierKey.Ctrl) + advanceUntilIdle() + + assertTrue(viewModel.uiState.value.isDragging) + } + @Test fun supportedProfileEnablesModifierToggles() = runTest(dispatcher) { val controller = connectedController(pointerProfile = modifierPointerProfile())