Add wxMoveToTrash function (PR #26256)

92 views
Skip to first unread message

Blake-Madden

unread,
Mar 1, 2026, 6:18:39 AM (13 days ago) Mar 1
to wx-...@googlegroups.com, Subscribed

Moves a file or directory (recursively) into the trash/recycle bin. If it fails, then returns false and leaves the file alone; I thought calling wxRemoveFile as an alternative path upon failure would be too aggressive and arbitrary.

I added implementation details in the docs; we seem to do that with system-level functions like this.

Tested on:

  • Windows 11
  • Linux Mint
  • macOS Catalina

You can view, comment on, or merge this pull request online at:

  https://github.com/wxWidgets/wxWidgets/pull/26256

Commit Summary

File Changes

(4 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256@github.com>

PB

unread,
Mar 1, 2026, 8:50:21 AM (13 days ago) Mar 1
to wx-...@googlegroups.com, Subscribed

@PBfordev commented on this pull request.

I suppose introducing a new function instead of adding a flag to the existing remove file/folder functions seemed better.


In src/common/filefn.cpp:

> +    // but without separator at the end of the path
+    wxString pathStr(path);
+    if ( pathStr.Last() == wxFILE_SEP_PATH )
+        pathStr.RemoveLast();
+    pathStr += wxT('\0');
+
+    SHFILEOPSTRUCT fileop;
+    wxZeroMemory(fileop);
+    fileop.wFunc = FO_DELETE;
+    fileop.pFrom = pathStr.t_str();
+    fileop.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;
+
+    int ret = SHFileOperation(&fileop);
+    if ( ret != 0 || fileop.fAnyOperationsAborted )
+    {
+        wxLogDebug(wxS("SHFileOperation(FO_DELETE with FOF_ALLOWUNDO) failed: error 0x%08x"),

Why was wxLogDebug() and not wxLogError() used here (and for macOS)? The error is reported to the user in the Linux code path and other wx file functions.


In src/common/filefn.cpp:

> +        else
+        {
+            result += wxString::Format("%%%02X", ch);
+        }
+        ++cur;
+    }
+
+    return result;
+}
+#endif // __UNIX__ && !__WXMAC__
+
+bool wxMoveToTrash(const wxString& path)
+{
+    if ( !wxFileExists(path) && !wxDirExists(path) )
+    {
+        wxLogError(_("'%s' doesn't exist and can't be moved to trash"), path);
⬇️ Suggested change
-        wxLogError(_("'%s' doesn't exist and can't be moved to trash"), path);
+        wxLogError(_("'%s' doesn't exist and can't be moved to trash."), path);

AFAICT, the sentences in wxLogError() (but not wxLogSysError()) end with a period elsewhere. Applies to the one at the end of the function as well.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3872123182@github.com>

Blake-Madden

unread,
Mar 1, 2026, 8:53:22 AM (13 days ago) Mar 1
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 0e583cc Update src/common/filefn.cpp


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/037e5ea36116b5f41e667ee5e7bad2354c2fd549/after/0e583cc9ee93fa0bfec3777cb3e863f9687150d0@github.com>

Blake-Madden

unread,
Mar 1, 2026, 8:57:55 AM (13 days ago) Mar 1
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +    // but without separator at the end of the path
+    wxString pathStr(path);
+    if ( pathStr.Last() == wxFILE_SEP_PATH )
+        pathStr.RemoveLast();
+    pathStr += wxT('\0');
+
+    SHFILEOPSTRUCT fileop;
+    wxZeroMemory(fileop);
+    fileop.wFunc = FO_DELETE;
+    fileop.pFrom = pathStr.t_str();
+    fileop.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;
+
+    int ret = SHFileOperation(&fileop);
+    if ( ret != 0 || fileop.fAnyOperationsAborted )
+    {
+        wxLogDebug(wxS("SHFileOperation(FO_DELETE with FOF_ALLOWUNDO) failed: error 0x%08x"),

That's how it's done in wxFileName::Rmdir (src/common/filename.cpp). Not saying that's right or wrong, I just re-used the code from there.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3872166343@github.com>

oneeyeman1

unread,
Mar 1, 2026, 2:31:25 PM (13 days ago) Mar 1
to wx-...@googlegroups.com, Subscribed
oneeyeman1 left a comment (wxWidgets/wxWidgets#26256)

@Blake-Madden ,
Please look at #2517 and try not to repeat the same mistakes I did... ;-)

Thank you.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3980844333@github.com>

VZ

unread,
Mar 2, 2026, 12:35:48 PM (12 days ago) Mar 2
to wx-...@googlegroups.com, Subscribed

@vadz commented on this pull request.

Thanks, this looks useful, but the error reporting needs to be streamlined.

I'm also not enamored of keeping the code for all platforms but macOS in the same function, it probably would be cleaner to have some wxMoveToTrashImpl() and implement it in MSW/Unix-specific file. But I realize that src/common/filefn.cpp is such a mess that it probably doesn't matter much.


In src/common/filefn.cpp:

> @@ -641,6 +641,160 @@ bool wxRemoveFile(const wxString& file)
     return res == 0;
 }
 
+#if defined(__WXMAC__)
+extern bool wxMoveToTrashOSX(const wxString& path);
+#endif
+
+#if defined(__UNIX__) && !defined(__WXMAC__)
+#include <fcntl.h>
+
+// Percent-encode a file path per RFC 2396 for the FreeDesktop Trash spec.
+static wxString wxTrashUrlEncodePath(const wxString& path)

Could we reuse wxURI::BuildURI() here? It's already supposed to have the correct logic for this.


In src/common/filefn.cpp:

> +    if ( !wxFileName::Mkdir(trashFiles, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+    if ( !wxFileName::Mkdir(trashInfo, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;

Should we create them? Maybe just check if they already exist and bail out if not? Not really sure, maybe this is the right thing to do, but some reference to the docs or whatever would be welcome here.


In src/common/filefn.cpp:

> +    if ( !wxFileName::Mkdir(trashFiles, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+    if ( !wxFileName::Mkdir(trashInfo, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+
+    // Resolve the full absolute path
+    wxFileName fileName(path);
+    fileName.MakeAbsolute();
+    wxString fullPath = fileName.GetFullPath();
+
+    // Pick a unique trash name atomically using O_EXCL per the spec
+    wxString baseName = fileName.GetFullName();
+    wxString trashName = baseName;
+    wxString infoPath;
+
+    for ( int attempt = 2; ; ++attempt )

It seems a bit dangerous to never stop, I'd put an upper bound on the number of attempts here (even if very high, e.g. 1,000,000). But again, I'm not sure what the spec says.


In src/common/filefn.cpp:

> +    // Write the .trashinfo file
+    {
+        wxFile infoFile;
+        if ( !infoFile.Open(infoPath, wxFile::write) )
+        {
+            wxRemoveFile(infoPath);
+            return false;
+        }
+
+        wxString encodedPath = wxTrashUrlEncodePath(fullPath);
+        wxString info = wxString::Format(
+            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",
+            encodedPath,
+            wxDateTime::Now().FormatISOCombined()
+        );
+        infoFile.Write(info);

Should check for error.


In src/common/filefn.cpp:

> +        if ( !ext.empty() )
+            trashName += "." + ext;
+    }
+
+    // Write the .trashinfo file
+    {
+        wxFile infoFile;
+        if ( !infoFile.Open(infoPath, wxFile::write) )
+        {
+            wxRemoveFile(infoPath);
+            return false;
+        }
+
+        wxString encodedPath = wxTrashUrlEncodePath(fullPath);
+        wxString info = wxString::Format(
+            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",

Minor, but this might look better/more clear as a raw string:

⬇️ Suggested change
-            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",
+R"[Trash Info]
+Path=%s
+DeletionDate=%s
+",

In src/common/filefn.cpp:

> +        wxString encodedPath = wxTrashUrlEncodePath(fullPath);
+        wxString info = wxString::Format(
+            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",
+            encodedPath,
+            wxDateTime::Now().FormatISOCombined()
+        );
+        infoFile.Write(info);
+    }
+
+    // Move the file or directory into Trash/files/
+    wxString destPath = trashFiles + "/" + trashName;
+    if ( wxRename(fullPath, destPath) != 0 )
+    {
+        // Move failed (e.g. cross-device) — clean up the .trashinfo
+        wxRemoveFile(infoPath);
+        wxLogSysError(_("'%s' couldn't be moved to trash"), path);

This won't log the correct error because it will have been overwritten by wxRemoveFile(), you need to call this first.

Note that using a scope guard for removing the file would take care of this automatically, as the dtor of the guard would be executed after any normal code.


In src/osx/cocoa/utils_base.mm:

> +bool wxMoveToTrashOSX(const wxString& path)
+{
+    wxCFStringRef cfPath(path);
+    NSURL *fileURL = [NSURL fileURLWithPath:cfPath.AsNSString()];
+    if ( fileURL == nil )
+        return false;
+
+    NSError *error = nil;
+    BOOL ok = [[NSFileManager defaultManager] trashItemAtURL:fileURL
+                                            resultingItemURL:nil
+                                                       error:&error];
+    if ( !ok )
+    {
+        if ( error )
+        {
+            wxLogDebug("NSFileManager trashItemAtURL failed: %s",

Those should also be replaced with user-readable error messages (i.e. "'%s' couldn't be moved to trash: %s").


In src/common/filefn.cpp:

> +    // but without separator at the end of the path
+    wxString pathStr(path);
+    if ( pathStr.Last() == wxFILE_SEP_PATH )
+        pathStr.RemoveLast();
+    pathStr += wxT('\0');
+
+    SHFILEOPSTRUCT fileop;
+    wxZeroMemory(fileop);
+    fileop.wFunc = FO_DELETE;
+    fileop.pFrom = pathStr.t_str();
+    fileop.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;
+
+    int ret = SHFileOperation(&fileop);
+    if ( ret != 0 || fileop.fAnyOperationsAborted )
+    {
+        wxLogDebug(wxS("SHFileOperation(FO_DELETE with FOF_ALLOWUNDO) failed: error 0x%08x"),

I think it was done like this in wxFileName::Rmdir() because it doesn't show user-visible log messages in any case (why is it so is another question...). This function does give errors in the Linux/Unix version and so I agree that this should be a wxLogError() too.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3877572742@github.com>

Ian McInerney

unread,
Mar 2, 2026, 12:46:36 PM (12 days ago) Mar 2
to wx-...@googlegroups.com, Subscribed
imciner2 left a comment (wxWidgets/wxWidgets#26256)

Why have you implemented the freedesktop spec directly instead of using something like g_file_trash (https://docs.gtk.org/gio/method.File.trash.html), which I believe implemented that spec also. (note in KiCad we implemented the move to trash functionality by just calling g_file_trash, https://gitlab.com/kicad/code/kicad/-/blob/master/libs/kiplatform/os/unix/environment.cpp?ref_type=heads#L68).


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3985919808@github.com>

Blake-Madden

unread,
Mar 2, 2026, 5:49:00 PM (12 days ago) Mar 2
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 9cefb93 Update src/common/filefn.cpp


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/0e583cc9ee93fa0bfec3777cb3e863f9687150d0/after/9cefb93be76450a8772d296068e34b9bdc290b5f@github.com>

Blake-Madden

unread,
Mar 2, 2026, 5:50:49 PM (12 days ago) Mar 2
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

Why have you implemented the freedesktop spec directly instead of using something like g_file_trash (https://docs.gtk.org/gio/method.File.trash.html), which I believe implemented that spec also. (note in KiCad we implemented the move to trash functionality by just calling g_file_trash, https://gitlab.com/kicad/code/kicad/-/blob/master/libs/kiplatform/os/unix/environment.cpp?ref_type=heads#L68).

I tried that, but would get link errors. Seems that we need to add a GLib/GIO dependency for that, so I went with a different approach.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3987432976@github.com>

VZ

unread,
Mar 2, 2026, 6:00:47 PM (12 days ago) Mar 2
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26256)

I tried that, but would get link errors. Seems that we need to add a GLib/GIO dependency for that, so I went with a different approach.

Even wxBase links with glib under Linux, so I'm not sure what the problem was... In any case, if we made this a GUI function (which might make sense?), there definitely should be no problems with using glib function in wxGTK.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3987483255@github.com>

Blake-Madden

unread,
Mar 3, 2026, 11:48:21 AM (11 days ago) Mar 3
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 50c743b Use g_file_trash for GTK, make error message more friendly


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/9cefb93be76450a8772d296068e34b9bdc290b5f/after/50c743b1197e319171fd014672e0d45c26a7233f@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:12:35 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> @@ -641,6 +641,160 @@ bool wxRemoveFile(const wxString& file)
     return res == 0;
 }
 
+#if defined(__WXMAC__)
+extern bool wxMoveToTrashOSX(const wxString& path);
+#endif
+
+#if defined(__UNIX__) && !defined(__WXMAC__)
+#include <fcntl.h>
+
+// Percent-encode a file path per RFC 2396 for the FreeDesktop Trash spec.
+static wxString wxTrashUrlEncodePath(const wxString& path)

Removed this, using g_file_trash now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883963435@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:13:06 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +        wxString encodedPath = wxTrashUrlEncodePath(fullPath);
+        wxString info = wxString::Format(
+            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",
+            encodedPath,
+            wxDateTime::Now().FormatISOCombined()
+        );
+        infoFile.Write(info);
+    }
+
+    // Move the file or directory into Trash/files/
+    wxString destPath = trashFiles + "/" + trashName;
+    if ( wxRename(fullPath, destPath) != 0 )
+    {
+        // Move failed (e.g. cross-device) — clean up the .trashinfo
+        wxRemoveFile(infoPath);
+        wxLogSysError(_("'%s' couldn't be moved to trash"), path);

Removed this, using g_file_trash now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883967413@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:17:28 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/osx/cocoa/utils_base.mm:

> +bool wxMoveToTrashOSX(const wxString& path)
+{
+    wxCFStringRef cfPath(path);
+    NSURL *fileURL = [NSURL fileURLWithPath:cfPath.AsNSString()];
+    if ( fileURL == nil )
+        return false;
+
+    NSError *error = nil;
+    BOOL ok = [[NSFileManager defaultManager] trashItemAtURL:fileURL
+                                            resultingItemURL:nil
+                                                       error:&error];
+    if ( !ok )
+    {
+        if ( error )
+        {
+            wxLogDebug("NSFileManager trashItemAtURL failed: %s",

Fixed.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883968752@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:17:49 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +    if ( !wxFileName::Mkdir(trashFiles, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+    if ( !wxFileName::Mkdir(trashInfo, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;

Removed this, using g_file_trash now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883964695@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:17:59 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

Using g_file_trash now. Seems simple enough now to keep MSW and GTK paths in one file, let me know if anyone disagrees.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3992449487@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:18:05 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +    if ( !wxFileName::Mkdir(trashFiles, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+    if ( !wxFileName::Mkdir(trashInfo, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
+        return false;
+
+    // Resolve the full absolute path
+    wxFileName fileName(path);
+    fileName.MakeAbsolute();
+    wxString fullPath = fileName.GetFullPath();
+
+    // Pick a unique trash name atomically using O_EXCL per the spec
+    wxString baseName = fileName.GetFullName();
+    wxString trashName = baseName;
+    wxString infoPath;
+
+    for ( int attempt = 2; ; ++attempt )

Removed this, using g_file_trash now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883970337@github.com>

Blake-Madden

unread,
Mar 3, 2026, 12:32:46 PM (11 days ago) Mar 3
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +    // Write the .trashinfo file
+    {
+        wxFile infoFile;
+        if ( !infoFile.Open(infoPath, wxFile::write) )
+        {
+            wxRemoveFile(infoPath);
+            return false;
+        }
+
+        wxString encodedPath = wxTrashUrlEncodePath(fullPath);
+        wxString info = wxString::Format(
+            "[Trash Info]\nPath=%s\nDeletionDate=%s\n",
+            encodedPath,
+            wxDateTime::Now().FormatISOCombined()
+        );
+        infoFile.Write(info);

Removed this, using g_file_trash now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3883965792@github.com>

Miguel Gimenez

unread,
Mar 4, 2026, 11:10:52 AM (10 days ago) Mar 4
to wx-...@googlegroups.com, Subscribed
wh11204 left a comment (wxWidgets/wxWidgets#26256)

I think these "unknown error" messages should be translatable


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c3998539758@github.com>

PB

unread,
Mar 4, 2026, 1:43:51 PM (10 days ago) Mar 4
to wx-...@googlegroups.com, Subscribed

@PBfordev commented on this pull request.


In interface/wx/filefn.h:

> @@ -348,6 +348,29 @@ bool wxConcatFiles(const wxString& src1,
 */
 bool wxRemoveFile(const wxString& file);
 
+/**
+    Moves @a path to the system trash or recycle bin, returning @true if
+    successful.
+
+    This works for both files and directories. The item is not permanently
+    deleted and can be restored by the user from the platform's trash
+    facility.
+
+    Under Windows, this uses the shell file operation with @c FOF_ALLOWUNDO.
+    Under macOS, this uses @c NSFileManager's @c trashItemAtURL method.
+    Under Unix systems (including Linux and BSD), this implements the

Just curious (I know nothing about Unix): Is the Unix part still still valid after changing the code?

I personally would also change the Windows part, replacing "the shell file operation" with the actual function name, i.e., SHFileOperation, as it is done for macOS.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3891271092@github.com>

Blake-Madden

unread,
Mar 4, 2026, 4:46:58 PM (10 days ago) Mar 4
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 2714488 Make message translatable, update docs


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/50c743b1197e319171fd014672e0d45c26a7233f/after/2714488dc02c55080c70043726e257858ec4f4a6@github.com>

Blake-Madden

unread,
Mar 4, 2026, 4:47:44 PM (10 days ago) Mar 4
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In interface/wx/filefn.h:

> @@ -348,6 +348,29 @@ bool wxConcatFiles(const wxString& src1,
 */
 bool wxRemoveFile(const wxString& file);
 
+/**
+    Moves @a path to the system trash or recycle bin, returning @true if
+    successful.
+
+    This works for both files and directories. The item is not permanently
+    deleted and can be restored by the user from the platform's trash
+    facility.
+
+    Under Windows, this uses the shell file operation with @c FOF_ALLOWUNDO.
+    Under macOS, this uses @c NSFileManager's @c trashItemAtURL method.
+    Under Unix systems (including Linux and BSD), this implements the

fixed


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3892229891@github.com>

Blake-Madden

unread,
Mar 4, 2026, 4:48:01 PM (10 days ago) Mar 4
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

I think these "unknown error" messages should be translatable

Fixed.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4000505046@github.com>

VZ

unread,
Mar 7, 2026, 10:12:47 AM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed

@vadz commented on this pull request.

Thanks, I definitely prefer the new version using the glib function. However I still think it would be better to implement this function in platform-specific file instead of the current approach.

I would advise doing the following:

  1. Add (and document in docs/doxygen/mainpages/const_cpp.h) wxHAS_MOVE_TO_TRASH preprocessor symbol.
  2. Define it for the platforms really implementing this function in the header and implement it in the platform-specific files.
  3. Provide fallback function just returning false (maybe without logging anything, as I don't think this error message is really useful) in the common code #ifndef wxHAS_MOVE_TO_TRASH.

And, of course, the CI failures need to be fixed (you should use .utf8_str()).


In src/common/filefn.cpp:

> +
+#elif defined(__WXMAC__)
+    return wxMoveToTrashOSX(path);
+
+#elif defined(__WXGTK__)
+    GError* err = nullptr;
+    GFile* file = g_file_new_for_path(path.fn_str());
+
+    bool ok = g_file_trash(file, nullptr, &err);
+    if ( !ok )
+    {
+        wxLogError(_("'%s' couldn't be moved to trash: %s"),
+                   path, err ? err->message : _("unknown error"));
+    }
+
+    g_clear_error(&err);

We have wxGtkError in include/wx/gtk/private/error.h, please use it instead (see the examples of existing use in wxGTK).


In src/common/filefn.cpp:

> +#elif defined(__WXMAC__)
+    return wxMoveToTrashOSX(path);
+
+#elif defined(__WXGTK__)
+    GError* err = nullptr;
+    GFile* file = g_file_new_for_path(path.fn_str());
+
+    bool ok = g_file_trash(file, nullptr, &err);
+    if ( !ok )
+    {
+        wxLogError(_("'%s' couldn't be moved to trash: %s"),
+                   path, err ? err->message : _("unknown error"));
+    }
+
+    g_clear_error(&err);
+    g_object_unref(file);

We also have wxGtkObject in include/wx/gtk/private/object.h to avoid having to do (or, worse, forget to do) this manually.


In src/common/filefn.cpp:

> +    if ( !wxFileExists(path) && !wxDirExists(path) )
+    {
+        wxLogError(_("'%s' doesn't exist and can't be moved to trash."), path);
+        return false;
+    }

I wonder if this is actually needed, wouldn't we get a similar error from the native function anyhow in this case?


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3908915871@github.com>

Blake-Madden

unread,
Mar 7, 2026, 1:23:29 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +    if ( !wxFileExists(path) && !wxDirExists(path) )
+    {
+        wxLogError(_("'%s' doesn't exist and can't be moved to trash."), path);
+        return false;
+    }

Indeed. I tend to be overly pedantic :) Removing this now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3909296639@github.com>

Blake-Madden

unread,
Mar 7, 2026, 1:25:07 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +#elif defined(__WXMAC__)
+    return wxMoveToTrashOSX(path);
+
+#elif defined(__WXGTK__)
+    GError* err = nullptr;
+    GFile* file = g_file_new_for_path(path.fn_str());
+
+    bool ok = g_file_trash(file, nullptr, &err);
+    if ( !ok )
+    {
+        wxLogError(_("'%s' couldn't be moved to trash: %s"),
+                   path, err ? err->message : _("unknown error"));
+    }
+
+    g_clear_error(&err);
+    g_object_unref(file);

Making change now.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3909300446@github.com>

Blake-Madden

unread,
Mar 7, 2026, 1:27:22 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed

@Blake-Madden commented on this pull request.


In src/common/filefn.cpp:

> +
+#elif defined(__WXMAC__)
+    return wxMoveToTrashOSX(path);
+
+#elif defined(__WXGTK__)
+    GError* err = nullptr;
+    GFile* file = g_file_new_for_path(path.fn_str());
+
+    bool ok = g_file_trash(file, nullptr, &err);
+    if ( !ok )
+    {
+        wxLogError(_("'%s' couldn't be moved to trash: %s"),
+                   path, err ? err->message : _("unknown error"));
+    }
+
+    g_clear_error(&err);

Fixing now...


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3909305345@github.com>

Blake-Madden

unread,
Mar 7, 2026, 1:43:06 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • a1e2bfe Move into platform specific files, use GTK helper object, remove extra error message


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/2714488dc02c55080c70043726e257858ec4f4a6/after/a1e2bfe8e0d8a1f10add1084fa1b72a498a33953@github.com>

Blake-Madden

unread,
Mar 7, 2026, 1:55:13 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/a1e2bfe8e0d8a1f10add1084fa1b72a498a33953/after/98f9421165abcf2abd6a3996f27d9b4813e654ba@github.com>

Blake-Madden

unread,
Mar 7, 2026, 2:21:34 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 0d5dfa8 Fix link error with GTK on macOS

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/98f9421165abcf2abd6a3996f27d9b4813e654ba/after/0d5dfa8f5d2e851b63c0a0d84fb3f6b0bfcbe31c@github.com>

Blake-Madden

unread,
Mar 7, 2026, 3:30:17 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

@vadz All requested changes applied.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4017285574@github.com>

PB

unread,
Mar 7, 2026, 4:52:53 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed
PBfordev left a comment (wxWidgets/wxWidgets#26256)

The error reporting on MSW still uses wxLogDebug() instead of wxLogError() the other two ports use?

"unknown error" in the macOS code path is not localized?

As for the docs:

  • Does the Unix note still apply after changing the API (and the rest of the Unix docs)?
  • I don't think I saw something like "Requires @c wxHAS_MOVE_TO_TRASH." for another API, this seems to be an implementation detail. The function is supported on all three platforms (Qt is not usually mentioned in the docs); I would not mention the availability at all here.

Sorry for all the nagging.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4017467106@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:16:31 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 5338fb8 Make message translatable


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/0d5dfa8f5d2e851b63c0a0d84fb3f6b0bfcbe31c/after/5338fb80c4a25dc74c66d3ef79d0e0b758cb951d@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:17:50 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/5338fb80c4a25dc74c66d3ef79d0e0b758cb951d/after/9886e8b57c72a2c4c3608884d03014d136201844@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:18:51 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • a190088 Remove wxHAS_MOVE_TO_TRASH requirement note

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/9886e8b57c72a2c4c3608884d03014d136201844/after/a190088bcca59d6d2651702bde38cf673057fce7@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:21:38 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 53c1590 Remove stale comment about trash on external drives

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/a190088bcca59d6d2651702bde38cf673057fce7/after/53c1590cc21b9e89acb6af52cd88d290506bddb1@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:22:15 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

Thanks, @PBfordev, I've applied the updates.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4017526496@github.com>

PB

unread,
Mar 7, 2026, 5:45:32 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed
PBfordev left a comment (wxWidgets/wxWidgets#26256)

Thanks, @PBfordev, I've applied the updates.

I would use the same error reporting on MSW as for the other two, i.e., (1) Make the message translatable and (2) Use the same basic message as in the other two ports (IMO, the current one is overly technical for the end user).


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4017575122@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:54:17 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Push

@Blake-Madden pushed 1 commit.

  • 1875ad1 Improve MSW error message


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/before/53c1590cc21b9e89acb6af52cd88d290506bddb1/after/1875ad12bd614a5dcf63e432c619607dd3c3ad5b@github.com>

Blake-Madden

unread,
Mar 7, 2026, 5:54:45 PM (7 days ago) Mar 7
to wx-...@googlegroups.com, Subscribed
Blake-Madden left a comment (wxWidgets/wxWidgets#26256)

I would use the same error reporting on MSW as for the other two, i.e., (1) Make the message translatable and (2) Use the same basic message as in the other two ports (IMO, the current one is overly technical for the end user).

Done


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/c4017585785@github.com>

VZ

unread,
Mar 13, 2026, 10:52:20 AM (yesterday) Mar 13
to wx-...@googlegroups.com, Subscribed

@vadz approved this pull request.

Looks perfect now, thanks! Will merge soon.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/review/3944609829@github.com>

VZ

unread,
Mar 13, 2026, 11:02:51 AM (yesterday) Mar 13
to wx-...@googlegroups.com, Subscribed

Closed #26256 via 400780a.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26256/issue_event/23549710428@github.com>

Reply all
Reply to author
Forward
0 new messages