Merge "Replacing NestedScroll Sources." into androidx-main
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 8f3b7b7..14d7aee 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
@@ -50,9 +50,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() }
             }
@@ -611,7 +610,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 =
@@ -642,14 +641,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)
@@ -699,7 +697,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 {
@@ -725,7 +727,7 @@
 
     suspend fun dispatchUserInputDelta(delta: Offset, source: NestedScrollSource) {
         scrollableState.scroll(MutatePriority.UserInput) {
-            dispatchScroll(delta, source)
+            dispatchScroll(delta, source, overscrollEnabledForSource = false)
         }
     }
 
@@ -734,7 +736,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