chore: swing CoroutineScope

This commit is contained in:
hstyi
2025-04-01 15:36:17 +08:00
committed by hstyi
parent 744e64b359
commit d90fb9aa35
12 changed files with 38 additions and 36 deletions

View File

@@ -3,7 +3,6 @@ package app.termora
import com.formdev.flatlaf.util.SystemInfo
import com.jthemedetecor.util.OsInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
@@ -123,19 +122,18 @@ object Application {
return "Termora"
}
@Suppress("OPT_IN_USAGE")
fun browse(uri: URI, async: Boolean = true) {
// https://github.com/TermoraDev/termora/issues/178
if (SystemInfo.isWindows && uri.scheme == "file") {
if (async) {
GlobalScope.launch(Dispatchers.IO) { tryBrowse(uri) }
swingCoroutineScope.launch(Dispatchers.IO) { tryBrowse(uri) }
} else {
tryBrowse(uri)
}
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(uri)
} else if (async) {
GlobalScope.launch(Dispatchers.IO) { tryBrowse(uri) }
swingCoroutineScope.launch(Dispatchers.IO) { tryBrowse(uri) }
} else {
tryBrowse(uri)
}

View File

@@ -12,9 +12,7 @@ import com.jthemedetecor.OsThemeDetector
import com.mixpanel.mixpanelapi.ClientDelivery
import com.mixpanel.mixpanelapi.MessageBuilder
import com.mixpanel.mixpanelapi.MixpanelAPI
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.apache.commons.io.FileUtils
import org.apache.commons.lang3.LocaleUtils
@@ -51,8 +49,7 @@ class ApplicationRunner {
val enableAnalytics = measureTimeMillis { enableAnalytics() }
// init ActionManager、KeymapManager
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
ActionManager.getInstance()
KeymapManager.getInstance()
}
@@ -89,9 +86,8 @@ class ApplicationRunner {
}
}
@Suppress("OPT_IN_USAGE")
private fun clearTemporary() {
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
// 启动时清除
FileUtils.cleanDirectory(Application.getTemporaryDir())
}
@@ -273,13 +269,12 @@ class ApplicationRunner {
/**
* 统计 https://mixpanel.com
*/
@OptIn(DelicateCoroutinesApi::class)
private fun enableAnalytics() {
if (Application.isUnknownVersion()) {
return
}
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
try {
val properties = JSONObject()
properties.put("os", SystemUtils.OS_NAME)

View File

@@ -11,7 +11,6 @@ import app.termora.terminal.CursorStyle
import jetbrains.exodus.bindings.StringBinding
import jetbrains.exodus.env.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.apache.commons.io.IOUtils
import org.apache.commons.lang3.StringUtils
@@ -348,8 +347,7 @@ class Database private constructor(private val env: Environment) : Disposable {
private val properties = Collections.synchronizedMap(mutableMapOf<String, String>())
init {
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.IO) { properties.putAll(getProperties()) }
swingCoroutineScope.launch(Dispatchers.IO) { properties.putAll(getProperties()) }
}
protected open fun getString(key: String): String? {

View File

@@ -222,7 +222,7 @@ abstract class DialogWrapper(owner: Window?) : JDialog(owner) {
return
}
doCancelAction()
SwingUtilities.invokeLater { doCancelAction() }
}
})

View File

@@ -2,8 +2,10 @@ package app.termora
import app.termora.actions.AnAction
import app.termora.actions.AnActionEvent
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.apache.commons.lang3.exception.ExceptionUtils
import org.apache.sshd.client.SshClient
import org.apache.sshd.client.session.ClientSession
@@ -51,8 +53,7 @@ class HostDialog(owner: Window, host: Host? = null) : DialogWrapper(owner) {
putValue(NAME, "${I18n.getString("termora.new-host.test-connection")}...")
isEnabled = false
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
testConnection(pane.getHost())
withContext(Dispatchers.Swing) {
putValue(NAME, I18n.getString("termora.new-host.test-connection"))

View File

@@ -10,7 +10,6 @@ import com.formdev.flatlaf.util.SystemInfo
import com.jgoodies.forms.builder.FormBuilder
import com.jgoodies.forms.layout.FormLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
@@ -1123,8 +1122,7 @@ open class HostOptionsPane : OptionsPane() {
addComponentListener(object : ComponentAdapter() {
override fun componentShown(e: ComponentEvent) {
removeComponentListener(this)
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
for (commPort in SerialPort.getCommPorts()) {
withContext(Dispatchers.Swing) {
serialPortComboBox.addItem(commPort.systemPortName)

View File

@@ -5,7 +5,9 @@ import com.formdev.flatlaf.FlatClientProperties
import com.formdev.flatlaf.extras.components.FlatTextPane
import com.formdev.flatlaf.util.SystemInfo
import com.jetbrains.JBR
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import org.apache.commons.lang3.StringUtils
import java.awt.BorderLayout
@@ -20,6 +22,8 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
object OptionPane {
private val coroutineScope = swingCoroutineScope
fun showConfirmDialog(
parentComponent: Component?,
message: Any,
@@ -104,9 +108,8 @@ object OptionPane {
val dialog = initDialog(pane.createDialog(parentComponent, title))
if (duration.inWholeMilliseconds > 0) {
dialog.addWindowListener(object : WindowAdapter() {
@OptIn(DelicateCoroutinesApi::class)
override fun windowOpened(e: WindowEvent) {
GlobalScope.launch(Dispatchers.Swing) {
coroutineScope.launch(Dispatchers.Swing) {
delay(duration.inWholeMilliseconds)
if (dialog.isVisible) {
dialog.isVisible = false

View File

@@ -1,5 +1,10 @@
package app.termora
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.swing.Swing
import org.slf4j.LoggerFactory
import java.awt.Component
import java.awt.Window
@@ -8,6 +13,8 @@ import javax.swing.JPopupMenu
import javax.swing.SwingUtilities
import kotlin.reflect.KClass
val swingCoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Swing)
@Suppress("UNCHECKED_CAST")
open class Scope(
private val beans: MutableMap<KClass<*>, Any> = ConcurrentHashMap(),
@@ -151,6 +158,7 @@ class ApplicationScope private constructor() : Scope() {
if (log.isInfoEnabled) {
log.info("ApplicationScope disposed")
}
swingCoroutineScope.cancel()
super.dispose()
}

View File

@@ -36,8 +36,10 @@ import com.jgoodies.forms.builder.FormBuilder
import com.jgoodies.forms.layout.FormLayout
import com.jthemedetecor.OsThemeDetector
import com.sun.jna.LastErrorException
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.*
import org.apache.commons.codec.binary.Base64
import org.apache.commons.io.IOUtils
@@ -615,10 +617,9 @@ class SettingsOptionsPane : OptionsPane() {
add(getCenterComponent(), BorderLayout.CENTER)
}
@OptIn(DelicateCoroutinesApi::class)
private fun initEvents() {
syncConfigButton.addActionListener {
GlobalScope.launch(Dispatchers.IO) { sync() }
swingCoroutineScope.launch(Dispatchers.IO) { sync() }
}
typeComboBox.addItemListener {

View File

@@ -4,7 +4,6 @@ import com.formdev.flatlaf.FlatLaf
import com.formdev.flatlaf.extras.FlatAnimatedLafChange
import com.jthemedetecor.OsThemeDetector
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.slf4j.LoggerFactory
import java.util.*
@@ -76,8 +75,7 @@ class ThemeManager private constructor() {
init {
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.IO) {
swingCoroutineScope.launch(Dispatchers.IO) {
OsThemeDetector.getDetector().registerListener(object : Consumer<Boolean> {
override fun accept(isDark: Boolean) {
if (!appearance.followSystem) {

View File

@@ -36,6 +36,7 @@ class AppUpdateAction private constructor() : AnAction(
StringUtils.EMPTY,
Icons.ideUpdate
) {
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Swing)
companion object {
private val log = LoggerFactory.getLogger(AppUpdateAction::class.java)
@@ -59,7 +60,6 @@ class AppUpdateAction private constructor() : AnAction(
}
@OptIn(DelicateCoroutinesApi::class)
private fun scheduleUpdate() {
fixedRateTimer(
name = "check-update-timer",
@@ -67,7 +67,7 @@ class AppUpdateAction private constructor() : AnAction(
period = 5.hours.inWholeMilliseconds, daemon = true
) {
if (!isRemindMeNextTime) {
GlobalScope.launch(Dispatchers.IO) { supervisorScope { launch { checkUpdate() } } }
coroutineScope.launch(Dispatchers.IO) { checkUpdate() }
}
}
}

View File

@@ -3,8 +3,11 @@ package app.termora.terminal.panel
import app.termora.Database
import app.termora.DynamicColor
import app.termora.assertEventDispatchThread
import app.termora.swingCoroutineScope
import app.termora.terminal.*
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import java.awt.*
import javax.swing.JComponent
@@ -484,14 +487,13 @@ class TerminalDisplay(
g.font = font
}
@OptIn(DelicateCoroutinesApi::class)
fun toast(text: String, duration: Duration) {
if (!terminalPanel.showToast) {
return
}
val toast = Toast(text)
GlobalScope.launch(Dispatchers.Swing) {
swingCoroutineScope.launch(Dispatchers.Swing) {
delay(duration)
toasts.remove(toast)
terminalPanel.repaintImmediate()