diff --git a/Util/OS/FolderDialogUtil.cs b/Util/OS/FolderDialogUtil.cs
index ef6587e..1403060 100644
--- a/Util/OS/FolderDialogUtil.cs
+++ b/Util/OS/FolderDialogUtil.cs
@@ -18,8 +18,8 @@ namespace ADOFAIRenderer.Util.OS;
///
/// - macOS: osascript running AppleScript choose folder.
///
-/// - Linux: zenity --file-selection --directory; when zenity does not return an existing directory (not installed,
-/// cancelled or failed), kdialog --getexistingdirectory.
+/// - Linux: zenity --file-selection --directory; when zenity is not installed or fails (exit code other than 0
+/// or 1), kdialog --getexistingdirectory. A cancelled zenity dialog (exit code 1) ends the selection.
///
///
/// The dialog runs off the main Unity thread so the game keeps rendering frames while it is open. Only one dialog can be open
@@ -688,13 +688,13 @@ internal static class FolderDialogUtil
///
/// Runs zenity --file-selection --directory --title=... [--filename=initialDirectory] and blocks until it exits.
- /// When zenity cannot be started, exits with a non-zero code (cancel or error) or prints a path that is not an existing
- /// directory, runs kdialog --getexistingdirectory [initialDirectory] --title ... instead. Both commands print the
+ /// Exit code 0 returns the printed path when it is an existing directory, and exit code 1 (cancelled or closed) returns null
+ /// without opening a second dialog. When zenity cannot be started or exits with any other code, runs kdialog --getexistingdirectory [initialDirectory] --title ... instead. Both commands print the
/// selected path to standard output.
///
/// Folder shown first; used only when it is an existing directory.
///
- /// The selected existing directory; null when both dialogs return nothing, when kdialog cannot be started, or on an
+ /// The selected existing directory; null when the dialog is cancelled, when kdialog cannot be started, or on an
/// exception (logged as a warning).
///
private static string? OpenLinuxFolderBrowser(string initialDirectory)
@@ -725,15 +725,19 @@ internal static class FolderDialogUtil
var output = process.StandardOutput.ReadToEnd().Trim();
process.WaitForExit();
- if (process.ExitCode == 0 && !string.IsNullOrEmpty(output) && Directory.Exists(output))
+ if (process.ExitCode == 0)
{
- return output;
+ return !string.IsNullOrEmpty(output) && Directory.Exists(output) ? output : null;
}
+
+ // zenity exit code 1: the dialog was cancelled or closed.
+ // Reference: https://gitlab.gnome.org/GNOME/zenity/-/raw/master/src/util.c (ZENITY_OK_DEFAULT 0, ZENITY_CANCEL_DEFAULT 1, ZENITY_ESC_DEFAULT 1, ZENITY_ERROR_DEFAULT -1).
+ if (process.ExitCode == 1) return null;
}
}
catch
{
- // Fallback to kdialog if zenity fails to start
+ // Falls back to kdialog when zenity is not installed or cannot be started.
}
var kdialogInfo = new ProcessStartInfo