Electron 43 deliberately stopped remembering the last folder used by the native open and save dialogs, so they always opened in Downloads. Track the last visited directory in the runtime's config store and pass it as defaultPath whenever the caller has not specified a location.
This commit is contained in:
@@ -478,9 +478,60 @@ function notifyUpdateInstalled() {
|
||||
}
|
||||
}
|
||||
|
||||
// Native file dialogs don't reliably remember the last used directory across
|
||||
// calls, so we track it ourselves and use it as the default when the caller
|
||||
// hasn't asked for a specific location.
|
||||
async function withLastVisitedDirectory(options) {
|
||||
if (options.defaultPath) {
|
||||
return options;
|
||||
}
|
||||
const lastVisitedDirectory = configStore.get('lastVisitedDirectory');
|
||||
if (!lastVisitedDirectory) {
|
||||
return options;
|
||||
}
|
||||
try {
|
||||
const stats = await fs.promises.stat(lastVisitedDirectory);
|
||||
if (stats.isDirectory()) {
|
||||
return { ...options, defaultPath: lastVisitedDirectory };
|
||||
}
|
||||
} catch {
|
||||
// Remembered directory no longer exists (e.g. removable/network drive) - fall through.
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function rememberVisitedDirectory(options, result) {
|
||||
const chosenPath = result.filePath || result.filePaths?.[0];
|
||||
if (!chosenPath) {
|
||||
return;
|
||||
}
|
||||
const isDirectory = options.properties?.includes('openDirectory');
|
||||
try {
|
||||
configStore.set('lastVisitedDirectory', isDirectory ? chosenPath : path.dirname(chosenPath));
|
||||
} catch (error) {
|
||||
try {
|
||||
misc.writeServerLog(`Error remembering last visited directory: ${error}`);
|
||||
} catch (logError) {
|
||||
console.error('Error remembering last visited directory:', error, logError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setup preload events.
|
||||
ipcMain.handle('showOpenDialog', (e, options) => dialog.showOpenDialog(BrowserWindow.fromWebContents(e.sender), options));
|
||||
ipcMain.handle('showSaveDialog', (e, options) => dialog.showSaveDialog(BrowserWindow.fromWebContents(e.sender), options));
|
||||
ipcMain.handle('showOpenDialog', async (e, options) => {
|
||||
const result = await dialog.showOpenDialog(BrowserWindow.fromWebContents(e.sender), await withLastVisitedDirectory(options));
|
||||
if (!result.canceled) {
|
||||
rememberVisitedDirectory(options, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
ipcMain.handle('showSaveDialog', async (e, options) => {
|
||||
const result = await dialog.showSaveDialog(BrowserWindow.fromWebContents(e.sender), await withLastVisitedDirectory(options));
|
||||
if (!result.canceled) {
|
||||
rememberVisitedDirectory(options, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
ipcMain.handle('showMessageBox', (e, options) => dialog.showMessageBox(BrowserWindow.fromWebContents(e.sender), options));
|
||||
ipcMain.handle('getStoreData', (_e, key) => key ? configStore.get(key) : configStore.store);
|
||||
ipcMain.handle('setStoreData', (_e, newValues) => {
|
||||
|
||||
Reference in New Issue
Block a user