Skip to content

Commit e833406

Browse files
committed
Track implementation plan and remaining work
1 parent cc463f7 commit e833406

File tree

3 files changed

+943
-0
lines changed

3 files changed

+943
-0
lines changed

NEXT.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Next Steps: SciJava Desktop Integration
2+
3+
This document outlines the remaining work for the scijava-desktop component.
4+
5+
## Overview
6+
7+
scijava-desktop provides unified desktop integration for SciJava applications, managing:
8+
1. **URI link scheme registration & handling** (Linux, Windows, macOS)
9+
2. **Desktop icon generation** (Linux .desktop file, Windows Start Menu - planned)
10+
3. **File extension registration** (planned)
11+
12+
The component uses a plugin system where Platform implementations (LinuxPlatform, WindowsPlatform, MacOSPlatform) handle platform-specific integration.
13+
14+
## Current Status
15+
16+
### ✅ Implemented
17+
- URI link handling system (LinkService, LinkHandler interface)
18+
- Platform-specific URI scheme registration (Windows Registry, Linux .desktop files)
19+
- Desktop icon management for Linux
20+
- DesktopIntegrationProvider interface for platform capabilities
21+
- OptionsDesktop plugin for user preferences (Edit > Options > Desktop...)
22+
- Platform plugins for Linux, Windows, and macOS
23+
24+
### ⚠️ Partially Implemented (Needs Fixes)
25+
- **Hardcoded scheme names**: WindowsPlatform:86,102 and LinuxPlatform:112,129 hardcode "fiji" scheme
26+
- **Hardcoded OS checks**: DefaultLinkService:119-132 directly checks OS name strings and instantiates platform-specific installers
27+
28+
### ❌ Not Yet Implemented
29+
- File extension registration
30+
- Windows Start Menu icon generation
31+
- First launch dialog for desktop integration opt-in
32+
- SchemeInstallerProvider interface for platforms
33+
34+
## Priority Work Items
35+
36+
### 1. Remove Hardcoded Scheme Names
37+
38+
**Problem**: Both Windows and Linux platforms hardcode the "fiji" scheme instead of querying registered LinkHandlers.
39+
40+
**Files to modify**:
41+
- `src/main/java/org/scijava/desktop/platform/windows/WindowsPlatform.java` (lines 86, 102)
42+
- `src/main/java/org/scijava/desktop/platform/linux/LinuxPlatform.java` (lines 112, 129)
43+
44+
**Solution**: Query LinkService for all registered schemes from LinkHandler plugins.
45+
46+
**Example** (WindowsPlatform.java):
47+
```java
48+
@Override
49+
public boolean isWebLinksEnabled() {
50+
final WindowsSchemeInstaller installer = new WindowsSchemeInstaller(log);
51+
final Set<String> schemes = collectSchemes();
52+
if (schemes.isEmpty()) return false;
53+
54+
// Check if any scheme is installed
55+
for (String scheme : schemes) {
56+
if (installer.isInstalled(scheme)) return true;
57+
}
58+
return false;
59+
}
60+
61+
@Override
62+
public void setWebLinksEnabled(final boolean enable) throws IOException {
63+
final WindowsSchemeInstaller installer = new WindowsSchemeInstaller(log);
64+
final String executablePath = System.getProperty("scijava.app.executable");
65+
if (executablePath == null) {
66+
throw new IOException("No executable path set (scijava.app.executable property)");
67+
}
68+
69+
final Set<String> schemes = collectSchemes();
70+
for (String scheme : schemes) {
71+
if (enable) {
72+
installer.install(scheme, executablePath);
73+
} else {
74+
installer.uninstall(scheme);
75+
}
76+
}
77+
}
78+
79+
private Set<String> collectSchemes() {
80+
final Set<String> schemes = new HashSet<>();
81+
if (linkService == null) return schemes;
82+
83+
for (final LinkHandler handler : linkService.getInstances()) {
84+
schemes.addAll(handler.getSchemes());
85+
}
86+
return schemes;
87+
}
88+
```
89+
90+
Similar changes needed for LinuxPlatform.
91+
92+
### 2. Add SchemeInstallerProvider Interface
93+
94+
**Goal**: Allow platforms to provide SchemeInstaller instances without hardcoding in DefaultLinkService.
95+
96+
**New file**: `src/main/java/org/scijava/desktop/links/SchemeInstallerProvider.java`
97+
98+
```java
99+
package org.scijava.desktop.links;
100+
101+
/**
102+
* Interface for platforms that provide {@link SchemeInstaller} functionality.
103+
* <p>
104+
* Platform implementations can implement this interface to provide
105+
* platform-specific URI scheme installation capabilities.
106+
* </p>
107+
*/
108+
public interface SchemeInstallerProvider {
109+
/**
110+
* Creates a SchemeInstaller for this platform.
111+
*
112+
* @return a SchemeInstaller, or null if not supported
113+
*/
114+
SchemeInstaller getSchemeInstaller();
115+
}
116+
```
117+
118+
**Files to modify**:
119+
- WindowsPlatform.java - implement SchemeInstallerProvider
120+
- LinuxPlatform.java - implement SchemeInstallerProvider
121+
- MacOSPlatform.java - implement SchemeInstallerProvider (return null)
122+
123+
### 3. Refactor DefaultLinkService#createInstaller()
124+
125+
**Problem**: Hardcoded OS checks violate the plugin architecture.
126+
127+
**Current code** (lines 119-132):
128+
```java
129+
private SchemeInstaller createInstaller() {
130+
final String os = System.getProperty("os.name");
131+
if (os == null) return null;
132+
133+
final String osLower = os.toLowerCase();
134+
if (osLower.contains("linux")) {
135+
return new LinuxSchemeInstaller(log);
136+
}
137+
else if (osLower.contains("win")) {
138+
return new WindowsSchemeInstaller(log);
139+
}
140+
141+
return null;
142+
}
143+
```
144+
145+
**Refactored code**:
146+
```java
147+
@Parameter(required = false)
148+
private PlatformService platformService;
149+
150+
private SchemeInstaller createInstaller() {
151+
if (platformService == null) return null;
152+
153+
final Platform platform = platformService.platform();
154+
if (platform instanceof SchemeInstallerProvider) {
155+
return ((SchemeInstallerProvider) platform).getSchemeInstaller();
156+
}
157+
158+
return null;
159+
}
160+
```
161+
162+
### 4. First Launch Dialog (Optional)
163+
164+
**Goal**: Prompt user on first launch to enable desktop integration.
165+
166+
**Implementation approach**:
167+
- Add `DesktopIntegrationService` to track first launch
168+
- Publish `DesktopIntegrationPromptEvent` on first run
169+
- Application (Fiji) can listen and show dialog
170+
171+
**Dialog content**:
172+
```
173+
Would you like to integrate [App Name] into your desktop?
174+
175+
If you say Yes, I will:
176+
- Add a [App Name] desktop icon
177+
- Add [App Name] as a handler for supported file types
178+
- Allow [App Name] to handle [scheme]:// web links
179+
180+
Either way: "To change these settings in the future, use Edit > Options > Desktop..."
181+
```
182+
183+
**Implementation notes**:
184+
- Use `appService.getApp().getTitle()` for `[App Name]` to keep it generic
185+
- Collect schemes from all `LinkHandler` plugins to populate `[scheme]://`
186+
- Show this dialog only on first launch (track via preferences)
187+
- Provide "Yes" and "No" options
188+
- If user selects "Yes", enable all available desktop integration features
189+
- If user selects "No", do nothing
190+
- Store user preference by writing to a local configuration file -- avoids showing dialog again
191+
192+
### 5. File Extension Registration (Future)
193+
194+
**Scope**: Extend DesktopIntegrationProvider to support file type associations.
195+
196+
**New methods**:
197+
```java
198+
boolean isFileExtensionsEnabled();
199+
boolean isFileExtensionsToggleable();
200+
void setFileExtensionsEnabled(boolean enable) throws IOException;
201+
```
202+
203+
**Platform implementations**:
204+
- **Linux**: Add MIME types to .desktop file (e.g., `image/tiff`, `application/x-imagej-macro`)
205+
- **Windows**: Register file associations in Registry under `HKCU\Software\Classes\.<ext>`
206+
- **macOS**: Declared in Info.plist (build-time, read-only)
207+
208+
### 6. Windows Start Menu Icon
209+
210+
**Goal**: Add desktop icon support for Windows.
211+
212+
**Implementation**:
213+
- Create Start Menu shortcut (.lnk file) in `%APPDATA%\Microsoft\Windows\Start Menu\Programs`
214+
- Use JNA or native executable to create shortcuts
215+
- Update WindowsPlatform.isDesktopIconToggleable() to return true
216+
217+
## Testing Checklist
218+
219+
- [ ] Test URI scheme registration on Windows (registry manipulation)
220+
- [ ] Test URI scheme registration on Linux (.desktop file updates)
221+
- [ ] Test desktop icon installation on Linux
222+
- [ ] Verify macOS reports correct read-only status
223+
- [ ] Test OptionsDesktop UI with multiple schemes
224+
- [ ] Verify scheme collection from LinkHandler plugins
225+
- [ ] Test toggling features on/off via UI
226+
- [ ] Verify no hardcoded "fiji" references remain
227+
228+
## System Properties Reference
229+
230+
- `scijava.app.executable` - Path to application executable (required for all platforms)
231+
- `scijava.app.name` - Application name (defaults to "SciJava Application")
232+
- `scijava.app.icon` - Icon path (Linux only)
233+
- `scijava.app.directory` - Working directory (Linux only)
234+
- `scijava.app.desktop-file` - Override .desktop file path (Linux only)
235+
236+
## Documentation Updates Needed
237+
238+
- [ ] Update README.md with current feature status
239+
- [ ] Update doc/WINDOWS.md to reflect generic scheme handling
240+
- [ ] Create doc/LINUX.md documenting .desktop file integration
241+
- [ ] Create doc/MACOS.md explaining Info.plist configuration
242+
- [ ] Add examples of LinkHandler implementation
243+
244+
## Questions to Resolve
245+
246+
1. Should SchemeInstallerProvider be a separate interface or extend Platform?
247+
2. How to handle partial scheme installation failures?
248+
3. Should first launch dialog be mandatory or optional?
249+
4. What file extensions should be supported by default?

0 commit comments

Comments
 (0)