-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
util.Desktop lacks cross-platform open file in default editor action #94
Comments
I can confirm that I have a similar problem on Windows 10 when trying to open the log file. Also the Windows 10 menu looks worse from the one provided by AWT. May be switching to that would be better? Or at least having the option to prefer one or the other? |
I tried playing around with FORCE_GTK2 and the TrayType options but nothing really did what I wanted. Here is my workaround which seems to do the job: if( SystemUtils.IS_OS_LINUX ) {
Desktop.browseURL( LOG_FILE_PATH );
} else {
// Windows and Mac OS X
java.awt.Desktop.getDesktop().open( new File( LOG_FILE_PATH ) );
} |
You're using an out of date version. The project has moved (hence the note in the read me), can you try the latest?
|
@dorkbox, I am using 3.16. Sorry I opened this issue in the old project, but I am using the latest release. In build.gradle I have this line: compile 'com.dorkbox:SystemTray:+' which resolves to 3.16. |
:) Ah, ok! I'll see what's going on, and add what you've got since these sorts of checks is 99% of what my stuff does.... :/ |
May be you'll need to add a third option Desktop.openFile() that would open the file in the default editor/viewer. Basically I would go with mimicking the functionality of the Java AWT Desktop class. |
I can't speak on behalf of the Gtk conflicts, but for browsing a directory: private static final String OS_NAME = System.getProperty("os.name").toLowerCase();
/**
* Opens the specified path in the system-default file browser. Works around several OS limitations:
* - Apple tries to launch <code>.app</code> bundle directories as applications rather than browsing contents
* - Linux has mixed support for <code>Desktop.getDesktop()</code>. Adds <code>xdg-open</code> fallback.
* @param path The directory to browse
* @throws IOException
*/
public static void browseDirectory(String path) throws IOException {
File directory = new File(path);
if (isMac() && path.endsWith(".app")) {
// Mac tries to open the .app rather than browsing it. Instead, pass a child with -R to select it in finder
File[] files = directory.listFiles();
if (files.length > 0) {
// Get first child
File child = directory.listFiles()[0];
if (execute(new String[] {"open", "-R", child.getCanonicalPath()})) {
return;
}
}
} else {
try {
// The default, java recommended usage
Desktop d = Desktop.getDesktop();
d.open(directory);
return;
} catch (IOException io) {
if (isLinux()) {
// Fallback on xdg-open for Linux
if (execute(new String[] {"xdg-open", path})) {
return;
}
}
throw io;
}
}
throw new IOException("Unable to open " + path);
}
/**
* Executes a synchronous shell command and returns true if the {@code Process.exitValue()} is {@code 0}.
*
* @param commandArray array of command pieces to supply to the shell environment to e executed as a single command
* @return {@code true} if {@code Process.exitValue()} is {@code 0}, otherwise {@code false}.
*/
public static boolean execute(String[] commandArray) {
log.debug("Executing: {}", Arrays.toString(commandArray));
try {
// Create and execute our new process
Process p = Runtime.getRuntime().exec(commandArray, envp);
p.waitFor();
return p.exitValue() == 0;
}
catch(InterruptedException ex) {
log.warn("InterruptedException waiting for a return value: {} envp: {}", Arrays.toString(commandArray), Arrays.toString(envp), ex);
}
catch(IOException ex) {
log.error("IOException executing: {} envp: {}", Arrays.toString(commandArray), Arrays.toString(envp), ex);
}
return false;
}
/**
* Determine if the current Operating System is Linux
*
* @return {@code true} if Linux, {@code false} otherwise
*/
public static boolean isLinux() {
return (OS_NAME.contains("linux"));
}
/**
* Determine if the current Operating System is Mac OS
*
* @return {@code true} if Mac OS, {@code false} otherwise
*/
public static boolean isMac() {
return (OS_NAME.contains("mac"));
} Opening a file on Mac should be a very similar call to the one above. @stanimirivanovde on a side note, we're considering abandoning Dorkbox because of Linux's completely abandonment of the system tray (#71). We too have Mac and Windows working fine without this library. We're going to try using Steam's technique instead (which has serious limitations, but if successful, we'll just adapt our interface instead). |
@tresf, thanks for the note. I actually like how the dorkbox.SystemTray looks on Mac OS X. It has the shortcut keys next to the menu items like a native app. But the Windows 10 version is very Java looking so I switched that to the Java AWT SystemTray and now it looks native. I'll keep this for Ubuntu and Mac OS X for now and try to work around the limitations. I didn't know Ubuntu is pushing away from the SystemTray functionality. It is such a standard thing that I expect it to be there for most OS GUIs. |
@dorkbox, thanks for looking into this issue. I hope this is helpful for improving the library. |
That's AWT as well, no? That's how I've been doing it in my app at least. Looks great on Mac. |
@tresf, you're right. I just tested it and shortcuts work well with AWT on Mac OS X. I didn't pay attention to java.awt.MenuShortcut. Thanks for the tip. |
Version 3.17 is now released, and have fixed this. Additionally, there is support now for Ubuntu 17.10, 18.04, Fedora 27, 28, 29, and Debian 9.5 (+ all DE's possible from it's installer, so Gnome3, KDE, Xfce, LXDE, and MATE). |
I need to open a file in the default editor for the user (a log file), but the dorkbox.util.Desktop abstraction doesn't support open, just browseURL() and browseDirectory(). browseURL() fails to open the file on Mac OS X but it works fine on Ubuntu. It fails on Mac OS X with the following message:
Prior to this I used Java's AWT Desktop instance and it has an open function: Desktop.getDesktop().open(logFile) which works well on Mac OS X and Windows 7 and 10. Actually the reason I use dorkbox's SystemTray is so I can have a system tray on Ubuntu.
But if I keep the AWT Desktop instance the whole application crashes on Ubuntu with the following message:
Apparently the AWT and the dorkbox SystemTray need different GTK versions.
I need a cross-platform way to open a file similar to what you have with Desktop.browseURL() and Desktop.browseDirectory().
The text was updated successfully, but these errors were encountered: