Skip to content

Commit

Permalink
Don't depend on kotlinx-coroutines-swing (#515)
Browse files Browse the repository at this point in the history
Because it overrides Dispatchers.Main

Fixes JetBrains/compose-multiplatform#1943 on skiko side
  • Loading branch information
igordmn authored Mar 9, 2022
1 parent 95ef46b commit 617eae5
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 19 deletions.
6 changes: 0 additions & 6 deletions skiko/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,6 @@ kotlin {

val awtMain by getting {
dependsOn(jvmMain)
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:$coroutinesVersion")
}
}

if (supportAndroid) {
Expand All @@ -298,9 +295,6 @@ kotlin {

val awtTest by getting {
dependsOn(jvmTest)
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:$coroutinesVersion")
}
}

if (supportAndroid) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.jetbrains.skiko

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.swing.Swing
import java.awt.*
import java.awt.event.FocusEvent
import java.awt.event.InputMethodEvent
Expand Down Expand Up @@ -110,7 +109,7 @@ internal open class HardwareLayer(
// and its accessibility context. This timeout is used to deal with concurrency
// TODO Find more reliable procedure
resetFocusAccessibleJob?.cancel()
resetFocusAccessibleJob = GlobalScope.launch(Dispatchers.Swing) {
resetFocusAccessibleJob = GlobalScope.launch(MainUIDispatcher) {
delay(100)
_focusedAccessible = null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.jetbrains.skiko

import kotlinx.coroutines.*
import java.awt.event.ActionListener
import java.lang.Runnable
import java.util.concurrent.TimeUnit
import javax.swing.SwingUtilities
import javax.swing.Timer
import kotlin.coroutines.CoroutineContext

/**
* Dispatcher for UI thread, which is used in the current implementation of native UI integration.
* Currently, it uses Swing event dispatching thread.
*/
val MainUIDispatcher: CoroutineDispatcher
get() = SwingDispatcher

/**
* Dispatcher for Swing event dispatching thread.
*
* Copy of Dispatchers.Swing from kotlinx-coroutines-swing.
*
* We don't depend on kotlinx-coroutines-swing, because it will override Dispatchers.Main, and
* application can require a different Dispatchers.Main.
*
* Note, that we use internal API `Delay` and experimental `resumeUndispatched`.
* That means it can be changed in the future. When it happens, we need
* to release a new version of Skiko.
*/
@OptIn(InternalCoroutinesApi::class, ExperimentalCoroutinesApi::class)
private object SwingDispatcher : CoroutineDispatcher(), Delay {
override fun dispatch(context: CoroutineContext, block: Runnable): Unit = SwingUtilities.invokeLater(block)

override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
val timer = schedule(timeMillis, TimeUnit.MILLISECONDS) {
with(continuation) { resumeUndispatched(Unit) }
}
continuation.invokeOnCancellation { timer.stop() }
}

override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle {
val timer = schedule(timeMillis, TimeUnit.MILLISECONDS) {
block.run()
}
return object : DisposableHandle {
override fun dispose() {
timer.stop()
}
}
}

private fun schedule(time: Long, unit: TimeUnit, action: ActionListener): Timer =
Timer(unit.toMillis(time).coerceAtMost(Int.MAX_VALUE.toLong()).toInt(), action).apply {
isRepeats = false
start()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import kotlinx.coroutines.*
import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.FrameLimiter
import org.jetbrains.skiko.RenderException
import org.jetbrains.skiko.MainUIDispatcher
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.context.DirectSoftwareContextHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.skiko.redrawer
import org.jetbrains.skia.BackendRenderTarget
import org.jetbrains.skia.DirectContext
import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.MainUIDispatcher
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.context.AngleContextHandler
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.*
import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.FrameLimiter
import org.jetbrains.skiko.MainUIDispatcher
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.context.SoftwareContextHandler
Expand Down
4 changes: 1 addition & 3 deletions skiko/src/jvmTest/kotlin/org/jetbrains/skiko/util/UiTest.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package org.jetbrains.skiko.util

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.swing.Swing
import org.jetbrains.skiko.*
import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
Expand All @@ -16,7 +14,7 @@ internal fun uiTest(block: suspend UiTestScope.() -> Unit) {

val renderApi = System.getProperty("skiko.test.ui.renderApi", "all")

runBlocking(Dispatchers.Swing) {
runBlocking(MainUIDispatcher) {
if (renderApi == "all") {
SkikoProperties.fallbackRenderApiQueue(SkikoProperties.renderApi).forEach {
println("Testing $it renderApi")
Expand Down

0 comments on commit 617eae5

Please sign in to comment.