diff --git a/app/main.ts b/app/main.ts index 22bca044a0..18651cbcfb 100644 --- a/app/main.ts +++ b/app/main.ts @@ -5,6 +5,8 @@ import { join, normalize, extname, dirname, basename } from 'path'; import { pathToFileURL } from 'url'; import * as os from 'os'; import { chmod, realpath, writeFile } from 'fs-extra'; +import { exec } from 'child_process'; +import { promisify } from 'util'; import { randomBytes } from 'crypto'; import { createParser } from 'dashdash'; @@ -3021,6 +3023,34 @@ ipc.handle('show-save-dialog', async (_event, { defaultPath }) => { return { canceled: true }; } + if ( + process.platform === 'linux' && + defaultPath && + defaultPath.charAt(0) !== '/' + ) { + // On Linux the defaultPath should be an absolute path, otherwise the save dialog will have an empty filename on KDE/Plasma + let downloadsPath = ''; + try { + downloadsPath = ( + await promisify(exec)('xdg-user-dir DOWNLOAD') + ).stdout.trim(); + getLogger().info( + 'show-save-dialog: saving to user downloads directory: ' + downloadsPath + ); + } catch (e) { + // If we cannot get Downloads path, fall back to the user's home directory + try { + downloadsPath = process.env['HOME']; + getLogger().info( + 'show-save-dialog: saving to user home directory: ' + downloadsPath + ); + } catch (ee) {} + } + if (downloadsPath) { + defaultPath = downloadsPath + '/' + defaultPath; + } + } + const { canceled, filePath: selectedFilePath } = await dialog.showSaveDialog( mainWindow, {