mirror of
https://github.com/amir1376/ab-download-manager.git
synced 2025-02-20 11:43:24 +08:00
add system tray for linux (#346)
### Fixed - System Tray in linux not showing well
This commit is contained in:
parent
40ca2a51fc
commit
53ff9154f8
@ -65,11 +65,10 @@ dependencies {
|
||||
|
||||
implementation(project(":desktop:tray:common"))
|
||||
if (Platform.getCurrentPlatform() == Platform.Desktop.Windows) {
|
||||
implementation(project(":desktop:tray:windows"))
|
||||
implementation(project(":desktop:tray:linux"))
|
||||
// implementation(project(":desktop:tray:windows"))
|
||||
} else {
|
||||
// TODO use external library for linux and remove this line
|
||||
implementation(project(":desktop:tray:windows"))
|
||||
// implementation(project(":desktop:tray:linux"))
|
||||
implementation(project(":desktop:tray:linux"))
|
||||
}
|
||||
|
||||
implementation(project(":shared:app"))
|
||||
|
@ -7,4 +7,5 @@ dependencies {
|
||||
api(project(":desktop:tray:common"))
|
||||
ksp(libs.autoService.ksp)
|
||||
implementation(libs.autoService.annoations)
|
||||
implementation(libs.systemTray)
|
||||
}
|
@ -1,14 +1,134 @@
|
||||
package ir.amirab.util.desktop.systemtray.impl
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.graphics.toAwtImage
|
||||
import com.google.auto.service.AutoService
|
||||
import dorkbox.systemTray.Menu
|
||||
import dorkbox.systemTray.Separator
|
||||
import dorkbox.systemTray.SystemTray
|
||||
import ir.amirab.util.compose.IconSource
|
||||
import ir.amirab.util.compose.StringSource
|
||||
import ir.amirab.util.compose.action.MenuItem
|
||||
import ir.amirab.util.desktop.GlobalDensity
|
||||
import ir.amirab.util.desktop.GlobalLayoutDirection
|
||||
import ir.amirab.util.desktop.systemtray.IComposeSystemTray
|
||||
import java.awt.Image
|
||||
|
||||
@AutoService(IComposeSystemTray::class)
|
||||
class ComposeSystemTrayForLinux : IComposeSystemTray {
|
||||
override fun ComposeSystemTray(icon: IconSource, title: StringSource, menu: List<MenuItem>, onClick: () -> Unit) {
|
||||
TODO("Not yet implemented")
|
||||
@Composable
|
||||
override fun ComposeSystemTray(
|
||||
icon: IconSource,
|
||||
title: StringSource,
|
||||
menu: List<MenuItem>,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val systemTray: SystemTray? = remember { SystemTray.get() }
|
||||
if (systemTray == null) {
|
||||
System.err.println("System tray is not supported")
|
||||
return
|
||||
}
|
||||
|
||||
val iconPainter = icon.rememberPainter()
|
||||
val awtImage = remember(iconPainter) {
|
||||
iconPainter.toAwtImage(
|
||||
GlobalDensity,
|
||||
GlobalLayoutDirection,
|
||||
)
|
||||
}
|
||||
val tooltipString = title.rememberString()
|
||||
|
||||
LaunchedEffect(awtImage) {
|
||||
systemTray.setImage(awtImage)
|
||||
}
|
||||
LaunchedEffect(tooltipString) {
|
||||
systemTray.setTooltip(tooltipString)
|
||||
}
|
||||
|
||||
val immutableMenu = menu.toImmutableMenuItem()
|
||||
DisposableEffect(immutableMenu) {
|
||||
systemTray.menu.addImmutableMenu(immutableMenu)
|
||||
onDispose {
|
||||
for (entry in systemTray.menu.entries) {
|
||||
systemTray.menu.remove(entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
systemTray.shutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Menu.addImmutableMenu(immutableMenu: List<ImmutableMenuItem>) {
|
||||
for (item in immutableMenu) {
|
||||
when (item) {
|
||||
ImmutableMenuItem.Separator -> add(Separator())
|
||||
is ImmutableMenuItem.SingleItem -> add(
|
||||
dorkbox.systemTray.MenuItem(
|
||||
item.title,
|
||||
item.icon,
|
||||
{
|
||||
item.onAction()
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
is ImmutableMenuItem.SubMenu -> add(
|
||||
Menu(
|
||||
item.title,
|
||||
item.icon,
|
||||
).apply {
|
||||
addImmutableMenu(item.items)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun List<MenuItem>.toImmutableMenuItem(): List<ImmutableMenuItem> {
|
||||
val density = GlobalDensity
|
||||
val layoutDirection = GlobalLayoutDirection
|
||||
return map {
|
||||
when (it) {
|
||||
MenuItem.Separator -> ImmutableMenuItem.Separator
|
||||
is MenuItem.SingleItem -> {
|
||||
ImmutableMenuItem.SingleItem(
|
||||
title = it.title.collectAsState().value.rememberString(),
|
||||
icon = null,
|
||||
// icon = it.icon.collectAsState().value?.rememberPainter()?.toAwtImage(
|
||||
// density, layoutDirection,
|
||||
// ),
|
||||
onAction = it::onClick
|
||||
)
|
||||
}
|
||||
|
||||
is MenuItem.SubMenu -> ImmutableMenuItem.SubMenu(
|
||||
title = it.title.collectAsState().value.rememberString(),
|
||||
icon = it.icon.collectAsState().value?.rememberPainter()?.toAwtImage(
|
||||
GlobalDensity, GlobalLayoutDirection,
|
||||
),
|
||||
items = it.items.collectAsState().value.toImmutableMenuItem()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal sealed class ImmutableMenuItem {
|
||||
data object Separator : ImmutableMenuItem()
|
||||
data class SingleItem(
|
||||
val title: String,
|
||||
val icon: Image?,
|
||||
val onAction: () -> Unit,
|
||||
) : ImmutableMenuItem()
|
||||
|
||||
data class SubMenu(
|
||||
val title: String,
|
||||
val icon: Image?,
|
||||
val items: List<ImmutableMenuItem>
|
||||
) : ImmutableMenuItem()
|
||||
}
|
@ -128,6 +128,8 @@ kotlinFileWatcher = { module = "io.github.irgaly.kfswatch:kfswatch", version.ref
|
||||
autoService-ksp = { module = "dev.zacsweers.autoservice:auto-service-ksp", version.ref = "autoServiceKsp" }
|
||||
autoService-annoations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" }
|
||||
|
||||
systemTray = "com.dorkbox:SystemTray:4.4"
|
||||
|
||||
[plugins]
|
||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user