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"))
|
implementation(project(":desktop:tray:common"))
|
||||||
if (Platform.getCurrentPlatform() == Platform.Desktop.Windows) {
|
if (Platform.getCurrentPlatform() == Platform.Desktop.Windows) {
|
||||||
implementation(project(":desktop:tray:windows"))
|
implementation(project(":desktop:tray:linux"))
|
||||||
|
// implementation(project(":desktop:tray:windows"))
|
||||||
} else {
|
} else {
|
||||||
// TODO use external library for linux and remove this line
|
implementation(project(":desktop:tray:linux"))
|
||||||
implementation(project(":desktop:tray:windows"))
|
|
||||||
// implementation(project(":desktop:tray:linux"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation(project(":shared:app"))
|
implementation(project(":shared:app"))
|
||||||
|
@ -7,4 +7,5 @@ dependencies {
|
|||||||
api(project(":desktop:tray:common"))
|
api(project(":desktop:tray:common"))
|
||||||
ksp(libs.autoService.ksp)
|
ksp(libs.autoService.ksp)
|
||||||
implementation(libs.autoService.annoations)
|
implementation(libs.autoService.annoations)
|
||||||
|
implementation(libs.systemTray)
|
||||||
}
|
}
|
@ -1,14 +1,134 @@
|
|||||||
package ir.amirab.util.desktop.systemtray.impl
|
package ir.amirab.util.desktop.systemtray.impl
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.graphics.toAwtImage
|
||||||
import com.google.auto.service.AutoService
|
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.IconSource
|
||||||
import ir.amirab.util.compose.StringSource
|
import ir.amirab.util.compose.StringSource
|
||||||
import ir.amirab.util.compose.action.MenuItem
|
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 ir.amirab.util.desktop.systemtray.IComposeSystemTray
|
||||||
|
import java.awt.Image
|
||||||
|
|
||||||
@AutoService(IComposeSystemTray::class)
|
@AutoService(IComposeSystemTray::class)
|
||||||
class ComposeSystemTrayForLinux : IComposeSystemTray {
|
class ComposeSystemTrayForLinux : IComposeSystemTray {
|
||||||
override fun ComposeSystemTray(icon: IconSource, title: StringSource, menu: List<MenuItem>, onClick: () -> Unit) {
|
@Composable
|
||||||
TODO("Not yet implemented")
|
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-ksp = { module = "dev.zacsweers.autoservice:auto-service-ksp", version.ref = "autoServiceKsp" }
|
||||||
autoService-annoations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" }
|
autoService-annoations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" }
|
||||||
|
|
||||||
|
systemTray = "com.dorkbox:SystemTray:4.4"
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||||
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user