Skip to content

[Desktop] 支持自定义 UI 线程判定,兼容 Nucleus Tao 等非 Swing 事件循环 #293

Description

@RavenLiao

感谢开源 ,项目里一直在用Sketch做图片缩略图和预览。

最近我在尝试把 Compose Desktop 应用迁移到 Nucleus 的 Tao backend。Tao 不走 AWT/Swing EDT,而是在 JVM 的主线程运行自己的 native event loop;Nucleus 也会将 Dispatchers.Main 映射到这个 Tao UI 线程。

迁移后发现 Sketch 的 desktop 实现目前固定通过 Swing 判断 UI 线程:

internal actual fun isMainThread() = SwingUtilities.isEventDispatchThread()

所以即使请求已经运行在 Tao 的 UI 线程上,Sketch 仍会认为它不在 UI thread:

java.lang.IllegalStateException: This method must be executed in the UI thread
    at com.github.panpf.sketch.util.Core_utils_desktopKt.requiredMainThread
    at com.github.panpf.sketch.request.internal.RequestExecutor.execute

我的调用方式是正常的 Compose 图片请求,例如:

val request = ComposableImageRequest(uri = imageUri) {
    size(256, 256)
}

SubcomposeAsyncImage(
    request = request,
    contentDescription = null,
)

或者在预览任务中:

val result = ImageRequest(
    context = PlatformContext.INSTANCE,
    uri = uri,
).execute()

目前我在 Decompose 中遇到过类似问题。它的 Compose 扩展默认也是 Swing EDT checker,但核心层提供了 MainThreadChecker 接口,可以由应用改成基于协程 Main dispatcher 的实现:

class CoroutineMainThreadChecker : MainThreadChecker {
    override fun isMainThread(): Boolean =
        !Dispatchers.Main.immediate.isDispatchNeeded(EmptyCoroutineContext)
}

这个判断在 Swing 下仍然对应 EDT,在 Tao 下则对应 Tao 的 UI thread。

想请教一下:Sketch Desktop 后续是否有可能提供类似的扩展点?例如允许通过 Builder 配置一个 isMainThread 回调,或者提供一个可替换的 MainThreadChecker。默认实现仍然继续用 SwingUtilities.isEventDispatchThread() 就可以保持现有行为,而 Tao、JavaFX 或其他非 Swing 的 Compose Desktop backend 可以自行接入。

我不确定这种设计是否符合 Sketch 的整体方向,所以像问一下能不能加上支持?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions