Aru
07/08/2024, 4:46 PMAlexander Maryanovsky
07/08/2024, 4:51 PMWindow
in your composition.Alexander Maryanovsky
07/08/2024, 4:53 PMshowWindow
that is controlled from your menu and in the composition do
if (showWindow) Window(…) { }
Aru
07/08/2024, 5:04 PMshowWindow
when the tray icon is clicked. I was testing with Tray(... ,onAction = { println("Tray.onAction" })
. As per the documentation:
Action performed when user clicks on the tray icon (double click on Windows, right click on macOs)But I don’t the debug line printed when I click / double click / right click the tray icon.
Alexander Maryanovsky
07/08/2024, 5:12 PMAru
07/08/2024, 8:03 PMisOpen
is driven by the last item in the menu.
I don’t want a menu when the icon is clicked. I want a window to appear just like the ToolBox. onAction
does not get triggered when I click the tray Icon.Alexander Maryanovsky
07/08/2024, 8:12 PMAlexander Maryanovsky
07/08/2024, 8:12 PMfun main() = application {
var showWindow by remember { mutableStateOf(false) }
val trayState = rememberTrayState()
Tray(
icon = MyAppIcon,
state = trayState,
onAction = { showWindow = !showWindow }
)
if (showWindow) {
Window(onCloseRequest = { showWindow = false }) {}
}
}
object MyAppIcon : Painter() {
override val intrinsicSize = Size(256f, 256f)
override fun DrawScope.onDraw() {
drawRect(Color.Red)
}
}
Alexander Maryanovsky
07/08/2024, 8:12 PMAlexander Maryanovsky
07/08/2024, 8:19 PMApplicationScope.Tray
into your app, and adding a click listener to it, like so:
fun ApplicationScope.Tray(
icon: Painter,
state: TrayState = rememberTrayState(),
tooltip: String? = null,
onAction: () -> Unit = {},
onClick: () -> Unit = {},
menu: @Composable MenuScope.() -> Unit = {}
) {
...
val currentOnAction by rememberUpdatedState(onAction)
val currentOnClick by rememberUpdatedState(onClick)
...
val tray = remember {
TrayIcon(awtIcon).apply {
isImageAutoSize = true
addActionListener {
currentOnAction()
}
addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
currentOnClick()
}
})
}
}
...
}
Aru
07/08/2024, 8:24 PMAru
07/08/2024, 8:29 PMonAction
. But when I actually press the trackpad with two fingers, it triggered the onAction
.
I don’t know why tapping with two fingers did not trigger the action, but pressing with two fingers did, while everywhere else I do two finger tap for right click. May be that’s not an issue with Compose and a java issue? I don’t know.Aru
07/08/2024, 8:29 PMMarcin Wisniowski
07/10/2024, 10:10 AMTray
implementation doesn't consistently work cross-platform. For menus, they look really bad on Windows and Linux, and having a click action, you will find doesn't work on all OS either (I think it only works on Mac).
The Toolbox app was my first thought as well – it seems to do it after all. It's not open source, but looking through the files you will find it uses it's own custom library for the tray icon, which turns out is available online: https://github.com/kropp/java-statusnotifier
But it has no documentation and I wasn't able to get it to work. I don't know if the code on GitHub is outdated. The author (@kropp) did not respond when I asked about it in November, so I assume it's not intended to be used.
I ended up using https://github.com/dorkbox/SystemTray It's not perfect, but it actually works in most cases on all 3 OSes.Alexander Maryanovsky
07/10/2024, 10:41 AMAlexander Maryanovsky
07/10/2024, 10:42 AMThe built-inThe click action as I described above doesn’t work on Windows?implementation doesn’t consistently work cross-platform. For menus, they look really bad on Windows and Linux, and having a click action, you will find doesn’t work on all OS either (I think it only works on Mac).Tray
kropp
07/10/2024, 10:48 AMjava-statusnotifier
repo – it implements a very limited subset of tray icon features on Linux. There are known missing features there, and in Toolbox app we haven't had resources to implement/fix them all. On Windows and macOS we used platform APIs directly via interop. Again, there's not much to opensource there, as it was just a few lines of code calling system APIs and tailored for the specific use case.
Overall, based on my Toolbox App experience, the tray/menubar icon behavior is very different on different OS (they even have different naming for that thingy), and on multitude implementations on Linux makes a true cross-platform solution a very hard task.Marcin Wisniowski
07/10/2024, 11:46 AMonAction
correctly
- Right click opens a menu, but the menu items cannot have icons, and the menu looks terrible. The menu appears on a different monitor than the icon.
On Windows 11:
- Icon displays at a lower resolution
- Icon tooltip shows correct text
- Left click does nothing
- Double click fires onAction
- Right click opens a menu, but the menu items cannot have icons, and the menu looks outdated (but not as bad as on Linux)
On macOS:
- Icon displays at a lower resolution
- No tooltips
- Left click open a menu, but the menu items cannot have icons
- Right click fires onAction
correctly
When using the SystemTray library, there is a different set of tradeoffs, but overall it's much better:
On Linux (KDE):
- Icon displays correctly
- Icon tooltip shows correct text
- Both left click and right click open the menu. No action possible.
- The menu can have icons and styling
On macOS:
- Icon displays correctly
- No tooltips
- Left click opens a menu, menu items can have icons
- Right click throws an exception (catch to do nothing)
On Windows 11:
- Icon displays in full resolution, but is a little blurry instead.
- Icon tooltip shows correct text
- Both left click and right click open the menu. No action possible.
- The menu can have icons and stylingMarcin Wisniowski
07/10/2024, 11:47 AMTray
Marcin Wisniowski
07/10/2024, 11:47 AMTray
Marcin Wisniowski
07/10/2024, 11:47 AMSystemTray
Marcin Wisniowski
07/10/2024, 11:54 AMAlexander Maryanovsky
07/10/2024, 11:55 AMrob42
08/20/2024, 4:42 PMrob42
08/20/2024, 4:43 PMTray()
composable that responds to mouse events: https://gist.github.com/iamcalledrob/9f3b35955e6650365314703fee3c781arob42
08/20/2024, 4:44 PMMarcin Wisniowski
08/20/2024, 5:08 PMrob42
08/21/2024, 8:57 AMMarcin Wisniowski
08/21/2024, 8:58 AMrob42
08/21/2024, 8:59 AMWindow(transparent = true) {}
is non-functional on linux?Marcin Wisniowski
08/21/2024, 9:01 AMMarcin Wisniowski
08/21/2024, 9:02 AMrob42
08/21/2024, 9:08 AMrob42
08/21/2024, 9:13 AMMarcin Wisniowski
08/21/2024, 9:15 AMrob42
08/21/2024, 9:16 AMval gc = window.peer.getAppropriateGraphicsConfiguration(window.graphicsConfiguration);
window.graphicsConfiguration = gc
Marcin Wisniowski
08/21/2024, 9:16 AMrob42
08/21/2024, 9:19 AMOh interesting, I will try a JDK 22 to see if it's fixed.Would love to know too if you end up testing this
Marcin Wisniowski
08/21/2024, 10:42 AM[SKIKO] warn: Failed to create Skia OpenGL context!
java.lang.RuntimeException: Can't wrap nullptr
[SKIKO] warn: Exception in draw scope
org.jetbrains.skiko.RenderException: Cannot init graphic context
and Compose switches to software rendering, making everything very slow.rob42
08/21/2024, 10:55 AMMarcin Wisniowski
08/21/2024, 10:57 AMrob42
08/21/2024, 10:59 AMrob42
08/21/2024, 10:59 AMMarcin Wisniowski
08/21/2024, 11:13 AMMarcin Wisniowski
08/21/2024, 11:14 AMMarcin Wisniowski
08/21/2024, 11:21 AMrob42
08/21/2024, 2:07 PM