Merge "Desktop. Make DesktopPlatform internal, introduce internal MouseScrollableConfig" into androidx-main
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopPlatform.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopPlatform.desktop.kt
new file mode 100644
index 0000000..409dae1
--- /dev/null
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DesktopPlatform.desktop.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation
+
+internal enum class DesktopPlatform {
+    Linux,
+    Windows,
+    MacOS,
+    Unknown;
+
+    companion object {
+        /**
+         * Identify OS on which the application is currently running.
+         */
+        val Current: DesktopPlatform by lazy {
+            val name = System.getProperty("os.name")
+            when {
+                name?.startsWith("Linux") == true -> Linux
+                name?.startsWith("Win") == true -> Windows
+                name == "Mac OS X" -> MacOS
+                else -> Unknown
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
index 60027ce..71001d5 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
@@ -18,18 +18,25 @@
 
 package androidx.compose.foundation.gestures
 
+import androidx.compose.foundation.DesktopPlatform
+import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.ui.input.mouse.MouseScrollOrientation
 import androidx.compose.ui.input.mouse.MouseScrollUnit
 import androidx.compose.ui.input.mouse.mouseScrollFilter
-import androidx.compose.ui.platform.DesktopPlatform
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalDesktopPlatform
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.dp
 import kotlin.math.sqrt
 
+// TODO(demin): figure out how we can provide a public API for changing MouseScrollConfig.
+//  There are two ways:
+//  - provide as CompositionLocal
+//  - provide as a parameter Modifier.scrollable(mouseScrollConfig=)
+//  This should be done only after new Pointer Input API with mouse support
+internal val LocalMouseScrollConfig = compositionLocalOf { MouseScrollableConfig.CurrentPlatform }
+
 // TODO(demin): implement smooth scroll animation on Windows
 // TODO(demin): implement touchpad bounce physics on MacOS
 // TODO(demin): maybe we need to differentiate different linux environments (Gnome/KDE)
@@ -39,8 +46,7 @@
     onScroll: (Float) -> Unit
 ): Modifier = composed {
     val density = LocalDensity.current
-    val desktopPlatform = LocalDesktopPlatform.current
-    val config = PlatformScrollConfig(density, desktopPlatform)
+    val config = LocalMouseScrollConfig.current
 
     mouseScrollFilter { event, bounds ->
         if (isOrientationMatches(orientation, event.orientation)) {
@@ -48,7 +54,8 @@
                 Orientation.Vertical -> bounds.height
                 Orientation.Horizontal -> bounds.width
             }
-            onScroll(-config.toScrollOffset(event.delta, scrollBounds))
+            val scrollOffset = config.offsetOf(event.delta, scrollBounds, density)
+            onScroll(-scrollOffset)
             true
         } else {
             false
@@ -67,37 +74,59 @@
     }
 }
 
-private class PlatformScrollConfig(
-    private val density: Density,
-    private val desktopPlatform: DesktopPlatform
-) {
-    fun toScrollOffset(
-        unit: MouseScrollUnit,
-        bounds: Int
-    ): Float = when (unit) {
-        is MouseScrollUnit.Line -> unit.value * platformLineScrollOffset(bounds)
+private fun MouseScrollableConfig.offsetOf(
+    unit: MouseScrollUnit,
+    bounds: Int,
+    density: Density
+) = when (unit) {
+    is MouseScrollUnit.Line -> offsetOf(unit.value, bounds, density)
 
-        // TODO(demin): Chrome/Firefox on Windows scroll differently: value * 0.90f * bounds
-        // the formula was determined experimentally based on Windows Start behaviour
-        is MouseScrollUnit.Page -> unit.value * bounds.toFloat()
-    }
+    // TODO(demin): Chrome/Firefox on Windows scroll differently: value * 0.90f * bounds
+    //
+    // TODO(demin): How can we integrate page scrolling into MouseScrollConfig and new
+    //  Pointer Input API with mouse support?
+    // the formula was determined experimentally based on Windows Start behaviour
+    is MouseScrollUnit.Page -> unit.value * bounds.toFloat()
+}
+
+internal interface MouseScrollableConfig {
+    fun offsetOf(scrollDelta: Float, bounds: Int, density: Density): Float
 
     // TODO(demin): Chrome on Windows/Linux uses different scroll strategy
     //  (always the same scroll offset, bounds-independent).
-    //  Figure out why and decide if we can use this strategy instead of current one.
-    private fun platformLineScrollOffset(bounds: Int): Float {
-        return when (desktopPlatform) {
-            // TODO(demin): is this formula actually correct? some experimental values don't fit
-            //  the formula
+    //  Figure out why and decide if we can use this strategy instead of the current one.
+    companion object {
+        // TODO(demin): is this formula actually correct? some experimental values don't fit
+        //  the formula
+        val LinuxGnome = object : MouseScrollableConfig {
             // the formula was determined experimentally based on Ubuntu Nautilus behaviour
-            DesktopPlatform.Linux -> sqrt(bounds.toFloat())
+            override fun offsetOf(scrollDelta: Float, bounds: Int, density: Density): Float {
+                return scrollDelta * sqrt(bounds.toFloat())
+            }
+        }
 
+        val WindowsWinUI = object : MouseScrollableConfig {
             // the formula was determined experimentally based on Windows Start behaviour
-            DesktopPlatform.Windows -> bounds / 20f
+            override fun offsetOf(scrollDelta: Float, bounds: Int, density: Density): Float {
+                return scrollDelta * bounds / 20f
+            }
+        }
 
+        val MacOSCocoa = object : MouseScrollableConfig {
             // the formula was determined experimentally based on MacOS Finder behaviour
             // MacOS driver will send events with accelerating delta
-            DesktopPlatform.MacOS -> with(density) { 10.dp.toPx() }
+            override fun offsetOf(scrollDelta: Float, bounds: Int, density: Density): Float {
+                return with(density) {
+                    scrollDelta * 10.dp.toPx()
+                }
+            }
+        }
+
+        val CurrentPlatform: MouseScrollableConfig = when (DesktopPlatform.Current) {
+            DesktopPlatform.Linux -> LinuxGnome
+            DesktopPlatform.Windows -> WindowsWinUI
+            DesktopPlatform.MacOS -> MacOSCocoa
+            DesktopPlatform.Unknown -> WindowsWinUI
         }
     }
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/KeyMapping.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/KeyMapping.desktop.kt
index 740602d..a5ff8c9 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/KeyMapping.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/KeyMapping.desktop.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.foundation.text
 
+import androidx.compose.foundation.DesktopPlatform
 import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.input.key.KeyEvent
 import androidx.compose.ui.input.key.isAltPressed
@@ -23,7 +24,6 @@
 import androidx.compose.ui.input.key.isMetaPressed
 import androidx.compose.ui.input.key.isShiftPressed
 import androidx.compose.ui.input.key.key
-import androidx.compose.ui.platform.DesktopPlatform
 import java.awt.event.KeyEvent as AwtKeyEvent
 
 internal actual val platformDefaultKeyMapping: KeyMapping =
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt
index 2d9fcce..cda2912 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text/selection/SelectionManager.desktop.kt
@@ -16,12 +16,12 @@
 
 package androidx.compose.foundation.text.selection
 
+import androidx.compose.foundation.DesktopPlatform
 import androidx.compose.foundation.text.MappedKeys
 import androidx.compose.ui.input.key.KeyEvent
 import androidx.compose.ui.input.key.isCtrlPressed
 import androidx.compose.ui.input.key.isMetaPressed
 import androidx.compose.ui.input.key.key
-import androidx.compose.ui.platform.DesktopPlatform
 
 // this doesn't sounds very sustainable
 // it would end up being a function for any conceptual keyevent (selectall, cut, copy, paste)
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
index 02ac894..780b6ea 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
@@ -16,6 +16,8 @@
 
 package androidx.compose.foundation
 
+import androidx.compose.foundation.gestures.LocalMouseScrollConfig
+import androidx.compose.foundation.gestures.MouseScrollableConfig
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
@@ -37,8 +39,6 @@
 import androidx.compose.ui.input.mouse.MouseScrollEvent
 import androidx.compose.ui.input.mouse.MouseScrollOrientation
 import androidx.compose.ui.input.mouse.MouseScrollUnit
-import androidx.compose.ui.platform.DesktopPlatform
-import androidx.compose.ui.platform.LocalDesktopPlatform
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.GestureScope
@@ -525,7 +525,7 @@
             unhoverColor = Color.Black,
             hoverColor = Color.Red
         ),
-        LocalDesktopPlatform provides DesktopPlatform.MacOS,
+        LocalMouseScrollConfig provides MouseScrollableConfig.MacOSCocoa,
         content = content
     )
 }
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
index 30eef41..50e864c 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
@@ -19,11 +19,11 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.mouse.MouseScrollEvent
-import androidx.compose.ui.input.mouse.MouseScrollUnit
 import androidx.compose.ui.input.mouse.MouseScrollOrientation
-import androidx.compose.ui.platform.DesktopPlatform
+import androidx.compose.ui.input.mouse.MouseScrollUnit
 import androidx.compose.ui.platform.TestComposeWindow
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
@@ -38,13 +38,10 @@
 class DesktopScrollableTest {
     private val density = 2f
 
-    private fun window(
-        platform: DesktopPlatform
-    ) = TestComposeWindow(
+    private fun window() = TestComposeWindow(
         width = 100,
         height = 100,
-        density = Density(density),
-        desktopPlatform = platform
+        density = Density(density)
     )
 
     private fun scrollLineLinux(bounds: Dp) = sqrt(bounds.value * density)
@@ -54,18 +51,22 @@
 
     @Test
     fun `linux, scroll vertical`() {
-        val window = window(platform = DesktopPlatform.Linux)
+        val window = window()
         val context = TestColumn()
 
         window.setContent {
-            Box(
-                Modifier
-                    .scrollable(
-                        orientation = Orientation.Vertical,
-                        state = context.controller()
-                    )
-                    .size(10.dp, 20.dp)
-            )
+            CompositionLocalProvider(
+                LocalMouseScrollConfig provides MouseScrollableConfig.LinuxGnome
+            ) {
+                Box(
+                    Modifier
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = context.controller()
+                        )
+                        .size(10.dp, 20.dp)
+                )
+            }
         }
 
         window.onMouseScroll(
@@ -87,18 +88,22 @@
 
     @Test
     fun `windows, scroll vertical`() {
-        val window = window(platform = DesktopPlatform.Windows)
+        val window = window()
         val context = TestColumn()
 
         window.setContent {
-            Box(
-                Modifier
-                    .scrollable(
-                        orientation = Orientation.Vertical,
-                        state = context.controller()
-                    )
-                    .size(10.dp, 20.dp)
-            )
+            CompositionLocalProvider(
+                LocalMouseScrollConfig provides MouseScrollableConfig.WindowsWinUI
+            ) {
+                Box(
+                    Modifier
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = context.controller()
+                        )
+                        .size(10.dp, 20.dp)
+                )
+            }
         }
 
         window.onMouseScroll(
@@ -120,18 +125,22 @@
 
     @Test
     fun `windows, scroll one page vertical`() {
-        val window = window(platform = DesktopPlatform.Windows)
+        val window = window()
         val context = TestColumn()
 
         window.setContent {
-            Box(
-                Modifier
-                    .scrollable(
-                        orientation = Orientation.Vertical,
-                        state = context.controller()
-                    )
-                    .size(10.dp, 20.dp)
-            )
+            CompositionLocalProvider(
+                LocalMouseScrollConfig provides MouseScrollableConfig.WindowsWinUI
+            ) {
+                Box(
+                    Modifier
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = context.controller()
+                        )
+                        .size(10.dp, 20.dp)
+                )
+            }
         }
 
         window.onMouseScroll(
@@ -145,18 +154,22 @@
 
     @Test
     fun `macOS, scroll vertical`() {
-        val window = window(platform = DesktopPlatform.MacOS)
+        val window = window()
         val context = TestColumn()
 
         window.setContent {
-            Box(
-                Modifier
-                    .scrollable(
-                        orientation = Orientation.Vertical,
-                        state = context.controller()
-                    )
-                    .size(10.dp, 20.dp)
-            )
+            CompositionLocalProvider(
+                LocalMouseScrollConfig provides MouseScrollableConfig.MacOSCocoa
+            ) {
+                Box(
+                    Modifier
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = context.controller()
+                        )
+                        .size(10.dp, 20.dp)
+                )
+            }
         }
 
         window.onMouseScroll(
@@ -170,18 +183,22 @@
 
     @Test
     fun `scroll with different orientation`() {
-        val window = window(platform = DesktopPlatform.Linux)
+        val window = window()
         val column = TestColumn()
 
         window.setContent {
-            Box(
-                Modifier
-                    .scrollable(
-                        orientation = Orientation.Vertical,
-                        state = column.controller()
-                    )
-                    .size(10.dp, 20.dp)
-            )
+            CompositionLocalProvider(
+                LocalMouseScrollConfig provides MouseScrollableConfig.LinuxGnome
+            ) {
+                Box(
+                    Modifier
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = column.controller()
+                        )
+                        .size(10.dp, 20.dp)
+                )
+            }
         }
 
         window.onMouseScroll(
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopPlatform.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopPlatform.desktop.kt
index d7cd1e4..69b44f4 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopPlatform.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopPlatform.desktop.kt
@@ -1,4 +1,20 @@
 /*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
  * Copyright 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,36 +32,23 @@
 
 package androidx.compose.ui.platform
 
-import androidx.compose.runtime.staticCompositionLocalOf
-
-// TODO(demin): changing DesktopPlatform is confusing.
-//  Replace DesktopPlatform by DesktopLookAndFeel
-//  (https://github.com/JetBrains/compose-jb/issues/303).
-//  Or get rid of it completely
-//  and provide appropriate Local's (LocalMouseScrollConfig, etc).
-val LocalDesktopPlatform = staticCompositionLocalOf(DesktopPlatform::Current)
-
-enum class DesktopPlatform {
+internal enum class DesktopPlatform {
     Linux,
     Windows,
-    MacOS;
+    MacOS,
+    Unknown;
 
     companion object {
         /**
          * Identify OS on which the application is currently running.
-         *
-         * If it is needed to know the current platform in @Composable function,
-         * use [LocalDesktopPlatform] instead of this function, so composable functions can
-         * change their behaviour if we change platform in tests or in application settings
-         * (some applications maybe will have this setting)
          */
         val Current: DesktopPlatform by lazy {
             val name = System.getProperty("os.name")
             when {
-                name.startsWith("Linux") -> Linux
-                name.startsWith("Win") -> Windows
+                name?.startsWith("Linux") == true -> Linux
+                name?.startsWith("Win") == true -> Windows
                 name == "Mac OS X" -> MacOS
-                else -> throw Error("Unsupported OS $name")
+                else -> Unknown
             }
         }
     }
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
index cddba9b..96e192f 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
@@ -17,7 +17,6 @@
 package androidx.compose.ui.platform
 
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.input.mouse.MouseScrollEvent
@@ -48,7 +47,6 @@
     val width: Int,
     val height: Int,
     val density: Density = Density(1f, 1f),
-    private val desktopPlatform: DesktopPlatform = DesktopPlatform.Linux,
     private val nanoTime: () -> Long = System::nanoTime,
     coroutineContext: CoroutineContext = emptyDispatcher
 ) {
@@ -104,11 +102,7 @@
 
         val owner = DesktopOwner(owners, density)
         owner.setContent {
-            CompositionLocalProvider(
-                LocalDesktopPlatform provides desktopPlatform
-            ) {
-                content()
-            }
+            content()
         }
         owner.setSize(width, height)
         owner.measureAndLayout()
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
index 8b3028a..a5a4065 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
@@ -30,6 +30,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Surface
@@ -54,9 +55,6 @@
 import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.input.key.KeyEventType
 import androidx.compose.ui.input.key.keyEvent
-import androidx.compose.ui.input.mouse.MouseScrollEvent
-import androidx.compose.ui.input.mouse.MouseScrollOrientation
-import androidx.compose.ui.input.mouse.MouseScrollUnit
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.test.junit4.DesktopScreenshotTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
@@ -297,17 +295,19 @@
     @Test(timeout = 5000)
     fun `rendering of LazyColumn`() = renderingTest(
         width = 40,
-        height = 40,
-        platform = DesktopPlatform.Windows // scrolling behave differently on different platforms
+        height = 40
     ) {
-        var height by mutableStateOf(10.dp)
+        var itemHeight by mutableStateOf(10.dp)
+        val padding = 10
+        val columnHeight = this.height - padding * 2
+        val state = LazyListState()
         setContent {
-            Box(Modifier.padding(10.dp)) {
-                LazyColumn {
+            Box(Modifier.padding(padding.dp)) {
+                LazyColumn(state = state) {
                     items(
                         listOf(Color.Red, Color.Green, Color.Blue, Color.Black, Color.Gray)
                     ) { color ->
-                        Box(Modifier.size(width = 30.dp, height = height).background(color))
+                        Box(Modifier.size(width = 30.dp, height = itemHeight).background(color))
                     }
                 }
             }
@@ -317,25 +317,21 @@
         screenshotRule.snap(surface, "frame1_initial")
         assertFalse(hasRenders())
 
-        owners.onMouseScroll(
-            10,
-            10,
-            MouseScrollEvent(MouseScrollUnit.Page(1f), MouseScrollOrientation.Vertical)
-        )
+        state.scroll {
+            scrollBy(columnHeight.toFloat())
+        }
         awaitNextRender()
         screenshotRule.snap(surface, "frame2_onMouseScroll")
         assertFalse(hasRenders())
 
-        owners.onMouseScroll(
-            10,
-            10,
-            MouseScrollEvent(MouseScrollUnit.Page(10f), MouseScrollOrientation.Vertical)
-        )
+        state.scroll {
+            scrollBy(10 * columnHeight.toFloat())
+        }
         awaitNextRender()
         screenshotRule.snap(surface, "frame3_onMouseScroll")
         assertFalse(hasRenders())
 
-        height = 5.dp
+        itemHeight = 5.dp
         awaitNextRender()
         screenshotRule.snap(surface, "frame4_change_height")
         assertFalse(hasRenders())
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
index 888d26d..95282d3 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
@@ -17,7 +17,6 @@
 package androidx.compose.ui.platform
 
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.unit.Density
@@ -36,11 +35,10 @@
 internal fun renderingTest(
     width: Int,
     height: Int,
-    platform: DesktopPlatform = DesktopPlatform.Linux,
     context: CoroutineContext = Dispatchers.Swing,
     block: suspend RenderingTestScope.() -> Unit
 ) = runBlocking(context) {
-    val scope = RenderingTestScope(width, height, platform, context)
+    val scope = RenderingTestScope(width, height, context)
     try {
         scope.block()
     } finally {
@@ -49,9 +47,8 @@
 }
 
 internal class RenderingTestScope(
-    private val width: Int,
-    private val height: Int,
-    private val platform: DesktopPlatform,
+    val width: Int,
+    val height: Int,
     coroutineContext: CoroutineContext
 ) {
     var currentTimeMillis = 0L
@@ -87,9 +84,7 @@
         owner?.dispose()
         val owner = DesktopOwner(owners)
         owner.setContent {
-            CompositionLocalProvider(LocalDesktopPlatform provides platform) {
-                content()
-            }
+            content()
         }
         this.owner = owner
     }