From d950382ab64befa94b3d88bf52ccef3b2fbc24bf Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 28 Feb 2026 15:24:54 +0800 Subject: [PATCH] refactor: unify the behavior of `Reveal in File Explorer` when the selected is a folder across all platforms Signed-off-by: leo --- src/Native/Linux.cs | 2 +- src/Native/MacOS.cs | 2 +- src/Native/OS.cs | 6 +- src/Native/Windows.cs | 86 ++++++++++--------------- src/Views/CommitDetail.axaml.cs | 4 +- src/Views/Compare.axaml.cs | 2 +- src/Views/RevisionCompare.axaml.cs | 2 +- src/Views/RevisionFileTreeView.axaml.cs | 6 +- src/Views/StashesPage.axaml.cs | 2 +- src/Views/WorkingCopy.axaml.cs | 8 +-- 10 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs index 32af912e..b192015b 100644 --- a/src/Native/Linux.cs +++ b/src/Native/Linux.cs @@ -106,7 +106,7 @@ namespace SourceGit.Native Process.Start(browser, url.Quoted()); } - public void OpenInFileManager(string path, bool select) + public void OpenInFileManager(string path) { if (Directory.Exists(path)) { diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index a3a1d612..fe0c0475 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -91,7 +91,7 @@ namespace SourceGit.Native Process.Start("open", url); } - public void OpenInFileManager(string path, bool select) + public void OpenInFileManager(string path) { if (Directory.Exists(path)) Process.Start("open", path.Quoted()); diff --git a/src/Native/OS.cs b/src/Native/OS.cs index 21be648f..159656f6 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -23,7 +23,7 @@ namespace SourceGit.Native List FindExternalTools(); void OpenTerminal(string workdir, string args); - void OpenInFileManager(string path, bool select); + void OpenInFileManager(string path); void OpenBrowser(string url); void OpenWithDefaultEditor(string file); } @@ -198,9 +198,9 @@ namespace SourceGit.Native } } - public static void OpenInFileManager(string path, bool select = false) + public static void OpenInFileManager(string path) { - _backend.OpenInFileManager(path, select); + _backend.OpenInFileManager(path); } public static void OpenBrowser(string url) diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 11a07f0d..c96a74ca 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -177,32 +177,30 @@ namespace SourceGit.Native Process.Start(startInfo); } - public void OpenInFileManager(string path, bool select) + public void OpenInFileManager(string path) { - string fullpath; if (File.Exists(path)) { - fullpath = new FileInfo(path).FullName; - select = true; - } - else - { - fullpath = new DirectoryInfo(path!).FullName; - fullpath += Path.DirectorySeparatorChar; + var pidl = ILCreateFromPathW(new FileInfo(path).FullName); + + try + { + SHOpenFolderAndSelectItems(pidl, 0, 0, 0); + } + finally + { + ILFree(pidl); + } + + return; } - if (select) + var dir = new DirectoryInfo(path).FullName + Path.DirectorySeparatorChar; + Process.Start(new ProcessStartInfo(dir) { - OpenFolderAndSelectFile(fullpath); - } - else - { - Process.Start(new ProcessStartInfo(fullpath) - { - UseShellExecute = true, - CreateNoWindow = true, - }); - } + UseShellExecute = true, + CreateNoWindow = true, + }); } public void OpenWithDefaultEditor(string file) @@ -213,6 +211,7 @@ namespace SourceGit.Native Process.Start(start); } + #region HELPER_METHODS private void FixWindowFrameOnWin10(Window w) { // Schedule the DWM frame extension to run in the next render frame @@ -228,11 +227,22 @@ namespace SourceGit.Native }, DispatcherPriority.Render); } - private PixelPoint IntPtrToPixelPoint(IntPtr param) + private List GenerateVSProjectLaunchOptions(string path) { - var v = IntPtr.Size == 4 ? param.ToInt32() : (int)(param.ToInt64() & 0xFFFFFFFF); - return new PixelPoint((short)(v & 0xffff), (short)(v >> 16)); + var root = new DirectoryInfo(path); + if (!root.Exists) + return null; + + var options = new List(); + root.WalkFiles(f => + { + if (f.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) || + f.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase)) + options.Add(new(root.GetRelativePath(f), f.Quoted())); + }); + return options; } + #endregion #region EXTERNAL_EDITOR_FINDER private string FindVSCode() @@ -385,35 +395,5 @@ namespace SourceGit.Native return string.Empty; } #endregion - - private void OpenFolderAndSelectFile(string folderPath) - { - var pidl = ILCreateFromPathW(folderPath); - - try - { - SHOpenFolderAndSelectItems(pidl, 0, 0, 0); - } - finally - { - ILFree(pidl); - } - } - - private List GenerateVSProjectLaunchOptions(string path) - { - var root = new DirectoryInfo(path); - if (!root.Exists) - return null; - - var options = new List(); - root.WalkFiles(f => - { - if (f.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) || - f.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase)) - options.Add(new(root.GetRelativePath(f), f.Quoted())); - }); - return options; - } } } diff --git a/src/Views/CommitDetail.axaml.cs b/src/Views/CommitDetail.axaml.cs index cd1f0ad8..16e76984 100644 --- a/src/Views/CommitDetail.axaml.cs +++ b/src/Views/CommitDetail.axaml.cs @@ -29,7 +29,7 @@ namespace SourceGit.Views explore.IsEnabled = Directory.Exists(fullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(fullPath, true); + Native.OS.OpenInFileManager(fullPath); ev.Handled = true; }; @@ -264,7 +264,7 @@ namespace SourceGit.Views explore.IsEnabled = File.Exists(fullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(fullPath, true); + Native.OS.OpenInFileManager(fullPath); ev.Handled = true; }; diff --git a/src/Views/Compare.axaml.cs b/src/Views/Compare.axaml.cs index 6304aa96..820a53c6 100644 --- a/src/Views/Compare.axaml.cs +++ b/src/Views/Compare.axaml.cs @@ -76,7 +76,7 @@ namespace SourceGit.Views explore.IsEnabled = File.Exists(full); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(full, true); + Native.OS.OpenInFileManager(full); ev.Handled = true; }; menu.Items.Add(explore); diff --git a/src/Views/RevisionCompare.axaml.cs b/src/Views/RevisionCompare.axaml.cs index f296aff5..21ec061c 100644 --- a/src/Views/RevisionCompare.axaml.cs +++ b/src/Views/RevisionCompare.axaml.cs @@ -77,7 +77,7 @@ namespace SourceGit.Views explore.IsEnabled = File.Exists(changeFullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(changeFullPath, true); + Native.OS.OpenInFileManager(changeFullPath); ev.Handled = true; }; menu.Items.Add(explore); diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs index 9141f3b0..ca00e8e2 100644 --- a/src/Views/RevisionFileTreeView.axaml.cs +++ b/src/Views/RevisionFileTreeView.axaml.cs @@ -446,7 +446,7 @@ namespace SourceGit.Views explore.IsEnabled = Directory.Exists(fullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(fullPath, true); + Native.OS.OpenInFileManager(fullPath); ev.Handled = true; }; @@ -567,10 +567,10 @@ namespace SourceGit.Views var explore = new MenuItem(); explore.Header = App.Text("RevealFile"); explore.Icon = App.CreateMenuIcon("Icons.Explore"); - explore.IsEnabled = File.Exists(fullPath); + explore.IsEnabled = File.Exists(fullPath) || Directory.Exists(fullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(fullPath, file.Type == Models.ObjectType.Blob); + Native.OS.OpenInFileManager(fullPath); ev.Handled = true; }; diff --git a/src/Views/StashesPage.axaml.cs b/src/Views/StashesPage.axaml.cs index 9a38d48d..8e8bb231 100644 --- a/src/Views/StashesPage.axaml.cs +++ b/src/Views/StashesPage.axaml.cs @@ -157,7 +157,7 @@ namespace SourceGit.Views explore.IsEnabled = File.Exists(fullPath); explore.Click += (_, ev) => { - Native.OS.OpenInFileManager(fullPath, true); + Native.OS.OpenInFileManager(fullPath); ev.Handled = true; }; diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index 1839bcc1..99c86e2c 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -285,7 +285,7 @@ namespace SourceGit.Views explore.Click += (_, e) => { var target = hasSelectedFolder ? Native.OS.GetAbsPath(repo.FullPath, selectedSingleFolder) : path; - Native.OS.OpenInFileManager(target, true); + Native.OS.OpenInFileManager(target); e.Handled = true; }; menu.Items.Add(explore); @@ -764,7 +764,7 @@ namespace SourceGit.Views explore.IsEnabled = Directory.Exists(dir); explore.Click += (_, e) => { - Native.OS.OpenInFileManager(dir, true); + Native.OS.OpenInFileManager(dir); e.Handled = true; }; menu.Items.Add(explore); @@ -960,7 +960,7 @@ namespace SourceGit.Views explore.Click += (_, e) => { var target = hasSelectedFolder ? Native.OS.GetAbsPath(repo.FullPath, selectedSingleFolder) : path; - Native.OS.OpenInFileManager(target, true); + Native.OS.OpenInFileManager(target); e.Handled = true; }; @@ -1173,7 +1173,7 @@ namespace SourceGit.Views explore.Icon = App.CreateMenuIcon("Icons.Explore"); explore.Click += (_, e) => { - Native.OS.OpenInFileManager(dir, true); + Native.OS.OpenInFileManager(dir); e.Handled = true; };