diff --git a/ui/ui/build.gradle b/ui/ui/build.gradle index cfd04cb3142..7a739f40a07 100644 --- a/ui/ui/build.gradle +++ b/ui/ui/build.gradle @@ -176,7 +176,6 @@ if(AndroidXComposePlugin.isMultiplatformEnabled(project)) { dependsOn(skikoMain) dependencies { implementation(libs.kotlinStdlibJdk8) - api(libs.kotlinCoroutinesSwing) } } diff --git a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/ConfigureSwingGlobalsForCompose.desktop.kt b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/ConfigureSwingGlobalsForCompose.desktop.kt index 540d5dadd3a..9e7ae841743 100644 --- a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/ConfigureSwingGlobalsForCompose.desktop.kt +++ b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/ConfigureSwingGlobalsForCompose.desktop.kt @@ -32,7 +32,7 @@ import org.jetbrains.skia.impl.Library * - sets UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) * * Should be called before using any class from `java.swing.*` - * (even before SwingUtilities.invokeLater or Dispatchers.Swing) + * (even before SwingUtilities.invokeLater or MainUIDispatcher) */ @ExperimentalComposeUiApi fun configureSwingGlobalsForCompose( diff --git a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt index 7f4b4259acb..015391e9ada 100644 --- a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt +++ b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt @@ -31,9 +31,8 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.window.WindowExceptionHandler import androidx.compose.ui.window.density import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.swing.Swing import org.jetbrains.skia.Canvas +import org.jetbrains.skiko.MainUIDispatcher import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.SkikoView import java.awt.Cursor @@ -93,7 +92,7 @@ internal class ComposeLayer { } internal val scene = ComposeScene( - Dispatchers.Swing + coroutineExceptionHandler, + MainUIDispatcher + coroutineExceptionHandler, _component, Density(1f), _component::needRedraw, diff --git a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt index 9c875918602..7928febcf04 100644 --- a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt +++ b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.launch -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import java.util.concurrent.atomic.AtomicBoolean /** @@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean * * Composition bootstrapping mechanisms for a particular platform/framework should call * [ensureStarted] during setup to initialize periodic global snapshot notifications. - * For desktop, these notifications are always sent on [Dispatchers.Swing]. Other platforms + * For desktop, these notifications are always sent on [MainUIDispatcher]. Other platforms * may establish different policies for these notifications. */ internal actual object GlobalSnapshotManager { @@ -43,7 +43,8 @@ internal actual object GlobalSnapshotManager { actual fun ensureStarted() { if (started.compareAndSet(false, true)) { val channel = Channel(Channel.CONFLATED) - CoroutineScope(Dispatchers.Swing).launch { + Dispatchers.IO + CoroutineScope(MainUIDispatcher).launch { channel.consumeEach { // TODO(https://github.com/JetBrains/compose-jb/issues/1854) get rid of synchronized synchronized(GlobalSnapshotManager) { diff --git a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt index 004939d98bc..bea831ca0c9 100644 --- a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt +++ b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt @@ -41,9 +41,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.withContext import kotlinx.coroutines.yield +import org.jetbrains.skiko.MainUIDispatcher import kotlin.system.exitProcess /** @@ -195,7 +195,7 @@ suspend fun awaitApplication( if (System.getProperty("compose.application.configure.swing.globals") == "true") { configureSwingGlobalsForCompose() } - withContext(Dispatchers.Swing) { + withContext(MainUIDispatcher) { withContext(YieldFrameClock) { GlobalSnapshotManager.ensureStarted() diff --git a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt index d5d32eb61f1..f9e6148ea0f 100644 --- a/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt +++ b/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt @@ -26,11 +26,10 @@ import androidx.compose.ui.node.Ref import androidx.compose.ui.util.UpdateEffect import androidx.compose.ui.util.makeDisplayable import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import java.awt.Window /** @@ -117,7 +116,7 @@ fun AwtWindow( // So we will have a wrong active window (window1). showJob.value?.cancel() - showJob.value = GlobalScope.launch(Dispatchers.Swing) { + showJob.value = GlobalScope.launch(MainUIDispatcher) { window().isVisible = currentVisible } } diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ImageComposeSceneTest.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ImageComposeSceneTest.kt index 963c54c5be7..313b308070e 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ImageComposeSceneTest.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ImageComposeSceneTest.kt @@ -39,10 +39,9 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import kotlin.time.Duration.Companion.seconds import kotlin.time.ExperimentalTime -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import org.junit.Ignore import org.junit.Rule import org.junit.Test @@ -118,7 +117,7 @@ class ImageComposeSceneTest { @Test(timeout = 5000) fun `closing ImageComposeScene should not cancel coroutineContext's Job`() { - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val scene = ImageComposeScene(100, 100, coroutineContext = coroutineContext) scene.close() } diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt index 371a4536e2a..6e6e8a79c8e 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt @@ -24,9 +24,8 @@ import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.dp import androidx.compose.ui.window.density import com.google.common.truth.Truth.assertThat -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import org.junit.Assume import org.junit.Test import java.awt.Dimension @@ -38,7 +37,7 @@ class ComposePanelTest { fun `don't override user preferred size`() { Assume.assumeFalse(GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance) - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val composePanel = ComposePanel() composePanel.preferredSize = Dimension(234, 345) assertThat(composePanel.preferredSize).isEqualTo(Dimension(234, 345)) @@ -63,7 +62,7 @@ class ComposePanelTest { fun `pack to Compose content`() { Assume.assumeFalse(GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance) - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val composePanel = ComposePanel() composePanel.setContent { Box(Modifier.requiredSize(300.dp, 400.dp)) @@ -93,7 +92,7 @@ class ComposePanelTest { val layoutPassConstraints = mutableListOf() - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val composePanel = ComposePanel() composePanel.setContent { Box(Modifier.fillMaxSize().layout { _, constraints -> diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposeWindowTest.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposeWindowTest.kt index 034a57e2902..9a1d93dbf98 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposeWindowTest.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposeWindowTest.kt @@ -44,9 +44,8 @@ import java.awt.event.MouseEvent.MOUSE_MOVED import java.awt.event.MouseEvent.MOUSE_PRESSED import java.awt.event.MouseEvent.MOUSE_RELEASED import java.awt.event.WindowEvent -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import org.junit.Assume import org.junit.Test @@ -142,7 +141,7 @@ class ComposeWindowTest { fun `don't override user preferred size`() { Assume.assumeFalse(GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance) - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val window = ComposeWindow() try { window.preferredSize = Dimension(234, 345) @@ -160,7 +159,7 @@ class ComposeWindowTest { fun `pack to Compose content`() { Assume.assumeFalse(GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance) - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val window = ComposeWindow() try { window.setContent { @@ -187,7 +186,7 @@ class ComposeWindowTest { val layoutPassConstraints = mutableListOf() - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { val window = ComposeWindow() try { window.size = Dimension(300, 400) diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt index dbc107b188d..c90acb317d2 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt @@ -24,21 +24,20 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Density import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.yield import org.jetbrains.skia.Canvas import org.jetbrains.skia.Surface import org.jetbrains.skiko.FrameDispatcher +import org.jetbrains.skiko.MainUIDispatcher import kotlin.coroutines.CoroutineContext internal fun renderingTest( width: Int, height: Int, - context: CoroutineContext = Dispatchers.Swing, + context: CoroutineContext = MainUIDispatcher, block: suspend RenderingTestScope.() -> Unit -) = runBlocking(Dispatchers.Swing) { +) = runBlocking(MainUIDispatcher) { val scope = RenderingTestScope(width, height, context) try { scope.block() diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt index 6ce74e06f2d..8c0a25e80e6 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt @@ -24,16 +24,15 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.Snapshot import java.awt.GraphicsEnvironment import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.withTimeout import kotlinx.coroutines.yield +import org.jetbrains.skiko.MainUIDispatcher import org.junit.Assume.assumeFalse @OptIn(ExperimentalCoroutinesApi::class) @@ -52,7 +51,7 @@ internal fun runApplicationTest( ) { assumeFalse(GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance) - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { withTimeout(30000) { val exceptionHandler = TestExceptionHandler() withExceptionHandler(exceptionHandler) { diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt index c3d25e63b3c..b82a9678805 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt @@ -394,7 +394,7 @@ class WindowStateTest { @Test fun `restore size and position after maximize`() = runApplicationTest { // Swing/macOs can't re-change isMaximized in a deterministic way: -// fun main() = runBlocking(Dispatchers.Swing) { +// fun main() = runBlocking(MainUIDispatcher) { // val window = ComposeWindow() // window.size = Dimension(200, 200) // window.isVisible = true @@ -498,7 +498,7 @@ class WindowStateTest { @Test fun `minimize window before show`() = runApplicationTest { // Linux/macos doesn't support this: -// fun main() = runBlocking(Dispatchers.Swing) { +// fun main() = runBlocking(MainUIDispatcher) { // val window = ComposeWindow() // window.size = Dimension(200, 200) // window.isMinimized = true diff --git a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowTest.kt b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowTest.kt index 98d1c896516..7853ce1ad14 100644 --- a/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowTest.kt +++ b/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowTest.kt @@ -50,11 +50,10 @@ import java.awt.Dimension import java.awt.GraphicsEnvironment import java.awt.event.WindowAdapter import java.awt.event.WindowEvent -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.MainUIDispatcher import org.junit.Assume.assumeFalse import org.junit.Test import kotlinx.coroutines.cancelAndJoin @@ -416,7 +415,7 @@ class WindowTest { val oldRecomposers = Recomposer.runningRecomposers.value - runBlocking(Dispatchers.Swing) { + runBlocking(MainUIDispatcher) { repeat(10) { val window = ComposeWindow() window.size = Dimension(200, 200) diff --git a/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.skiko.kt b/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.skiko.kt index d011e093f24..cbdfccbfca8 100644 --- a/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.skiko.kt +++ b/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.skiko.kt @@ -24,7 +24,7 @@ package androidx.compose.ui.platform * * Composition bootstrapping mechanisms for a particular platform/framework should call * [ensureStarted] during setup to initialize periodic global snapshot notifications. - * For desktop, these notifications are always sent on [Dispatchers.Swing]. Other platforms + * For desktop, these notifications are always sent on [MainUIDispatcher]. Other platforms * may establish different policies for these notifications. */ internal expect object GlobalSnapshotManager {