diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index df11bfa846..49b4012ea1 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -342,6 +342,11 @@ public class DesktopLauncher extends ClientLauncher{ //this should never happen unless someone is being dumb with the parameters String[] ext = shownExtensions == null || shownExtensions.length == 0 ? new String[]{""} : shownExtensions; + if(OS.isLinux){ + showZenity(open, formatted, shownExtensions, cons, () -> Platform.defaultFileDialog(open, title, ext[0], cons)); + return; + } + //native file dialog Threads.daemon(() -> { try{ @@ -398,6 +403,61 @@ public class DesktopLauncher extends ClientLauncher{ }); } + + /** attempt to use the native file picker with zenity, or runs the fallback Runnable if the operation fails */ + static void showZenity(boolean open, String title, String[] extensions, Cons cons, Runnable fallback){ + Threads.daemon(() -> { + try{ + String formatted = (title.startsWith("@") ? Core.bundle.get(title.substring(1)) : title).replaceAll("\"", "'"); + + String last = FileChooser.getLastDirectory().absolutePath(); + if(!last.endsWith("/")) last += "/"; + + //zenity doesn't support filtering by extension + Seq args = Seq.with("zenity", + "--file-selection", + "--title=" + formatted, + "--filename=" + last, + "--confirm-overwrite", + "--file-filter=" + Seq.with(extensions).toString(" ", s -> "*." + s), + "--file-filter=All files | *" //allow anything if the user wants + ); + + if(!open){ + args.add("--save"); + } + + String result = OS.exec(args.toArray(String.class)); + //first line. + if(result.length() > 1 && result.contains("\n")){ + result = result.split("\n")[0]; + } + + //cancelled selection, ignore result + if(result.isEmpty() || result.equals("\n")) return; + + if(result.endsWith("\n")) result = result.substring(0, result.length() - 1); + if(result.contains("\n")) throw new IOException("invalid input: \"" + result + "\""); + + Fi file = Core.files.absolute(result); + Core.app.post(() -> { + FileChooser.setLastDirectory(file.isDirectory() ? file : file.parent()); + + if(!open){ + cons.get(file.parent().child(file.nameWithoutExtension() + "." + extensions[0])); + }else{ + cons.get(file); + } + }); + }catch(Exception e){ + Log.err(e); + Log.warn("zenity not found, using non-native file dialog. Consider installing `zenity` for native file dialogs."); + Core.app.post(fallback); + } + }); + } + + @Override public Seq getWorkshopContent(Class type){ return !steam ? super.getWorkshopContent(type) : SVars.workshop.getWorkshopFiles(type);