diff --git a/scripts/build.number b/scripts/build.number index 3c2b221..faa6583 100644 --- a/scripts/build.number +++ b/scripts/build.number @@ -1,3 +1,3 @@ #Build Number for ANT. Do not edit! -#Wed Feb 21 00:06:44 EST 2024 -build.number=603 +#Fri Mar 01 15:00:52 EST 2024 +build.number=604 diff --git a/src/java/net/i2p/i2pfirefox/I2PBrowser.java b/src/java/net/i2p/i2pfirefox/I2PBrowser.java index 3b42532..99d931f 100644 --- a/src/java/net/i2p/i2pfirefox/I2PBrowser.java +++ b/src/java/net/i2p/i2pfirefox/I2PBrowser.java @@ -203,6 +203,22 @@ public class I2PBrowser extends I2PGenericUnsafeBrowser { */ public void launch() { launch(false); } + /** + * Stop all running processes managed by the browser manager. + * + * @return true if successful, false if not + */ + public boolean stop() { + boolean r = true; + if (i2pFirefox != null) + r = i2pFirefox.stop(); + if (i2pChromium != null) + r = i2pChromium.stop(); + if (i2pGeneral != null) + r = i2pGeneral.stop(); + return r; + } + private String ValidURL(String inUrl) { String[] schemes = {"http", "https"}; for (String scheme : schemes) { diff --git a/src/java/net/i2p/i2pfirefox/I2PChromium.java b/src/java/net/i2p/i2pfirefox/I2PChromium.java index 49c23f6..cb4d0e1 100644 --- a/src/java/net/i2p/i2pfirefox/I2PChromium.java +++ b/src/java/net/i2p/i2pfirefox/I2PChromium.java @@ -764,6 +764,19 @@ public class I2PChromium extends I2PChromiumProfileUnpacker { */ public void launch() { launch(false); } + /** + * Stop all running processes managed by the browser manager. + * + * @return true if successful, false if not + */ + public boolean stop() { + if (p != null) { + p.destroy(); + return true; + } + return false; + } + private String ValidURL(String inUrl) { String[] schemes = {"http", "https"}; for (String scheme : schemes) { diff --git a/src/java/net/i2p/i2pfirefox/I2PFirefox.java b/src/java/net/i2p/i2pfirefox/I2PFirefox.java index e7f20fe..890d3b9 100644 --- a/src/java/net/i2p/i2pfirefox/I2PFirefox.java +++ b/src/java/net/i2p/i2pfirefox/I2PFirefox.java @@ -827,6 +827,19 @@ public class I2PFirefox extends I2PFirefoxProfileUnpacker { */ public void launch() { launch(false); } + /** + * Stop all running processes managed by the browser manager. + * + * @return true if successful, false if not + */ + public boolean stop() { + if (process != null) { + process.destroy(); + return true; + } + return false; + } + private String ValidURL(String inUrl) { String[] schemes = {"http", "https"}; for (String scheme : schemes) { diff --git a/src/java/net/i2p/i2pfirefox/I2PGenericUnsafeBrowser.java b/src/java/net/i2p/i2pfirefox/I2PGenericUnsafeBrowser.java index bae412d..e48a116 100644 --- a/src/java/net/i2p/i2pfirefox/I2PGenericUnsafeBrowser.java +++ b/src/java/net/i2p/i2pfirefox/I2PGenericUnsafeBrowser.java @@ -404,6 +404,18 @@ public class I2PGenericUnsafeBrowser extends I2PCommonBrowser { } } } + /** + * Stop all running processes managed by the browser manager. + * + * @return true if successful, false if not + */ + public boolean stop() { + if (p != null) { + p.destroy(); + return true; + } + return false; + } private String ValidURL(String inUrl) { String[] schemes = {"http", "https"}; diff --git a/src/plugin/net/i2p/i2pfirefox/plugin/plugin/I2PBrowserPlugin.java b/src/plugin/net/i2p/i2pfirefox/plugin/plugin/I2PBrowserPlugin.java index c3d2b31..d72ab8a 100644 --- a/src/plugin/net/i2p/i2pfirefox/plugin/plugin/I2PBrowserPlugin.java +++ b/src/plugin/net/i2p/i2pfirefox/plugin/plugin/I2PBrowserPlugin.java @@ -1,9 +1,16 @@ package net.i2p.i2pfirefox.plugin; -import net.i2p.i2pfirefox.I2PBrowser; +import java.awt.GraphicsEnvironment; +import net.i2p.I2PAppContext; import net.i2p.app.ClientApp; import net.i2p.app.ClientAppState; - +import net.i2p.app.MenuCallback; +import net.i2p.app.MenuHandle; +import net.i2p.app.MenuService; +import net.i2p.desktopgui.ExternalMain; +import net.i2p.i2pfirefox.I2PBrowser; +import net.i2p.util.I2PAppThread; +import net.i2p.util.SystemVersion; /** * I2PBrowserPlugin.java * Copyright (C) 2022 idk @@ -23,19 +30,117 @@ import net.i2p.app.ClientAppState; * @since 0.0.16 */ public class I2PBrowserPlugin extends I2PBrowser implements ClientApp { - public String getDisplayName() { - return "I2P Browser"; + private final I2PAppContext _context = new I2PAppContext(); + private static final String PROP_DTG_ENABLED = "desktopgui.enabled"; + private final I2PBrowser i2pBrowser = new I2PBrowser(); + public String getDisplayName() { return "I2P Browser"; } + public String getName() { return "I2P Browser"; } + public ClientAppState getState() { return ClientAppState.RUNNING; } + public void shutdown(String[] args) {} + public void startup() { + try { + String url = "http://proxy.i2p"; + System.out.println( + "Starting I2P Browser tray manager by testing http://proxy.i2p"); + MenuService dtg = startTrayApp(); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + i2pBrowser.launch(false, new String[] {url}); + if (dtg != null) { + dtg.addMenu("Launch I2P Browser", new Starter(dtg)); + dtg.addMenu("Quit I2P Browser", new Stopper(dtg)); + } + } catch (Exception e) { + e.printStackTrace(); } - public String getName() { - return "I2P Browser"; - } - public ClientAppState getState() { - return ClientAppState.RUNNING; - } - public void shutdown(String[] args) { + } + // Copied directly from I2PSnark-standalone + private MenuService startTrayApp() { + try { + if (isSystrayEnabled(_context)) { + System.setProperty("java.awt.headless", "false"); + ExternalMain dtg = + new ExternalMain(_context, _context.clientAppManager(), null); + dtg.startup(); + return dtg; + } + } catch (Throwable t) { + t.printStackTrace(); } - public void startup() { - + return null; + } + + // Copied directly from I2PSnark-standalone where it is used to determine + // whether to launch the tray app Our environment should basically never be + // headless, that doesn't make any sense, but something tells me I should + // leave that check in. + private static boolean isSystrayEnabled(I2PAppContext context) { + if (GraphicsEnvironment.isHeadless()) + return false; + // default false except on OSX and Windows, + // and on Linux KDE and LXDE. + // Xubuntu XFCE works but doesn't look very good + // Ubuntu Unity was far too buggy to enable + // Ubuntu GNOME does not work, SystemTray.isSupported() returns false + String xdg = System.getenv("XDG_CURRENT_DESKTOP"); + boolean dflt = SystemVersion.isWindows() || SystemVersion.isMac() || + //"XFCE".equals(xdg) || + "KDE".equals(xdg) || "LXDE".equals(xdg); + return context.getProperty(PROP_DTG_ENABLED, dflt); + } + + /** + * Callback when Start I2PBrowser is clicked in systray + * @since 0.9.61 + */ + public class Starter implements MenuCallback { + private final MenuService _ms; + public Starter(MenuService ms) { _ms = ms; } + public void clicked(MenuHandle menu) { + _ms.disableMenu(menu); + _ms.updateMenu("I2PBrowser-Launcher starting", menu); + Thread t = new I2PAppThread(new StarterThread(), + "I2PBrowser-Launcher start", true); + t.start(); } + } + + /** + * Threaded startup + * @since 0.9.61 + */ + public class StarterThread implements Runnable { + public void run() { + i2pBrowser.launch(false); + } + } + + /** + * Callback when Stop I2PBrowser is clicked in systray + * @since 0.9.61 + */ + public class Stopper implements MenuCallback { + private final MenuService _ms; + public Stopper(MenuService ms) { _ms = ms; } + public void clicked(MenuHandle menu) { + _ms.disableMenu(menu); + _ms.updateMenu("I2PBrowser-Launcher stopping", menu); + Thread t = new I2PAppThread(new StopperThread(), + "I2PBrowser-Launcher stop", true); + t.start(); + } + } + + /** + * Threaded startup + * @since 0.9.61 + */ + public class StopperThread implements Runnable { + public void run() { + //i2pBrowser + } + } } \ No newline at end of file