diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/AWTDebounceEventQueue.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/AWTDebounceEventQueue.desktop.kt deleted file mode 100644 index 0016be5465181..0000000000000 --- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/AWTDebounceEventQueue.desktop.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.ui.awt - -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.launch -import kotlinx.coroutines.swing.Swing -import kotlinx.coroutines.yield -import kotlin.coroutines.CoroutineContext - -/** - * Dispatch events on the next EDT tick if they are blocking EDT too long, - * so EDT can handle more important actions (like render a new frame). - * - * (EDT - AWT event dispatch thread) - * - * [maxNanosToBlockThread] defines how long events can block EDT. - * - * It is needed in a case when we have a lot of heavy events (like mouse scroll) - * in a short period of time. - * - * Without dispatching events we may have a situation - * when 30 events of scroll block AWT Thread for 1 second, without rerendering content. - */ -@OptIn(DelicateCoroutinesApi::class) -internal class AWTDebounceEventQueue constructor( - // 4 ms is enough for the user not to see the lags - private val maxNanosToBlockThread: Long = 4_000_000, // 4 milliseconds - private val nanoTime: () -> Long = System::nanoTime, - context: CoroutineContext = Dispatchers.Swing -) { - private val queue = Channel<() -> Unit>(Channel.UNLIMITED) - - private var job = GlobalScope.launch(context) { - var lastTime = nanoTime() - for (event in queue) { - val time = nanoTime() - if (time - lastTime >= maxNanosToBlockThread) { - lastTime = time - yield() - } - event() - } - } - - fun cancel() { - job.cancel() - } - - fun post(event: () -> Unit) { - queue.trySend(event) - } -} \ No newline at end of file diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt index 27571fc84e12b..4cca1ddadef37 100644 --- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt +++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt @@ -69,11 +69,6 @@ import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent internal class ComposeLayer { private var isDisposed = false - // TODO(demin): probably we need to get rid of asynchronous events. it was added because of - // slow lazy scroll. But events become unpredictable, and we can't consume them. - // Alternative solution to a slow scroll - merge multiple scroll events into a single one. - private val events = AWTDebounceEventQueue() - private val _component = ComponentImpl() val component: SkiaLayer get() = _component @@ -247,7 +242,7 @@ internal class ComposeLayer { } } - override fun inputMethodTextChanged(event: InputMethodEvent) = events.post { + override fun inputMethodTextChanged(event: InputMethodEvent) { catchExceptions { scene.onInputMethodEvent(event) } @@ -280,19 +275,15 @@ internal class ComposeLayer { private fun onMouseEvent(event: MouseEvent) { lastMouseEvent = event - events.post { - catchExceptions { - scene.onMouseEvent(density, event) - } + catchExceptions { + scene.onMouseEvent(density, event) } } private fun onMouseWheelEvent(event: MouseWheelEvent) { lastMouseEvent = event - events.post { - catchExceptions { - scene.onMouseWheelEvent(density, event) - } + catchExceptions { + scene.onMouseWheelEvent(density, event) } } @@ -307,7 +298,6 @@ internal class ComposeLayer { fun dispose() { check(!isDisposed) scene.close() - events.cancel() _component.dispose() _initContent = null isDisposed = true diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/desktop/AWTDebounceEventQueueTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/desktop/AWTDebounceEventQueueTest.kt deleted file mode 100644 index 7e6dd86d151e6..0000000000000 --- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/desktop/AWTDebounceEventQueueTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2020 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.desktop - -import androidx.compose.desktop.AWTDebounceEventQueueTest.Event.Input -import androidx.compose.desktop.AWTDebounceEventQueueTest.Event.Render -import androidx.compose.ui.awt.AWTDebounceEventQueue -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.runBlockingTest -import kotlinx.coroutines.yield -import org.junit.Assert.assertEquals -import org.junit.Test - -@OptIn(ExperimentalCoroutinesApi::class) -internal class AWTDebounceEventQueueTest { - enum class Event { - Input, Render - } - - var events = mutableListOf() - var time = 0L - - fun input() { - events.add(Input) - time++ - } - - fun TestCoroutineScope.scheduleRender() = launch { - yield() - events.add(Render) - } - - fun TestCoroutineScope.testQueue() = AWTDebounceEventQueue( - maxNanosToBlockThread = 3, - nanoTime = { time }, - coroutineContext - ) - - @Test - fun `queue events`() = runBlockingTest { - val queue = testQueue() - queue.post { input() } - assertEquals(listOf(Input), events) - - queue.post { input() } - queue.post { input() } - assertEquals(listOf(Input, Input, Input), events) - - queue.post { input() } - assertEquals(listOf(Input, Input, Input), events) - - runCurrent() - assertEquals(listOf(Input, Input, Input, Input), events) - - queue.cancel() - } - - @Test - fun `queue events and render simultaneously`() = runBlockingTest { - val queue = testQueue() - - scheduleRender() - scheduleRender() - - for (i in 0 until 7) { - queue.post { input() } - } - - runCurrent() - - assertEquals( - listOf(Input, Input, Input, Render, Render, Input, Input, Input, Input), - events - ) - - queue.cancel() - } -} \ No newline at end of file