From 5813750cd24ab60096671f2b667c97908d3bf45f Mon Sep 17 00:00:00 2001 From: James Carroll Date: Fri, 14 Feb 2020 18:22:04 +0000 Subject: [PATCH] Thread Desktop browse and open This should allow systems without GVFS to open the logs folder. This applies to the AppImage on non-Gnome or bare bone systems, the raw Jar, and Snap. Co-authored-by: Adam --- .../plugins/screenshot/ScreenshotPlugin.java | 12 +- .../runelite/client/ui/FatalErrorDialog.java | 10 +- .../net/runelite/client/util/LinkBrowser.java | 110 ++++++++++++++---- 3 files changed, 88 insertions(+), 44 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index e5bdce4414..49c46d394e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -28,11 +28,9 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.inject.Provides; -import java.awt.Desktop; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.time.LocalDate; import java.util.concurrent.ScheduledExecutorService; @@ -82,6 +80,7 @@ import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageCapture; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; +import net.runelite.client.util.LinkBrowser; @PluginDescriptor( name = "Screenshot", @@ -188,14 +187,7 @@ public class ScreenshotPlugin extends Plugin .builder() .put("Open screenshot folder...", () -> { - try - { - Desktop.getDesktop().open(SCREENSHOT_DIR); - } - catch (IOException ex) - { - log.warn("Error opening screenshot dir", ex); - } + LinkBrowser.open(SCREENSHOT_DIR.toString()); }) .build()) .build(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FatalErrorDialog.java b/runelite-client/src/main/java/net/runelite/client/ui/FatalErrorDialog.java index 131bbb7830..8563595685 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FatalErrorDialog.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FatalErrorDialog.java @@ -28,7 +28,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; -import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; import java.awt.event.WindowAdapter; @@ -141,14 +140,7 @@ public class FatalErrorDialog extends JDialog addButton("Open logs folder", () -> { - try - { - Desktop.getDesktop().open(RuneLite.LOGS_DIR); - } - catch (IOException e) - { - log.warn("Unable to open logs", e); - } + LinkBrowser.open(RuneLite.LOGS_DIR.toString()); }); addButton("Get help on Discord", () -> LinkBrowser.browse(RuneLiteProperties.getDiscordInvite())); addButton("Troubleshooting steps", () -> LinkBrowser.browse(RuneLiteProperties.getTroubleshootingLink())); diff --git a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java index 194b1974b2..f4bc491571 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java +++ b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java @@ -28,6 +28,7 @@ import com.google.common.base.Strings; import java.awt.Desktop; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; +import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -37,7 +38,7 @@ import javax.swing.SwingUtilities; import lombok.extern.slf4j.Slf4j; /** - * Utility class used for browser navigation + * Utility class used for web and file browser navigation */ @Singleton @Slf4j @@ -48,37 +49,70 @@ public class LinkBrowser /** * Tries to navigate to specified URL in browser. In case operation fails, displays message box with message * and copies link to clipboard to navigate to. - * @param url url to open - * @return true if operation was successful */ - public static boolean browse(final String url) + public static void browse(final String url) { - if (Strings.isNullOrEmpty(url)) + new Thread(() -> { - return false; - } + if (Strings.isNullOrEmpty(url)) + { + log.warn("LinkBrowser.browse() called with invalid input"); + return; + } - if (attemptDesktopBrowse(url)) - { - log.debug("Opened browser through Desktop#browse to {}", url); - return true; - } + if (attemptDesktopBrowse(url)) + { + log.debug("Opened url through Desktop#browse to {}", url); + return; + } - if (shouldAttemptXdg && attemptXdgOpen(url)) - { - log.debug("Opened browser through xdg-open to {}", url); - return true; - } - - showMessageBox("Unable to open link. Press 'OK' and link will be copied to your clipboard.", url); - return false; + if (shouldAttemptXdg && attemptXdgOpen(url)) + { + log.debug("Opened url through xdg-open to {}", url); + return; + } + + log.warn("LinkBrowser.browse() could not open {}", url); + showMessageBox("Unable to open link. Press 'OK' and the link will be copied to your clipboard.", url); + }).start(); } - private static boolean attemptXdgOpen(String url) + /** + * Tries to open a directory in the OS native file manager. + * @param directory directory to open + */ + public static void open(final String directory) + { + new Thread(() -> + { + if (Strings.isNullOrEmpty(directory)) + { + log.warn("LinkBrowser.open() called with invalid input"); + return; + } + + if (attemptDesktopOpen(directory)) + { + log.debug("Opened directory through Desktop#open to {}", directory); + return; + } + + if (shouldAttemptXdg && attemptXdgOpen(directory)) + { + log.debug("Opened directory through xdg-open to {}", directory); + return; + } + + log.warn("LinkBrowser.open() could not open {}", directory); + showMessageBox("Unable to open folder. Press 'OK' and the folder directory will be copied to your clipboard.", directory); + }).start(); + } + + private static boolean attemptXdgOpen(String resource) { try { - final Process exec = Runtime.getRuntime().exec(new String[]{"xdg-open", url}); + final Process exec = Runtime.getRuntime().exec(new String[]{"xdg-open", resource}); exec.waitFor(); final int ret = exec.exitValue(); @@ -87,7 +121,7 @@ public class LinkBrowser return true; } - log.warn("xdg-open {} returned with error code {}", url, ret); + log.warn("xdg-open {} returned with error code {}", resource, ret); return false; } catch (IOException ex) @@ -98,7 +132,7 @@ public class LinkBrowser } catch (InterruptedException ex) { - log.warn("Interrupted while waiting for xdg-open {} to execute", url); + log.warn("Interrupted while waiting for xdg-open {} to execute", resource); return false; } } @@ -124,7 +158,33 @@ public class LinkBrowser } catch (IOException | URISyntaxException ex) { - log.warn("Failed to open Desktop#browser {}", url, ex); + log.warn("Failed to open Desktop#browse {}", url, ex); + return false; + } + } + + private static boolean attemptDesktopOpen(String directory) + { + if (!Desktop.isDesktopSupported()) + { + return false; + } + + final Desktop desktop = Desktop.getDesktop(); + + if (!desktop.isSupported(Desktop.Action.OPEN)) + { + return false; + } + + try + { + desktop.open(new File(directory)); + return true; + } + catch (IOException ex) + { + log.warn("Failed to open Desktop#open {}", directory, ex); return false; } }