2525
2626#ifdef SDL_USE_LIBDBUS
2727
28+ #include <libgen.h>
2829#include <errno.h>
2930#include <sys/types.h>
3031#include <sys/wait.h>
32+ #include <sys/stat.h>
3133#include <unistd.h>
3234
3335#define PORTAL_DESTINATION "org.freedesktop.portal.Desktop"
@@ -294,7 +296,12 @@ void SDL_Portal_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_Dialog
294296 bool allow_many = SDL_GetBooleanProperty (props , SDL_PROP_FILE_DIALOG_MANY_BOOLEAN , false);
295297 const char * default_location = SDL_GetStringProperty (props , SDL_PROP_FILE_DIALOG_LOCATION_STRING , NULL );
296298 const char * accept = SDL_GetStringProperty (props , SDL_PROP_FILE_DIALOG_ACCEPT_STRING , NULL );
299+ char * location_name = NULL ;
300+ char * location_folder = NULL ;
301+ struct stat statbuf ;
297302 bool open_folders = false;
303+ bool save_file_existing = false;
304+ bool save_file_new_named = false;
298305
299306 switch (type ) {
300307 case SDL_FILEDIALOG_OPENFILE :
@@ -305,6 +312,22 @@ void SDL_Portal_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_Dialog
305312 case SDL_FILEDIALOG_SAVEFILE :
306313 method = "SaveFile" ;
307314 method_title = SDL_GetStringProperty (props , SDL_PROP_FILE_DIALOG_TITLE_STRING , "Save File" );
315+ if (default_location ) {
316+ if (stat (default_location , & statbuf ) == 0 ) {
317+ save_file_existing = S_ISREG (statbuf .st_mode ) || S_ISLNK (statbuf .st_mode );
318+ } else if (errno == ENOENT ) {
319+ char * dirc = SDL_strdup (default_location );
320+ location_folder = SDL_strdup (dirname (dirc ));
321+ SDL_free (dirc );
322+ save_file_new_named = (stat (location_folder , & statbuf ) == 0 ) && S_ISDIR (statbuf .st_mode );
323+ }
324+
325+ if (save_file_existing || save_file_new_named ) {
326+ char * basec = SDL_strdup (default_location );
327+ location_name = SDL_strdup (basename (basec ));
328+ SDL_free (basec );
329+ }
330+ }
308331 break ;
309332
310333 case SDL_FILEDIALOG_OPENFOLDER :
@@ -410,8 +433,23 @@ void SDL_Portal_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_Dialog
410433 DBus_AppendFilters (dbus , & options , filters , nfilters );
411434 }
412435 if (default_location ) {
413- DBus_AppendByteArray (dbus , & options , "current_folder" , default_location );
436+ if (save_file_existing ) {
437+ DBus_AppendByteArray (dbus , & options , "current_file" , default_location );
438+ /* Setting "current_name" should not be necessary however the kde-desktop-portal sets the filename without an extension.
439+ * An alternative would be to match the extension to a filter and set "current_filter".
440+ */
441+ DBus_AppendStringOption (dbus , & options , "current_name" , location_name );
442+ } else if (save_file_new_named ) {
443+ DBus_AppendByteArray (dbus , & options , "current_folder" , location_folder );
444+ DBus_AppendStringOption (dbus , & options , "current_name" , location_name );
445+ } else {
446+ DBus_AppendByteArray (dbus , & options , "current_folder" , default_location );
447+ }
448+
449+ SDL_free (location_name );
450+ SDL_free (location_folder );
414451 }
452+
415453 if (accept ) {
416454 DBus_AppendStringOption (dbus , & options , "accept_label" , accept );
417455 }
0 commit comments