Skip to content

Commit cc463f7

Browse files
ctruedenclaude
andcommitted
Implement desktop integrations in Platform plugins
A new DesktopIntegrationProvider interface adds on to Platform plugin functions, enabling them to query and modify the state of desktop-level integrations, including web links support and desktop icon presence. Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent a206217 commit cc463f7

File tree

7 files changed

+907
-156
lines changed

7 files changed

+907
-156
lines changed

README.md

Lines changed: 233 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,267 @@
1+
# scijava-desktop
2+
13
[![Build Status](https://github.com/scijava/scijava-desktop/actions/workflows/build.yml/badge.svg)](https://github.com/scijava/scijava-desktop/actions/workflows/build.yml)
24

3-
This component provides supporting code for SciJava applications
4-
to manage their integration with the system native desktop:
5+
Unified desktop integration for SciJava applications.
56

6-
* SciJava Platform plugins for macOS and Windows
7-
* A links subsystem to handle URI-based links via plugins
7+
## Features
88

9-
The scijava-desktop component requires Java 11 as a minimum, due
10-
to its use of java.awt.Desktop features not present in Java 8.
9+
The scijava-desktop component provides three kinds of desktop integration:
1110

12-
## Features
11+
1. **URI Link Scheme Registration & Handling**
12+
- Register custom URI schemes (e.g., `myapp://`) with the operating system
13+
- Handle URI clicks from web browsers and other applications
14+
- Automatic scheme registration on application startup
15+
16+
2. **Desktop Icon Generation**
17+
- Linux: `.desktop` file creation in application menus
18+
- Windows: Start Menu shortcuts (planned)
19+
- macOS: Application bundle support
20+
21+
3. **File Extension Registration** (planned)
22+
- Associate file types with your application
23+
- Platform-specific MIME type handling
24+
25+
## Platform Support
26+
27+
- **Linux**: Full support for URI schemes and desktop icons via `.desktop` files
28+
- **Windows**: URI scheme registration via Windows Registry (desktop icons planned)
29+
- **macOS**: Read-only support (configuration via Info.plist at build time)
30+
31+
## Requirements
32+
33+
- Java 11 or later (due to use of `java.awt.Desktop` features)
34+
- Platform-specific tools:
35+
- Linux: `xdg-utils` (for `xdg-mime` and `update-desktop-database`)
36+
- Windows: `reg` command (built-in)
37+
- macOS: No runtime dependencies
38+
39+
## Quick Start
1340

14-
- **Link handling**: Register custom handlers for URI schemes through the `LinkHandler` plugin interface
15-
- **CLI integration**: Automatic handling of URI arguments passed on the command line via `ConsoleArgument`
16-
- **OS integration**: Automatic registration of URI schemes with the operating system (Windows supported, macOS/Linux planned)
41+
### 1. Add Dependency
1742

18-
## Usage
43+
```xml
44+
<dependency>
45+
<groupId>org.scijava</groupId>
46+
<artifactId>scijava-desktop</artifactId>
47+
<version><!-- latest version --></version>
48+
</dependency>
49+
```
50+
51+
### 2. Configure System Properties
1952

20-
### Creating a Link Handler
53+
Set these properties when launching your application:
2154

22-
Implement the `LinkHandler` interface to handle custom URI schemes:
55+
```bash
56+
java -Dscijava.app.executable="/path/to/myapp" \
57+
-Dscijava.app.name="My Application" \
58+
-Dscijava.app.icon="/path/to/icon.png" \
59+
-jar myapp.jar
60+
```
61+
62+
### 3. Create a LinkHandler Plugin
2363

2464
```java
65+
package com.example;
66+
67+
import org.scijava.desktop.links.AbstractLinkHandler;
68+
import org.scijava.desktop.links.LinkHandler;
69+
import org.scijava.plugin.Plugin;
70+
71+
import java.net.URI;
72+
import java.util.Arrays;
73+
import java.util.List;
74+
2575
@Plugin(type = LinkHandler.class)
26-
public class MyLinkHandler extends AbstractLinkHandler {
76+
public class MyAppLinkHandler extends AbstractLinkHandler {
2777

2878
@Override
29-
public boolean supports(URI uri) {
79+
public boolean supports(final URI uri) {
3080
return "myapp".equals(uri.getScheme());
3181
}
3282

3383
@Override
34-
public void handle(URI uri) {
35-
// Handle the URI
84+
public void handle(final URI uri) {
85+
// Handle the URI (e.g., open a file, navigate to a view)
3686
System.out.println("Handling: " + uri);
3787
}
3888

3989
@Override
4090
public List<String> getSchemes() {
41-
// Return schemes to register with the OS
91+
// Schemes to register with the OS
4292
return Arrays.asList("myapp");
4393
}
4494
}
4595
```
4696

47-
### OS Registration
97+
### 4. Launch and Test
4898

49-
On Windows, URI schemes returned by `LinkHandler.getSchemes()` are automatically registered
50-
in the Windows Registry when the `LinkService` initializes. This allows users to click
51-
links like `myapp://action` in web browsers or other applications, which will launch your
52-
Java application with the URI as a command-line argument.
99+
1. Start your application
100+
2. The `myapp://` scheme is automatically registered with your OS
101+
3. Click a `myapp://action?param=value` link in your browser
102+
4. Your application launches and handles the URI
53103

54-
The registration uses `HKEY_CURRENT_USER` and requires no administrator privileges.
104+
## Architecture
55105

56-
See [doc/WINDOWS.md](doc/WINDOWS.md) for details.
106+
### Link Handling System
57107

58-
## Architecture
108+
- **LinkService**: Service for routing URIs to appropriate handlers
109+
- **LinkHandler**: Plugin interface for implementing URI handlers
110+
- **LinkArgument**: Console argument plugin for command-line URI handling
111+
- **SchemeInstaller**: Platform-specific OS registration
112+
113+
### Platform Integration
114+
115+
- **Platform Plugins**: LinuxPlatform, WindowsPlatform, MacOSPlatform
116+
- **DesktopIntegrationProvider**: Interface for querying/toggling desktop features
117+
- **OptionsDesktop**: User-facing options plugin (Edit > Options > Desktop...)
118+
119+
### State Management
120+
121+
Desktop integration state is queried directly from the OS (not saved to preferences):
122+
- On load: Query OS for current registration state
123+
- On save: Apply changes directly to OS (e.g. registry, .desktop files)
124+
- Keeps UI in sync with actual OS state
125+
126+
## System Properties
127+
128+
| Property | Description | Platforms | Required |
129+
|----------------------------|--------------------------------|-----------|-----------------------------------------------------------|
130+
| `scijava.app.executable` | Path to application executable | All | Yes (for URI schemes) |
131+
| `scijava.app.name` | Application name | All | No (default: "SciJava") |
132+
| `scijava.app.icon` | Icon path | All | No |
133+
| `scijava.app.directory` | Application directory | All | No |
134+
| `scijava.app.desktop-file` | Override .desktop file path | Linux | No (default: `~/.local/share/applications/<app>.desktop`) |
135+
136+
## User Interface
137+
138+
Users can manage desktop integration via **Edit > Options > Desktop...** in your application:
139+
140+
- **Enable web links**: Register/unregister URI schemes
141+
- **Add desktop icon**: Install/remove application launcher
142+
143+
The UI automatically grays out features that are not available on the current platform.
144+
145+
## Documentation
146+
147+
- [doc/WINDOWS.md](doc/WINDOWS.md) - Windows Registry-based URI scheme registration
148+
149+
## Examples
150+
151+
### Parse URI Components
152+
153+
```java
154+
import org.scijava.desktop.links.Links;
155+
156+
URI uri = new URI("myapp://view/document?id=123&mode=edit");
157+
158+
String operation = Links.operation(uri); // "view"
159+
List<String> pathFragments = Links.pathFragments(uri); // ["view", "document"]
160+
Map<String, String> query = Links.query(uri); // {"id": "123", "mode": "edit"}
161+
```
162+
163+
### Multiple Schemes
164+
165+
```java
166+
@Plugin(type = LinkHandler.class)
167+
public class MultiSchemeLinkHandler extends AbstractLinkHandler {
168+
169+
@Override
170+
public boolean supports(final URI uri) {
171+
String scheme = uri.getScheme();
172+
return "myapp".equals(scheme) || "myapp-dev".equals(scheme);
173+
}
174+
175+
@Override
176+
public void handle(final URI uri) {
177+
if ("myapp-dev".equals(uri.getScheme())) {
178+
// Handle development scheme
179+
} else {
180+
// Handle production scheme
181+
}
182+
}
183+
184+
@Override
185+
public List<String> getSchemes() {
186+
return Arrays.asList("myapp", "myapp-dev");
187+
}
188+
}
189+
```
190+
191+
## Platform-Specific Details
192+
193+
### Linux
194+
195+
URI schemes are registered by:
196+
1. Creating a `.desktop` file in `~/.local/share/applications/`
197+
2. Adding `x-scheme-handler/<scheme>` to the MimeType field
198+
3. Registering with `xdg-mime default <app>.desktop x-scheme-handler/<scheme>`
199+
4. Updating the desktop database with `update-desktop-database`
200+
201+
Desktop icons are created by installing the `.desktop` file with appropriate fields (Name, Exec, Icon, Categories).
202+
203+
### macOS
204+
205+
URI schemes are declared in the application's `Info.plist` file within the `.app` bundle. This is configured at build time (bundle is code-signed and immutable), so runtime registration is not supported.
59206

60-
- `LinkService` - Service for routing URIs to appropriate handlers
61-
- `LinkHandler` - Plugin interface for implementing custom URI handlers
62-
- `LinkArgument` - Console argument plugin that recognizes URIs on the command line
63-
- `SchemeInstaller` - Interface for OS-specific URI scheme registration
64-
- `WindowsSchemeInstaller` - Windows implementation using registry commands
207+
The MacOSPlatform correctly reports read-only status for all desktop integration features.
65208

66-
The launcher should set the `scijava.app.executable` system property to enable URI scheme registration.
209+
### Windows
210+
211+
URI schemes are registered in the Windows Registry under `HKEY_CURRENT_USER\Software\Classes\<scheme>`. No administrator privileges are required.
212+
213+
The registry structure:
214+
```
215+
HKCU\Software\Classes\myapp
216+
(Default) = "URL:myapp"
217+
URL Protocol = ""
218+
shell\open\command\
219+
(Default) = "C:\Path\To\App.exe" "%1"
220+
```
221+
222+
## Known Issues
223+
224+
### Hardcoded Elements (Needs Fixes)
225+
226+
1. **Hardcoded "fiji" scheme**: WindowsPlatform:86,102 and LinuxPlatform:112,129 hardcode the "fiji" scheme instead of querying LinkHandler plugins.
227+
- Impact: Only works for Fiji application
228+
- Fix: See NEXT.md Work Item #1
229+
230+
2. **Hardcoded OS checks**: DefaultLinkService:119-132 directly checks OS name instead of using PlatformService.
231+
- Impact: Violates plugin architecture
232+
- Fix: See NEXT.md Work Items #2 and #3
233+
234+
### Missing Features
235+
236+
- File extension registration
237+
- Windows desktop icon (Start Menu shortcut)
238+
- First launch dialog for opt-in
239+
240+
See [NEXT.md](NEXT.md) for details on planned improvements.
241+
242+
## Manual Testing
243+
244+
**Windows**:
245+
```bash
246+
# Check registry after running your app
247+
regedit
248+
# Navigate to HKCU\Software\Classes\myapp
249+
```
250+
251+
**Linux**:
252+
```bash
253+
# Check .desktop file
254+
cat ~/.local/share/applications/myapp.desktop
255+
256+
# Check MIME associations
257+
xdg-mime query default x-scheme-handler/myapp
258+
```
259+
260+
**Test URI handling**:
261+
```bash
262+
# Linux/macOS
263+
xdg-open "myapp://test"
264+
265+
# Windows
266+
start "myapp://test"
267+
```

0 commit comments

Comments
 (0)