Skip to content

Commit

Permalink
Add post 2023-05-01-issue1645-3.md
Browse files Browse the repository at this point in the history
  • Loading branch information
purejava committed May 17, 2023
1 parent 363c364 commit 78864a6
Showing 1 changed file with 122 additions and 0 deletions.
122 changes: 122 additions & 0 deletions _posts/2023-05-01-issue1645-3.md
@@ -0,0 +1,122 @@
---
title: Implementing Tray Icon for Common Linux Environments - final part
date: 2023-05-01 14:45:00 +/-0000
categories: [Java, FFI]
tags: [coding] # TAG names should always be lowercase
---
Cryptomator issue #1645

Please find the first post of this story [here](https://blog.purejava.org/posts/issue1645/).
# Some revisions and changes
## Changed icons
The [feed back](https://github.com/cryptomator/cryptomator/pull/2862) for the first PR I submitted included the request to use icons provided by the **Cryptomator** project, so I included these.
## Different image data handling
Furthermore the devs wished, that the widening of the `integrations-*` API should implement an [**URI**](https://download.java.net/java/early_access/panama/docs/api/java.base/java/net/URI.html) parameter, instead of adding the String. And in this case transporting the image as a byte array can be omitted, as URIs do support direct data transportation via the data scheme and file paths can be specified by the file scheme:

```diff
From 17fbf493eace2e32cec3658fafab98d7d9311e37 Mon Sep 17 00:00:00 2001
From: Ralph Plawetzki <ralph@purejava.org>
Date: Sun, 23 Apr 2023 08:15:09 +0200
Subject: [PATCH 3/3] Change API to support svg icons

---
.../integrations/tray/TrayMenuController.java | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/cryptomator/integrations/tray/TrayMenuController.java b/src/main/java/org/cryptomator/integrations/tray/TrayMenuController.java
index 85f8c63..5cdd413 100644
--- a/src/main/java/org/cryptomator/integrations/tray/TrayMenuController.java
+++ b/src/main/java/org/cryptomator/integrations/tray/TrayMenuController.java
@@ -3,8 +3,7 @@
import org.cryptomator.integrations.common.IntegrationsLoader;
import org.jetbrains.annotations.ApiStatus;

-import java.io.IOException;
-import java.io.InputStream;
+import java.net.URI;
import java.util.List;
import java.util.Optional;

@@ -23,20 +22,20 @@ static Optional<TrayMenuController> get() {
/**
* Displays an icon on the system tray.
*
- * @param imageData What image to show
+ * @param imageUri What image to show
* @param defaultAction Action to perform when interacting with the icon directly instead of its menu
* @param tooltip Text shown when hovering
* @throws TrayMenuException thrown when adding the tray icon failed
*/
- void showTrayIcon(byte[] imageData, Runnable defaultAction, String tooltip) throws TrayMenuException;
+ void showTrayIcon(URI imageUri, Runnable defaultAction, String tooltip) throws TrayMenuException;

/**
* Updates the icon on the system tray.
*
- * @param imageData What image to show
+ * @param imageUri What image to show
* @throws IllegalStateException thrown when called before an icon has been added
*/
- void updateTrayIcon(byte[] imageData);
+ void updateTrayIcon(URI imageUri);

/**
* Show the given options in the tray menu.

```
## As proposed: JDK 19 -> JDK 20
The final step was to migrate my implementation to **JDK 20**.
This required code changes, as the FFI has changed with **JDK 20** ([JEP 434](https://openjdk.org/projects/jdk/20/)). `MemorySession` was split into `Arena` and `SegmentScope` to promote sharing of segments across maintenance boundaries:

```diff
diff --git a/src/main/java/org/cryptomator/ui/traymenu/AppindicatorTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AppindicatorTrayMenuController.java
index 8f8e7653f3..4be9b690f9 100644
--- a/src/main/java/org/cryptomator/ui/traymenu/AppindicatorTrayMenuController.java
+++ b/src/main/java/org/cryptomator/ui/traymenu/AppindicatorTrayMenuController.java
@@ -13,8 +13,8 @@
import org.slf4j.LoggerFactory;

import java.io.File;
-import java.lang.foreign.MemoryAddress;
-import java.lang.foreign.MemorySession;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SegmentScope;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;
@@ -27,9 +27,9 @@ public class AppindicatorTrayMenuController implements TrayMenuController {

private static final Logger LOG = LoggerFactory.getLogger(AppindicatorTrayMenuController.class);

- private final MemorySession session = MemorySession.openShared();
- private MemoryAddress indicator;
- private MemoryAddress menu = gtk_menu_new();
+ private final SegmentScope scope = SegmentScope.auto();
+ private MemorySegment indicator;
+ private MemorySegment menu = gtk_menu_new();

@CheckAvailability
public static boolean isAvailable() {
@@ -64,7 +64,7 @@ public void onBeforeOpenMenu(Runnable runnable) {

}

- private void addChildren(MemoryAddress menu, List<TrayMenuItem> items) {
+ private void addChildren(MemorySegment menu, List<TrayMenuItem> items) {
for (var item : items) {
// TODO: use Pattern Matching for switch, once available
if (item instanceof ActionItem a) {
@@ -72,7 +72,7 @@ private void addChildren(MemoryAddress menu, List<TrayMenuItem> items) {
gtk_menu_item_set_label(gtkMenuItem, MemoryAllocator.ALLOCATE_FOR(a.title()));
g_signal_connect_object(gtkMenuItem,
MemoryAllocator.ALLOCATE_FOR("activate"),
- MemoryAllocator.ALLOCATE_CALLBACK_FOR(new ActionItemCallback(a), session),
+ MemoryAllocator.ALLOCATE_CALLBACK_FOR(new ActionItemCallback(a), scope),
menu,
0);
gtk_menu_shell_append(menu, gtkMenuItem);
```
# Review pending
All coding was submitted as two PRs, that are awaiting their review:
- [cryptomator/cryptomator#2885](https://github.com/cryptomator/cryptomator/pull/2885)
- [cryptomator/integrations-linux#18](https://github.com/cryptomator/integrations-linux/pull/18)

0 comments on commit 78864a6

Please sign in to comment.