Replacing NestedScroll Sources.

NestedScroll sources Drag and Fling are being replaced by UserInput and SideEffect to accommodate for the extended definition of these sources that now include animations (Side Effect) and Mouse Wheel and Keyboard (UserInput).

Test: Previous tests should pass.
Relnote: NestedScroll sources Drag and Fling are being replaced by UserInput and SideEffect to accommodate for the extended definition of these sources that now include animations (Side Effect) and Mouse Wheel and Keyboard (UserInput).
Change-Id: I40579c9b053d6bcf477191b212c7a72876a588b7
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsControllerTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsControllerTest.kt
index f9791e05..3540fb5 100644
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsControllerTest.kt
+++ b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsControllerTest.kt
@@ -183,7 +183,7 @@
             val consumed = connection.onPostScroll(
                 consumed = Offset.Zero,
                 available = Offset(3f, directionMultiplier),
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             )
             assertThat(consumed).isEqualTo(Offset(0f, directionMultiplier))
         }
@@ -196,7 +196,7 @@
                 connection.onPostScroll(
                     consumed = Offset.Zero,
                     available = Offset(3f, directionMultiplier * 5f),
-                    source = NestedScrollSource.Drag
+                    source = NestedScrollSource.UserInput
                 )
                 coordinates.size
             }
@@ -236,7 +236,7 @@
             // The first scroll triggers the animation controller to be requested
             val consumed = connection.onPreScroll(
                 available = Offset(3f, -directionMultiplier),
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             )
             assertThat(consumed).isEqualTo(Offset(0f, -directionMultiplier))
         }
@@ -248,7 +248,7 @@
             val size = rule.runOnUiThread {
                 connection.onPreScroll(
                     available = Offset(3f, directionMultiplier * -5f),
-                    source = NestedScrollSource.Drag
+                    source = NestedScrollSource.UserInput
                 )
                 coordinates.size
             }
@@ -447,7 +447,7 @@
                 connection.onPostScroll(
                     consumed = Offset.Zero,
                     available = Offset(0f, directionMultiplier),
-                    source = NestedScrollSource.Drag
+                    source = NestedScrollSource.UserInput
                 )
             }
         } while (!isVisible)
@@ -458,7 +458,7 @@
             connection.onPostScroll(
                 consumed = Offset.Zero,
                 available = Offset(0f, directionMultiplier * sizeDifference),
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             )
         }
 
@@ -509,7 +509,7 @@
             rule.runOnIdle {
                 connection.onPreScroll(
                     available = Offset(0f, directionMultiplier * -1f),
-                    source = NestedScrollSource.Drag
+                    source = NestedScrollSource.UserInput
                 )
             }
         } while (insetsSize != shownSize)
@@ -519,7 +519,7 @@
             val sizeDifference = shownSize / 2f + 1f - insetsSize
             connection.onPreScroll(
                 available = Offset(0f, directionMultiplier * sizeDifference),
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             )
         }
 
diff --git a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsDeviceTest.kt b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsDeviceTest.kt
index 6800c39..f5c86b7 100644
--- a/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsDeviceTest.kt
+++ b/compose/foundation/foundation-layout/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/layout/WindowInsetsDeviceTest.kt
@@ -159,7 +159,7 @@
                 dispatcher.dispatchPostScroll(
                     Offset.Zero,
                     Offset(0f, -10f),
-                    NestedScrollSource.Drag
+                    NestedScrollSource.UserInput
                 )
                 Snapshot.sendApplyNotifications()
                 iteration++
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/OverscrollSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/OverscrollSample.kt
index 1a1e3f6..69c8e0c 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/OverscrollSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/OverscrollSample.kt
@@ -94,7 +94,7 @@
             val consumedByScroll = performScroll(leftForScroll)
             val overscrollDelta = leftForScroll - consumedByScroll
             // if it is a drag, not a fling, add the delta left to our over scroll value
-            if (abs(overscrollDelta.y) > 0.5 && source == NestedScrollSource.Drag) {
+            if (abs(overscrollDelta.y) > 0.5 && source == NestedScrollSource.UserInput) {
                 scope.launch {
                     // multiply by 0.1 for the sake of parallax effect
                     overscrollOffset.snapTo(overscrollOffset.value + overscrollDelta.y * 0.1f)
@@ -197,7 +197,10 @@
         // Horizontal, so convert the delta to a horizontal offset
         val deltaAsOffset = Offset(delta, 0f)
         // Wrap the original logic inside applyToScroll
-        overscrollEffect.applyToScroll(deltaAsOffset, NestedScrollSource.Drag) { remainingOffset ->
+        overscrollEffect.applyToScroll(
+            deltaAsOffset,
+            NestedScrollSource.UserInput
+        ) { remainingOffset ->
             val remainingDelta = remainingOffset.x
             val newPosition = (dragPosition + remainingDelta).coerceIn(minPosition, maxPosition)
             // Calculate how much delta we have consumed
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/OverscrollTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/OverscrollTest.kt
index 5a42438..7276c9f 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/OverscrollTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/OverscrollTest.kt
@@ -136,7 +136,7 @@
 
         rule.runOnIdle {
             assertThat(controller.lastVelocity.x).isGreaterThan(0f)
-            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.Fling)
+            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.SideEffect)
         }
     }
 
@@ -166,7 +166,7 @@
             assertThat(abs(acummulatedScroll - 1000f * 9 / 10)).isWithin(0.1f)
 
             assertThat(controller.lastPreScrollDelta).isEqualTo(Offset(1000f - slop, 0f))
-            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.Drag)
+            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.UserInput)
         }
 
         rule.onNodeWithTag(boxTag).performTouchInput {
@@ -208,7 +208,7 @@
             assertThat(abs(acummulatedScroll - 1000f * 9 / 10)).isWithin(0.1f)
 
             assertThat(controller.lastPreScrollDelta).isEqualTo(Offset(1000f - slop, 0f))
-            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.Drag)
+            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.UserInput)
             controller.lastPreScrollDelta = Offset.Zero
         }
 
@@ -381,7 +381,7 @@
             val offset = Offset(x = 0f, y = 50f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -455,7 +455,7 @@
             val offset = Offset(x = 0f, y = 50f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -586,7 +586,7 @@
             val offset = Offset(x = 50f, y = 0f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -717,7 +717,7 @@
             val offset = Offset(x = 50f, y = 50f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -842,7 +842,7 @@
             val offset = Offset(x = 0f, y = 50f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -904,7 +904,7 @@
             val offset = Offset(x = 50f, y = 0f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -966,7 +966,7 @@
             val offset = Offset(x = 50f, y = 50f)
             controller.applyToScroll(
                 offset,
-                source = NestedScrollSource.Drag
+                source = NestedScrollSource.UserInput
             ) { Offset.Zero }
             // we have to disable further invalidation requests as otherwise while the overscroll
             // effect is considered active (as it is in a pulled state) this will infinitely
@@ -1004,7 +1004,7 @@
                 val offset = Offset(-10f, -10f)
                 var offsetConsumed: Offset? = null
 
-                effect.applyToScroll(offset, NestedScrollSource.Drag) {
+                effect.applyToScroll(offset, NestedScrollSource.UserInput) {
                     offsetConsumed = offset - it
                     Offset.Zero
                 }
@@ -1037,7 +1037,7 @@
                 val offset = Offset(0f, 10f)
                 var offsetConsumed: Offset? = null
 
-                effect.applyToScroll(offset, NestedScrollSource.Drag) {
+                effect.applyToScroll(offset, NestedScrollSource.UserInput) {
                     offsetConsumed = offset - it
                     Offset.Zero
                 }
@@ -1340,7 +1340,7 @@
             assertThat(controller.lastInitialDragDelta.y).isZero()
             assertThat(controller.lastOverscrollDelta.x)
                 .isEqualTo(controller.lastInitialDragDelta.x / 2)
-            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.Drag)
+            assertThat(controller.lastNestedScrollSource).isEqualTo(NestedScrollSource.UserInput)
         }
 
         rule.onNodeWithTag(boxTag).performTouchInput {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
index 523307e..1603c65 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ScrollableTest.kt
@@ -1305,7 +1305,7 @@
             ): Offset {
                 // we should get in post scroll as much as left in controller callback
                 assertThat(available.x).isEqualTo(expectedLeft)
-                return if (source == NestedScrollSource.Fling) Offset.Zero else available
+                return if (source == NestedScrollSource.SideEffect) Offset.Zero else available
             }
 
             override suspend fun onPostFling(
@@ -1374,7 +1374,7 @@
             ): Offset {
                 // we should get in post scroll as much as left in controller callback
                 assertThat(available.x).isEqualTo(-expectedLeft)
-                return if (source == NestedScrollSource.Fling) Offset.Zero else available
+                return if (source == NestedScrollSource.SideEffect) Offset.Zero else available
             }
 
             override suspend fun onPostFling(
@@ -1459,14 +1459,14 @@
 
         val lastValueBeforeFling = rule.runOnIdle {
             val preScrollConsumed = dispatcher
-                .dispatchPreScroll(Offset(20f, 20f), NestedScrollSource.Drag)
+                .dispatchPreScroll(Offset(20f, 20f), NestedScrollSource.UserInput)
             // scrollable is not interested in pre scroll
             assertThat(preScrollConsumed).isEqualTo(Offset.Zero)
 
             val consumed = dispatcher.dispatchPostScroll(
                 Offset(20f, 20f),
                 Offset(50f, 50f),
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             assertThat(consumed.x - expectedConsumed).isWithin(0.001f)
             value
@@ -1640,7 +1640,7 @@
                 available: Offset,
                 source: NestedScrollSource
             ): Offset {
-                if (source == NestedScrollSource.Fling && available != Offset.Zero) {
+                if (source == NestedScrollSource.SideEffect && available != Offset.Zero) {
                     throw CancellationException()
                 }
                 return Offset.Zero
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.android.kt
index 8347e5c..c1cc0fc 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.android.kt
@@ -495,7 +495,7 @@
         val leftForOverscroll = leftForDelta - consumedByDelta
 
         var needsInvalidation = false
-        if (source == NestedScrollSource.Drag) {
+        if (source == NestedScrollSource.UserInput) {
             // Ignore small deltas (< 0.5) as this usually comes from floating point rounding issues
             // and can cause scrolling to lock up (b/265363356)
             val appliedHorizontalOverscroll = if (leftForOverscroll.x > 0.5f) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
index 9e75d4a..d31eb71 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
@@ -205,7 +205,7 @@
             } else {
                 overscrollEffect!!.applyToScroll(
                     delta = dragDelta.delta.reverseIfNeeded(),
-                    source = NestedScrollSource.Drag
+                    source = NestedScrollSource.UserInput
                 ) { deltaForDrag ->
                     val dragOffset = state.newOffsetForDelta(deltaForDrag.toFloat())
                     val consumedDelta = (dragOffset - state.requireOffset()).toOffset()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
index cf92947..72c2b20 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
@@ -52,9 +52,8 @@
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.Drag
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.Fling
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.Wheel
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.SideEffect
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.UserInput
 import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode
 import androidx.compose.ui.input.pointer.PointerEvent
 import androidx.compose.ui.input.pointer.PointerEventPass
@@ -447,7 +446,7 @@
             // lazily launch one coroutine (with the first event) and use a Channel
             // to communicate the scroll amount to the UI thread.
             coroutineScope.launch {
-                scrollingLogic.dispatchUserInputDelta(scrollAmount, Wheel)
+                scrollingLogic.dispatchUserInputDelta(scrollAmount, UserInput)
             }
             true
         } else {
@@ -482,7 +481,7 @@
                 // lazily launch one coroutine (with the first event) and use a Channel
                 // to communicate the scroll amount to the UI thread.
                 coroutineScope.launch {
-                    scrollingLogic.dispatchUserInputDelta(scrollAmount, Wheel)
+                    scrollingLogic.dispatchUserInputDelta(scrollAmount, UserInput)
                 }
                 event.changes.fastForEach { it.consume() }
             }
@@ -678,7 +677,7 @@
     )
 
     private var latestScrollScope: ScrollScope = NoOpScrollScope
-    private var latestScrollSource: NestedScrollSource = Drag
+    private var latestScrollSource: NestedScrollSource = UserInput
 
     private val performScroll: (delta: Offset) -> Offset = { delta ->
         val consumedByPreScroll =
@@ -709,14 +708,13 @@
      */
     private fun ScrollScope.dispatchScroll(
         initialAvailableDelta: Offset,
-        source: NestedScrollSource
+        source: NestedScrollSource,
+        overscrollEnabledForSource: Boolean
     ): Offset {
         latestScrollSource = source
         latestScrollScope = this
         val overscroll = overscrollEffect
-        return if (source == Wheel) {
-            performScroll(initialAvailableDelta)
-        } else if (overscroll != null && shouldDispatchOverscroll) {
+        return if (overscroll != null && shouldDispatchOverscroll && overscrollEnabledForSource) {
             overscroll.applyToScroll(initialAvailableDelta, source, performScroll)
         } else {
             performScroll(initialAvailableDelta)
@@ -766,7 +764,11 @@
         var result: Velocity = available
         scrollableState.scroll {
             val outerScopeScroll: (Offset) -> Offset = { delta ->
-                dispatchScroll(delta.reverseIfNeeded(), Fling).reverseIfNeeded()
+                dispatchScroll(
+                    delta.reverseIfNeeded(),
+                    SideEffect,
+                    overscrollEnabledForSource = true
+                ).reverseIfNeeded()
             }
             val scope = object : ScrollScope {
                 override fun scrollBy(pixels: Float): Float {
@@ -792,7 +794,7 @@
 
     suspend fun dispatchUserInputDelta(delta: Offset, source: NestedScrollSource) {
         scrollableState.scroll(MutatePriority.UserInput) {
-            dispatchScroll(delta, source)
+            dispatchScroll(delta, source, overscrollEnabledForSource = false)
         }
     }
 
@@ -801,7 +803,11 @@
     ) {
         scrollableState.scroll(MutatePriority.UserInput) {
             forEachDelta {
-                dispatchScroll(it.delta.singleAxisOffset(), Drag)
+                dispatchScroll(
+                    it.delta.singleAxisOffset(),
+                    UserInput,
+                    overscrollEnabledForSource = true
+                )
             }
         }
     }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 23ccc24..316e643 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -397,7 +397,7 @@
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         return if (
         // rounding error and drag only
-            source == NestedScrollSource.Drag && abs(state.currentPageOffsetFraction) > 0e-6
+            source == NestedScrollSource.UserInput && abs(state.currentPageOffsetFraction) > 0e-6
         ) {
             // find the current and next page (in the direction of dragging)
             val currentPageOffset = state.currentPageOffsetFraction * state.pageSize
@@ -434,7 +434,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        if (source == NestedScrollSource.Fling && available.mainAxis() != 0f) {
+        if (source == NestedScrollSource.SideEffect && available.mainAxis() != 0f) {
             throw CancellationException()
         }
         return Offset.Zero
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
index 445b390..2769c3f 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
@@ -431,7 +431,7 @@
             val offsetBeforeScroll = bottomSheetState.requireOffset()
             scrollDispatcher.dispatchPreScroll(
                 Offset(x = 0f, y = -sheetHeightPx),
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             rule.waitForIdle()
             Truth.assertWithMessage("Offset after scroll is equal to offset before scroll")
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
index 8b0d427..3b87fa0 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
@@ -971,7 +971,7 @@
             val offsetBeforeScroll = sheetState.requireOffset()
             scrollDispatcher.dispatchPreScroll(
                 Offset(x = 0f, y = -sheetHeightPx),
-                NestedScrollSource.Drag,
+                NestedScrollSource.UserInput,
             )
             rule.waitForIdle()
             assertWithMessage("Offset after scroll is equal to offset before scroll")
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/pullrefresh/PullRefreshStateTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/pullrefresh/PullRefreshStateTest.kt
index d9c5610..01decee 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/pullrefresh/PullRefreshStateTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/pullrefresh/PullRefreshStateTest.kt
@@ -72,7 +72,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -102,7 +105,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -146,7 +152,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -197,7 +206,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -246,7 +258,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -287,7 +302,10 @@
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -340,7 +358,10 @@
                 refreshThreshold = with(LocalDensity.current) { threshold.toDp() }
             )
 
-            Box(Modifier.pullRefresh(state).testTag(PullRefreshTag)) {
+            Box(
+                Modifier
+                    .pullRefresh(state)
+                    .testTag(PullRefreshTag)) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -408,8 +429,14 @@
                 onRefresh = { },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -417,7 +444,8 @@
         val dragUpOffset = Offset(0f, -100f)
 
         rule.runOnIdle {
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is not showing, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.position).isEqualTo(0f)
@@ -428,7 +456,8 @@
 
         rule.runOnIdle {
             assertThat(state.position).isEqualTo(100f /* 200 / 2 for drag multiplier */)
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is currently showing, so we should consume all the delta
             assertThat(preConsumed).isEqualTo(dragUpOffset)
             assertThat(state.position).isEqualTo(50f /* (200 - 100) / 2 for drag multiplier */)
@@ -449,8 +478,14 @@
                 onRefresh = { },
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -458,7 +493,8 @@
         val dragUpOffset = Offset(0f, -100f)
 
         rule.runOnIdle {
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is refreshing, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.position).isEqualTo(refreshingOffset)
@@ -479,8 +515,14 @@
                 onRefresh = { },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -488,7 +530,8 @@
         val dragUpOffset = Offset(0f, 100f)
 
         rule.runOnIdle {
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // We should ignore positive delta in prescroll, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.position).isEqualTo(0f)
@@ -499,7 +542,8 @@
 
         rule.runOnIdle {
             assertThat(state.position).isEqualTo(100f /* 200 / 2 for drag multiplier */)
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // We should ignore positive delta in prescroll, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.position).isEqualTo(100f /* 200 / 2 for drag multiplier */)
@@ -520,8 +564,14 @@
                 onRefresh = { },
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -529,7 +579,8 @@
         val dragUpOffset = Offset(0f, 100f)
 
         rule.runOnIdle {
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is refreshing, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.position).isEqualTo(refreshingOffset)
@@ -550,8 +601,14 @@
                 onRefresh = { },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -562,7 +619,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // We should ignore negative delta in postscroll, so we should consume nothing
             assertThat(postConsumed).isEqualTo(Offset.Zero)
@@ -577,7 +634,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // We should ignore negative delta in postscroll, so we should consume nothing
             assertThat(postConsumed).isEqualTo(Offset.Zero)
@@ -599,8 +656,14 @@
                 onRefresh = { },
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -611,7 +674,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // Pull refresh is refreshing, so we should consume nothing
             assertThat(postConsumed).isEqualTo(Offset.Zero)
@@ -633,8 +696,14 @@
                 onRefresh = { },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -645,7 +714,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // We should consume all the delta
             assertThat(postConsumed).isEqualTo(dragUpOffset)
@@ -660,7 +729,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // We should consume all the delta again
             assertThat(postConsumed).isEqualTo(dragUpOffset)
@@ -683,8 +752,14 @@
                 onRefresh = { },
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -695,7 +770,7 @@
             val postConsumed = dispatcher.dispatchPostScroll(
                 Offset.Zero,
                 dragUpOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             // Pull refresh is refreshing, so we should consume nothing
             assertThat(postConsumed).isEqualTo(Offset.Zero)
@@ -718,8 +793,14 @@
                 onRefresh = { onRefreshCalled = true },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -761,10 +842,12 @@
 
         rule.runOnIdle {
             assertThat(state.position)
-                .isEqualTo(calculateIndicatorPosition(
-                    refreshThreshold * (3 / 2f) /* account for drag multiplier */,
-                    refreshThreshold
-                ))
+                .isEqualTo(
+                    calculateIndicatorPosition(
+                        refreshThreshold * (3 / 2f) /* account for drag multiplier */,
+                        refreshThreshold
+                    )
+                )
             val preConsumed = runBlocking { dispatcher.dispatchPreFling(flingUp) }
             // Upwards fling, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Velocity.Zero)
@@ -792,8 +875,14 @@
                 onRefresh = {},
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -828,8 +917,14 @@
                 onRefresh = { onRefreshCalled = true },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -871,10 +966,12 @@
 
         rule.runOnIdle {
             assertThat(state.position)
-                .isEqualTo(calculateIndicatorPosition(
-                    refreshThreshold * (3 / 2f) /* account for drag multiplier */,
-                    refreshThreshold
-                ))
+                .isEqualTo(
+                    calculateIndicatorPosition(
+                        refreshThreshold * (3 / 2f) /* account for drag multiplier */,
+                        refreshThreshold
+                    )
+                )
             val preConsumed = runBlocking { dispatcher.dispatchPreFling(flingDown) }
             // Downwards fling, and we are currently showing, so we should consume all
             assertThat(preConsumed).isEqualTo(flingDown)
@@ -902,8 +999,14 @@
                 onRefresh = {},
                 refreshingOffset = with(LocalDensity.current) { refreshingOffset.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
@@ -938,8 +1041,14 @@
                 onRefresh = { onRefreshCalled = true },
                 refreshThreshold = with(LocalDensity.current) { refreshThreshold.toDp() }
             )
-            Box(Modifier.size(200.dp).pullRefresh(state)) {
-                Box(Modifier.size(100.dp).nestedScroll(connection, dispatcher))
+            Box(
+                Modifier
+                    .size(200.dp)
+                    .pullRefresh(state)) {
+                Box(
+                    Modifier
+                        .size(100.dp)
+                        .nestedScroll(connection, dispatcher))
             }
         }
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
index fc760ab..00636a4 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
@@ -682,7 +682,7 @@
 ): NestedScrollConnection = object : NestedScrollConnection {
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
+        return if (delta < 0 && source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(delta).toOffset()
         } else {
             Offset.Zero
@@ -694,7 +694,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        return if (source == NestedScrollSource.Drag) {
+        return if (source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(available.toFloat()).toOffset()
         } else {
             Offset.Zero
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index 8e434dd..223a9db 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -571,7 +571,7 @@
 ): NestedScrollConnection = object : NestedScrollConnection {
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
+        return if (delta < 0 && source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(delta).toOffset()
         } else {
             Offset.Zero
@@ -583,7 +583,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        return if (source == NestedScrollSource.Drag) {
+        return if (source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(available.toFloat()).toOffset()
         } else {
             Offset.Zero
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index d2f9de7..c7e699b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -866,7 +866,7 @@
 
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
+        return if (delta < 0 && source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(delta).toOffset()
         } else {
             Offset.Zero
@@ -878,7 +878,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        return if (source == NestedScrollSource.Drag) {
+        return if (source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(available.toFloat()).toOffset()
         } else {
             Offset.Zero
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
index 86e9f43..65c3069 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
@@ -554,7 +554,7 @@
 ): NestedScrollConnection = object : NestedScrollConnection {
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
+        return if (delta < 0 && source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(delta).toOffset()
         } else {
             Offset.Zero
@@ -566,7 +566,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        return if (source == NestedScrollSource.Drag) {
+        return if (source == NestedScrollSource.UserInput) {
             state.dispatchRawDelta(available.toFloat()).toOffset()
         } else {
             Offset.Zero
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
index fc39fae..c98d89b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
@@ -863,7 +863,7 @@
     get() = object : NestedScrollConnection {
         override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
             val delta = available.toFloat()
-            return if (delta < 0 && source == NestedScrollSource.Drag) {
+            return if (delta < 0 && source == NestedScrollSource.UserInput) {
                 performDrag(delta).toOffset()
             } else {
                 Offset.Zero
@@ -875,7 +875,7 @@
             available: Offset,
             source: NestedScrollSource
         ): Offset {
-            return if (source == NestedScrollSource.Drag) {
+            return if (source == NestedScrollSource.UserInput) {
                 performDrag(available.toFloat()).toOffset()
             } else {
                 Offset.Zero
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
index 1ef9312..baab13f 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
@@ -21,7 +21,6 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 import androidx.compose.ui.input.nestedscroll.NestedScrollSource
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.Drag
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.unit.Velocity
 
@@ -84,7 +83,10 @@
         source: NestedScrollSource
     ): Offset = when {
         !enabled -> Offset.Zero
-        source == Drag && available.y < 0 -> Offset(0f, onPull(available.y)) // Swiping up
+        source == NestedScrollSource.UserInput && available.y < 0 -> Offset(
+            0f,
+            onPull(available.y)
+        ) // Swiping up
         else -> Offset.Zero
     }
 
@@ -94,7 +96,10 @@
         source: NestedScrollSource
     ): Offset = when {
         !enabled -> Offset.Zero
-        source == Drag && available.y > 0 -> Offset(0f, onPull(available.y)) // Pulling down
+        source == NestedScrollSource.UserInput && available.y > 0 -> Offset(
+            0f,
+            onPull(available.y)
+        ) // Pulling down
         else -> Offset.Zero
     }
 
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/PullToRefreshSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/PullToRefreshSamples.kt
index a374481..36f9db7 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/PullToRefreshSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/PullToRefreshSamples.kt
@@ -223,7 +223,7 @@
                         available: Offset,
                         source: NestedScrollSource,
                     ): Offset = when {
-                        source == NestedScrollSource.Drag && available.y < 0 -> {
+                        source == NestedScrollSource.UserInput && available.y < 0 -> {
                             // Swiping up
                             val y = if (isRefreshing) 0f else {
                                 val newOffset = (verticalOffset + available.y).coerceAtLeast(0f)
@@ -242,7 +242,7 @@
                         available: Offset,
                         source: NestedScrollSource
                     ): Offset = when {
-                        source == NestedScrollSource.Drag && available.y > 0 -> {
+                        source == NestedScrollSource.UserInput && available.y > 0 -> {
                             // Swiping Down
                             val y = if (isRefreshing) 0f else {
                                 val newOffset = (verticalOffset + available.y).coerceAtLeast(0f)
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
index 27f5ee5..a3464b2 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
@@ -1262,7 +1262,7 @@
         nestedScrollDispatcher.dispatchPostScroll(
             consumed = Offset.Zero,
             available = Offset(x = 0f, y = scrollableContentHeight / 2f),
-            source = NestedScrollSource.Drag
+            source = NestedScrollSource.UserInput
         )
         scope.launch {
             nestedScrollDispatcher.dispatchPostFling(
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshStateImplTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshStateImplTest.kt
index 1233c28..998d030 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshStateImplTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/pulltorefresh/PullToRefreshStateImplTest.kt
@@ -79,7 +79,8 @@
             Box(
                 Modifier
                     .nestedScroll(state.nestedScrollConnection)
-                    .testTag(PullRefreshTag)) {
+                    .testTag(PullRefreshTag)
+            ) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -137,7 +138,8 @@
             Box(
                 Modifier
                     .nestedScroll(state.nestedScrollConnection)
-                    .testTag(PullRefreshTag)) {
+                    .testTag(PullRefreshTag)
+            ) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -180,7 +182,8 @@
             Box(
                 Modifier
                     .nestedScroll(state.nestedScrollConnection)
-                    .testTag(PullRefreshTag)) {
+                    .testTag(PullRefreshTag)
+            ) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -234,7 +237,8 @@
             Box(
                 Modifier
                     .nestedScroll(state.nestedScrollConnection)
-                    .testTag(PullRefreshTag)) {
+                    .testTag(PullRefreshTag)
+            ) {
                 LazyColumn {
                     items(100) {
                         Text("item $it")
@@ -277,18 +281,21 @@
             Box(
                 Modifier
                     .nestedScroll(state.nestedScrollConnection)
-                    .testTag(PullRefreshTag)) {
+                    .testTag(PullRefreshTag)
+            ) {
                 Box(
                     Modifier
                         .size(100.dp)
-                        .nestedScroll(connection, dispatcher))
+                        .nestedScroll(connection, dispatcher)
+                )
             }
         }
         // 100 pixels up
         val dragUpOffset = Offset(0f, -100f)
 
         rule.runOnIdle {
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is not showing, so we should consume nothing
             assertThat(preConsumed).isEqualTo(Offset.Zero)
             assertThat(state.verticalOffset).isEqualTo(0f)
@@ -300,7 +307,8 @@
         rule.runOnIdle {
             assertThat(state.calculateVerticalOffset())
                 .isEqualTo(100f /* 200 / 2 for drag multiplier */)
-            val preConsumed = dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.Drag)
+            val preConsumed =
+                dispatcher.dispatchPreScroll(dragUpOffset, NestedScrollSource.UserInput)
             // Pull refresh is currently showing, so we should consume all the delta
             assertThat(preConsumed).isEqualTo(dragUpOffset)
             assertThat(state.calculateVerticalOffset())
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
index 0bc9184..a8977c5 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
@@ -376,7 +376,7 @@
 ): NestedScrollConnection = object : NestedScrollConnection {
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
         val delta = available.toFloat()
-        return if (delta < 0 && source == NestedScrollSource.Drag) {
+        return if (delta < 0 && source == NestedScrollSource.UserInput) {
             sheetState.anchoredDraggableState.dispatchRawDelta(delta).toOffset()
         } else {
             Offset.Zero
@@ -388,7 +388,7 @@
         available: Offset,
         source: NestedScrollSource
     ): Offset {
-        return if (source == NestedScrollSource.Drag) {
+        return if (source == NestedScrollSource.UserInput) {
             sheetState.anchoredDraggableState.dispatchRawDelta(available.toFloat()).toOffset()
         } else {
             Offset.Zero
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
index f46c597..67a0f7b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/pulltorefresh/PullToRefresh.kt
@@ -318,7 +318,7 @@
         ): Offset = when {
             !enabled() -> Offset.Zero
             // Swiping up
-            source == NestedScrollSource.Drag && available.y < 0 -> {
+            source == NestedScrollSource.UserInput && available.y < 0 -> {
                 consumeAvailableOffset(available)
             }
             else -> Offset.Zero
@@ -331,7 +331,7 @@
         ): Offset = when {
             !enabled() -> Offset.Zero
             // Swiping down
-            source == NestedScrollSource.Drag && available.y > 0 -> {
+            source == NestedScrollSource.UserInput && available.y > 0 -> {
                 consumeAvailableOffset(available)
             }
             else -> Offset.Zero
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index af35be4..7a707ab 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -1702,14 +1702,18 @@
   }
 
   public static final class NestedScrollSource.Companion {
-    method public int getDrag();
-    method public int getFling();
+    method @Deprecated public int getDrag();
+    method @Deprecated public int getFling();
     method @Deprecated @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public int getRelocate();
-    method public int getWheel();
-    property public final int Drag;
-    property public final int Fling;
+    method public int getSideEffect();
+    method public int getUserInput();
+    method @Deprecated public int getWheel();
+    property @Deprecated public final int Drag;
+    property @Deprecated public final int Fling;
     property @Deprecated @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public final int Relocate;
-    property public final int Wheel;
+    property public final int SideEffect;
+    property public final int UserInput;
+    property @Deprecated public final int Wheel;
   }
 
 }
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 0c0e4ac..fd944d2 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -1702,14 +1702,18 @@
   }
 
   public static final class NestedScrollSource.Companion {
-    method public int getDrag();
-    method public int getFling();
+    method @Deprecated public int getDrag();
+    method @Deprecated public int getFling();
     method @Deprecated @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public int getRelocate();
-    method public int getWheel();
-    property public final int Drag;
-    property public final int Fling;
+    method public int getSideEffect();
+    method public int getUserInput();
+    method @Deprecated public int getWheel();
+    property @Deprecated public final int Drag;
+    property @Deprecated public final int Fling;
     property @Deprecated @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public final int Relocate;
-    property public final int Wheel;
+    property public final int SideEffect;
+    property public final int UserInput;
+    property @Deprecated public final int Wheel;
   }
 
 }
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt
index 2f557b3..e4c7320 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt
@@ -137,8 +137,12 @@
     }
 
     override fun toggleState() {
-        scrollResult = dispatcher.dispatchPreScroll(delta, NestedScrollSource.Drag)
-        scrollResult = dispatcher.dispatchPostScroll(delta, scrollResult, NestedScrollSource.Drag)
+        scrollResult = dispatcher.dispatchPreScroll(delta, NestedScrollSource.UserInput)
+        scrollResult = dispatcher.dispatchPostScroll(
+            delta,
+            scrollResult,
+            NestedScrollSource.UserInput
+        )
 
         runBlocking {
             velocityResult = dispatcher.dispatchPreFling(velocity)
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollSamples.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollSamples.kt
index 1d3cc92..cb2b988 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollSamples.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollSamples.kt
@@ -147,7 +147,7 @@
                     // want to pre consume (it's a nested scroll contract)
                     val parentsConsumed = nestedScrollDispatcher.dispatchPreScroll(
                         available = Offset(x = 0f, y = delta),
-                        source = NestedScrollSource.Drag
+                        source = NestedScrollSource.UserInput
                     )
                     // adjust what's available to us since might have consumed smth
                     val adjustedAvailable = delta - parentsConsumed.y
@@ -159,7 +159,7 @@
                     nestedScrollDispatcher.dispatchPostScroll(
                         consumed = totalConsumed,
                         available = Offset(x = 0f, y = left),
-                        source = NestedScrollSource.Drag
+                        source = NestedScrollSource.UserInput
                     )
                     // we won't dispatch pre/post fling events as we have no flinging here, but the
                     // idea is very similar:
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifierTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifierTest.kt
index c523c91..f5f45b3 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifierTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifierTest.kt
@@ -124,12 +124,12 @@
         assertThat(counter).isEqualTo(0)
         counter++
 
-        childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+        childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
         assertThat(counter).isEqualTo(2)
         counter++
 
         childDispatcher
-            .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.Drag)
+            .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.UserInput)
         assertThat(counter).isEqualTo(4)
         counter++
 
@@ -175,7 +175,7 @@
             assertThat(counter).isEqualTo(0)
             counter++
 
-            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(counter).isEqualTo(3)
             counter++
         }
@@ -224,7 +224,7 @@
             counter++
 
             childDispatcher
-                .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.Drag)
+                .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.UserInput)
             assertThat(counter).isEqualTo(3)
             counter++
         }
@@ -316,7 +316,7 @@
     fun nestedScroll_twoNodes_hierarchyDispatch(): Unit = runBlocking {
         val preScrollReturn = Offset(60f, 30f)
         val preFlingReturn = Velocity(154f, 56f)
-        var currentsource = NestedScrollSource.Drag
+        var currentsource = NestedScrollSource.UserInput
 
         val childConnection = object : NestedScrollConnection {}
         val parentConnection = object : NestedScrollConnection {
@@ -365,7 +365,7 @@
 
         childDispatcher.dispatchPostScroll(scrollOffset, scrollLeftOffset, currentsource)
         // flip to fling to test again below
-        currentsource = NestedScrollSource.Fling
+        currentsource = NestedScrollSource.SideEffect
 
         val preRes2 = childDispatcher.dispatchPreScroll(preScrollOffset, currentsource)
         assertThat(preRes2).isEqualTo(preScrollReturn)
@@ -410,7 +410,7 @@
 
         rule.runOnIdle {
             val preRes =
-                childDispatcher.dispatchPreScroll(dispatchedPreScroll, NestedScrollSource.Drag)
+                childDispatcher.dispatchPreScroll(dispatchedPreScroll, NestedScrollSource.UserInput)
             assertThat(preRes).isEqualTo(grandParentConsumesPreScroll + parentConsumedPreScroll)
         }
     }
@@ -460,7 +460,7 @@
             childDispatcher.dispatchPostScroll(
                 dispatchedConsumedScroll,
                 dispatchedScroll,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
         }
     }
@@ -549,7 +549,7 @@
     fun nestedScroll_twoNodes_flatDispatch(): Unit = runBlocking {
         val preScrollReturn = Offset(60f, 30f)
         val preFlingReturn = Velocity(154f, 56f)
-        var currentsource = NestedScrollSource.Drag
+        var currentsource = NestedScrollSource.UserInput
 
         val childConnection = object : NestedScrollConnection {}
         val parentConnection = object : NestedScrollConnection {
@@ -599,7 +599,7 @@
 
         childDispatcher.dispatchPostScroll(scrollOffset, scrollLeftOffset, currentsource)
         // flip to fling to test again below
-        currentsource = NestedScrollSource.Fling
+        currentsource = NestedScrollSource.SideEffect
 
         val preRes2 = childDispatcher.dispatchPreScroll(preScrollOffset, currentsource)
         assertThat(preRes2).isEqualTo(preScrollReturn)
@@ -649,9 +649,9 @@
             }
         }
 
-        childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+        childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
         childDispatcher
-            .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.Fling)
+            .dispatchPostScroll(scrollOffset, scrollLeftOffset, NestedScrollSource.SideEffect)
 
         childDispatcher.dispatchPreFling(preFling)
         childDispatcher.dispatchPostFling(postFlingConsumed, postFlingLeft)
@@ -822,14 +822,14 @@
         repeat(2) {
             counter = 1
 
-            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(counter).isEqualTo(3)
             counter = 1
 
             childDispatcher.dispatchPostScroll(
                 scrollOffset,
                 scrollLeftOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             assertThat(counter).isEqualTo(3)
             counter = 1
@@ -962,14 +962,14 @@
         repeat(2) {
             counter = 1
 
-            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(counter).isEqualTo(3)
             counter = 1
 
             childDispatcher.dispatchPostScroll(
                 scrollOffset,
                 scrollLeftOffset,
-                NestedScrollSource.Drag
+                NestedScrollSource.UserInput
             )
             assertThat(counter).isEqualTo(3)
             counter = 1
@@ -1118,14 +1118,14 @@
 
         rule.runOnIdle {
             val res =
-                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(res).isEqualTo(rootParentPreConsumed + parentToRemovePreConsumed)
             emitNewParent.value = false
         }
 
         rule.runOnIdle {
             val res =
-                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(res).isEqualTo(rootParentPreConsumed)
 
             emitNewParent.value = true
@@ -1133,7 +1133,7 @@
 
         rule.runOnIdle {
             val res =
-                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+                childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.UserInput)
             assertThat(res).isEqualTo(rootParentPreConsumed + parentToRemovePreConsumed)
         }
     }
@@ -1161,20 +1161,29 @@
         }
 
         rule.runOnIdle {
-            val res = childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            val res = childDispatcher.dispatchPreScroll(
+                preScrollOffset,
+                NestedScrollSource.UserInput
+            )
             assertThat(res).isEqualTo(preScrollReturn)
 
             emitParentNestedScroll.value = false
         }
 
         rule.runOnIdle {
-            val res = childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            val res = childDispatcher.dispatchPreScroll(
+                preScrollOffset,
+                NestedScrollSource.UserInput
+            )
             assertThat(res).isEqualTo(Offset.Zero)
             emitParentNestedScroll.value = true
         }
 
         rule.runOnIdle {
-            val res = childDispatcher.dispatchPreScroll(preScrollOffset, NestedScrollSource.Drag)
+            val res = childDispatcher.dispatchPreScroll(
+                preScrollOffset,
+                NestedScrollSource.UserInput
+            )
             assertThat(res).isEqualTo(preScrollReturn)
         }
     }
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/NestedScrollInteropConnection.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/NestedScrollInteropConnection.android.kt
index 5d125ee..d579246 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/NestedScrollInteropConnection.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/NestedScrollInteropConnection.android.kt
@@ -189,7 +189,7 @@
 }
 
 private fun NestedScrollSource.toViewType(): Int = when (this) {
-    NestedScrollSource.Drag -> TYPE_TOUCH
+    NestedScrollSource.UserInput -> TYPE_TOUCH
     else -> TYPE_NON_TOUCH
 }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
index c1d4642..6789cf6 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidViewHolder.android.kt
@@ -614,6 +614,6 @@
 private fun Float.toComposeVelocity(): Float = this * -1f
 
 private fun toNestedScrollSource(type: Int): NestedScrollSource = when (type) {
-    ViewCompat.TYPE_TOUCH -> NestedScrollSource.Drag
-    else -> NestedScrollSource.Fling
+    ViewCompat.TYPE_TOUCH -> NestedScrollSource.UserInput
+    else -> NestedScrollSource.SideEffect
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifier.kt
index 457a782..3672fd2 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollModifier.kt
@@ -229,25 +229,53 @@
     override fun toString(): String {
         @Suppress("DEPRECATION")
         return when (this) {
-            Drag -> "Drag"
-            Fling -> "Fling"
+            UserInput -> "UserInput"
+            SideEffect -> "SideEffect"
             @OptIn(ExperimentalComposeUiApi::class)
             Relocate -> "Relocate"
-            Wheel -> "Wheel"
             else -> "Invalid"
         }
     }
 
     companion object {
+
+        /**
+         * Represents any source of scroll events originated from a user interaction: mouse, touch,
+         * key events.
+         */
+        val UserInput: NestedScrollSource = NestedScrollSource(1)
+
+        /**
+         * Represents any other source of scroll events that are not a direct user input. (e.g
+         * animations, fling)
+         */
+        val SideEffect: NestedScrollSource = NestedScrollSource(2)
+
         /**
          * Dragging via mouse/touch/etc events.
          */
-        val Drag: NestedScrollSource = NestedScrollSource(1)
+        @Deprecated(
+            "This has been replaced by UserInput.",
+            replaceWith = ReplaceWith(
+                "NestedScrollSource.UserInput",
+                "import androidx.compose.ui.input.nestedscroll." +
+                    "NestedScrollSource.Companion.UserInput"
+            )
+        )
+        val Drag: NestedScrollSource = UserInput
 
         /**
          * Flinging after the drag has ended with velocity.
          */
-        val Fling: NestedScrollSource = NestedScrollSource(2)
+        @Deprecated(
+            "This has been replaced by SideEffect.",
+            replaceWith = ReplaceWith(
+                "NestedScrollSource.SideEffect",
+                "import androidx.compose.ui.input.nestedscroll." +
+                    "NestedScrollSource.Companion.SideEffect"
+            )
+        )
+        val Fling: NestedScrollSource = SideEffect
 
         /**
          * Relocating when a component asks parents to scroll to bring it into view.
@@ -261,7 +289,15 @@
         /**
          * Scrolling via mouse wheel.
          */
-        val Wheel: NestedScrollSource = NestedScrollSource(4)
+        @Deprecated(
+            "This has been replaced by UserInput.",
+            replaceWith = ReplaceWith(
+                "NestedScrollSource.UserInput",
+                "import androidx.compose.ui.input.nestedscroll." +
+                    "NestedScrollSource.Companion.UserInput"
+            )
+        )
+        val Wheel: NestedScrollSource = UserInput
     }
 }
 
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
index 4a1d531..b6ebbda 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
@@ -831,7 +831,7 @@
     get() = object : NestedScrollConnection {
         override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
             val delta = available.toFloat()
-            return if (delta < 0 && source == NestedScrollSource.Drag) {
+            return if (delta < 0 && source == NestedScrollSource.UserInput) {
                 performDrag(delta).toOffset()
             } else {
                 Offset.Zero
@@ -843,7 +843,7 @@
             available: Offset,
             source: NestedScrollSource
         ): Offset {
-            return if (source == NestedScrollSource.Drag) {
+            return if (source == NestedScrollSource.UserInput) {
                 performDrag(available.toFloat()).toOffset()
             } else {
                 Offset.Zero
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
index 9bfc687..009334f9 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/BasicSwipeToDismissBox.kt
@@ -353,6 +353,7 @@
             edgeSwipeState: State<EdgeSwipeState>
         ): NestedScrollConnection =
             object : NestedScrollConnection {
+                @Suppress("DEPRECATION") // b/327155912
                 override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                     val delta = available.x
                     // If swipeState = SwipeState.SWIPING_TO_DISMISS - perform swipeToDismiss
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
index 94200e9..e344c9f 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
@@ -471,6 +471,7 @@
      *
      * @return The delta the consumed by the [SwipeableV2State]
      */
+    @Suppress("DEPRECATION") // b/327155912
     fun dispatchRawDelta(delta: Float): Float {
         var remainingDelta = delta