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 <Adam@sigterm.info>
This commit is contained in:
James Carroll
2020-02-14 18:22:04 +00:00
committed by Adam
parent abf055c9b8
commit 5813750cd2
3 changed files with 88 additions and 44 deletions

View File

@@ -28,11 +28,9 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.Desktop;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.concurrent.ScheduledExecutorService; 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.ImageCapture;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text; import net.runelite.client.util.Text;
import net.runelite.client.util.LinkBrowser;
@PluginDescriptor( @PluginDescriptor(
name = "Screenshot", name = "Screenshot",
@@ -188,14 +187,7 @@ public class ScreenshotPlugin extends Plugin
.<String, Runnable>builder() .<String, Runnable>builder()
.put("Open screenshot folder...", () -> .put("Open screenshot folder...", () ->
{ {
try LinkBrowser.open(SCREENSHOT_DIR.toString());
{
Desktop.getDesktop().open(SCREENSHOT_DIR);
}
catch (IOException ex)
{
log.warn("Error opening screenshot dir", ex);
}
}) })
.build()) .build())
.build(); .build();

View File

@@ -28,7 +28,6 @@ import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Desktop;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
@@ -141,14 +140,7 @@ public class FatalErrorDialog extends JDialog
addButton("Open logs folder", () -> addButton("Open logs folder", () ->
{ {
try LinkBrowser.open(RuneLite.LOGS_DIR.toString());
{
Desktop.getDesktop().open(RuneLite.LOGS_DIR);
}
catch (IOException e)
{
log.warn("Unable to open logs", e);
}
}); });
addButton("Get help on Discord", () -> LinkBrowser.browse(RuneLiteProperties.getDiscordInvite())); addButton("Get help on Discord", () -> LinkBrowser.browse(RuneLiteProperties.getDiscordInvite()));
addButton("Troubleshooting steps", () -> LinkBrowser.browse(RuneLiteProperties.getTroubleshootingLink())); addButton("Troubleshooting steps", () -> LinkBrowser.browse(RuneLiteProperties.getTroubleshootingLink()));

View File

@@ -28,6 +28,7 @@ import com.google.common.base.Strings;
import java.awt.Desktop; import java.awt.Desktop;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@@ -37,7 +38,7 @@ import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* Utility class used for browser navigation * Utility class used for web and file browser navigation
*/ */
@Singleton @Singleton
@Slf4j @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 * 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. * 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)) if (attemptDesktopBrowse(url))
{ {
log.debug("Opened browser through Desktop#browse to {}", url); log.debug("Opened url through Desktop#browse to {}", url);
return true; return;
} }
if (shouldAttemptXdg && attemptXdgOpen(url)) if (shouldAttemptXdg && attemptXdgOpen(url))
{ {
log.debug("Opened browser through xdg-open to {}", url); log.debug("Opened url through xdg-open to {}", url);
return true; return;
} }
showMessageBox("Unable to open link. Press 'OK' and link will be copied to your clipboard.", url); log.warn("LinkBrowser.browse() could not open {}", url);
return false; 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 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(); exec.waitFor();
final int ret = exec.exitValue(); final int ret = exec.exitValue();
@@ -87,7 +121,7 @@ public class LinkBrowser
return true; return true;
} }
log.warn("xdg-open {} returned with error code {}", url, ret); log.warn("xdg-open {} returned with error code {}", resource, ret);
return false; return false;
} }
catch (IOException ex) catch (IOException ex)
@@ -98,7 +132,7 @@ public class LinkBrowser
} }
catch (InterruptedException ex) 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; return false;
} }
} }
@@ -124,7 +158,33 @@ public class LinkBrowser
} }
catch (IOException | URISyntaxException ex) 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; return false;
} }
} }