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,26 @@ 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+ SDL_LogDebug (SDL_LOG_CATEGORY_SYSTEM , "Create save dialog for existing file" );
438+ DBus_AppendByteArray (dbus , & options , "current_file" , default_location );
439+ /* Setting "current_name" should not be necessary however the kde-desktop-portal sets the filename without an extension.
440+ * An alternative would be to match the extension to a filter and set "current_filter".
441+ */
442+ DBus_AppendStringOption (dbus , & options , "current_name" , location_name );
443+ } else if (save_file_new_named ) {
444+ SDL_LogDebug (SDL_LOG_CATEGORY_SYSTEM , "Create save dialog for new file" );
445+ DBus_AppendByteArray (dbus , & options , "current_folder" , location_folder );
446+ DBus_AppendStringOption (dbus , & options , "current_name" , location_name );
447+ } else {
448+ SDL_LogDebug (SDL_LOG_CATEGORY_SYSTEM , "Create dialog at folder" );
449+ DBus_AppendByteArray (dbus , & options , "current_folder" , default_location );
450+ }
451+
452+ SDL_free (location_name );
453+ SDL_free (location_folder );
414454 }
455+
415456 if (accept ) {
416457 DBus_AppendStringOption (dbus , & options , "accept_label" , accept );
417458 }
0 commit comments