Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix Move File To Trash: Use build it solution
  • Loading branch information
xavierdono committed Jul 4, 2025
commit a775c07c01c183119b03590002636399db457e65
36 changes: 8 additions & 28 deletions src/Commands/SaveDiscardOnTrash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,16 @@ public static async Task<bool> ProcessSaveDiscardOnTrash(string repo, List<Model
{
changes ??= await new QueryLocalChanges(repo).GetResultAsync().ConfigureAwait(false);

var succ = false;
string fullName = $"discard_{DateTime.Now.Ticks}.patch";
string trashDirectory;
string tempFolder = Path.GetTempPath();
string fileName = $"discard_{DateTime.Now.Ticks}.patch";
string fileNameTemp = Path.Combine(tempFolder, fileName);

if (OperatingSystem.IsLinux())
{
trashDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "Trash", "files");
fullName = Path.Combine(trashDirectory, fullName);
succ = await SaveChangesAsPatch.ProcessLocalChangesAsync(repo, changes, true, fullName);
if (succ) return false;
}
else if (OperatingSystem.IsMacOS())
{
trashDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".Trash");
fullName = Path.Combine(trashDirectory, fullName);
succ = await SaveChangesAsPatch.ProcessLocalChangesAsync(repo, changes, true, fullName);
if (succ)
return false;
}
else
{
trashDirectory = Path.GetTempPath();
fullName = Path.Combine(trashDirectory, fullName);
succ = await SaveChangesAsPatch.ProcessLocalChangesAsync(repo, changes, true, fullName);
if (succ)
return false;
// Save the patch in the Temp Folder
var succ = await SaveChangesAsPatch.ProcessLocalChangesAsync(repo, changes, true, fileNameTemp);
if (succ) return false;

if (!SaveDiscardOnTrashWindows.MoveFileToTrash(fullName))
return false;
}
// Move the file in the Trash
if(!Native.OS.MoveFileToTrash(fileNameTemp)) return false;

return false;
}
Expand Down
50 changes: 0 additions & 50 deletions src/Commands/SaveDiscardOnTrashWindows.cs

This file was deleted.

5 changes: 5 additions & 0 deletions src/Native/Linux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,10 @@ private string FindJetBrainsFleet()
var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet";
return File.Exists(path) ? path : FindExecutable("fleet");
}

public bool MoveFileToTrash(string file)
{
return true;
}
}
}
5 changes: 5 additions & 0 deletions src/Native/MacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,10 @@ public void OpenWithDefaultEditor(string file)
{
Process.Start("open", $"\"{file}\"");
}

public bool MoveFileToTrash(string file)
{
return true;
}
}
}
6 changes: 6 additions & 0 deletions src/Native/OS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public interface IBackend
string FindGitExecutable();
string FindTerminal(Models.ShellOrTerminal shell);
List<Models.ExternalTool> FindExternalTools();
bool MoveFileToTrash(string file);

void OpenTerminal(string workdir);
void OpenInFileManager(string path, bool select);
Expand Down Expand Up @@ -162,6 +163,11 @@ public static void OpenBrowser(string url)
_backend.OpenBrowser(url);
}

public static bool MoveFileToTrash(string file)
{
return _backend.MoveFileToTrash(file);
}

public static void OpenTerminal(string workdir)
{
if (string.IsNullOrEmpty(ShellOrTerminal))
Expand Down
42 changes: 42 additions & 0 deletions src/Native/Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ internal struct MARGINS
public int cyBottomHeight;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
public uint wFunc;
public string pFrom;
public string pTo;
public ushort fFlags;
public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}

[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

Expand All @@ -48,6 +61,9 @@ internal struct MARGINS
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)]
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, int cild, IntPtr apidl, int dwFlags);

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);

[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

Expand Down Expand Up @@ -253,6 +269,28 @@ public void OpenWithDefaultEditor(string file)
Process.Start(start);
}

public bool MoveFileToTrash(string file)
{
SHFILEOPSTRUCT fileOp = new SHFILEOPSTRUCT
{
wFunc = FO_DELETE,
pFrom = file + '\0',
pTo = null,
fFlags = (ushort)(FOF_ALLOWUNDO | FOF_NOCONFIRMATION),
fAnyOperationsAborted = false,
hNameMappings = IntPtr.Zero,
lpszProgressTitle = null
};

// Move the file in the Trash
bool result = SHFileOperation(ref fileOp) == 0;

// If move ok delete the temp file
if (result) File.Delete(file);

return result;
}

private void FixWindowFrameOnWin10(Window w)
{
// Schedule the DWM frame extension to run in the next render frame
Expand Down Expand Up @@ -431,5 +469,9 @@ private string FindVSSolutionFile(DirectoryInfo dir, int leftDepth)

return null;
}

private const uint FO_DELETE = 0x0003; // Delete operation
private const uint FOF_ALLOWUNDO = 0x0040; // Put in Trash
private const uint FOF_NOCONFIRMATION = 0x0010; // No confirmation
}
}