Fix autostart on linux
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { app } from 'electron';
|
||||
import AutoLaunch from 'auto-launch';
|
||||
import * as fsp from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import { readDesktopSettings } from '../desktop-settings';
|
||||
|
||||
let autoLauncher: AutoLaunch | null = null;
|
||||
let autoLaunchPath = '';
|
||||
|
||||
const LINUX_AUTO_START_ARGUMENTS = ['--no-sandbox', '%U'];
|
||||
|
||||
function resolveLaunchPath(): string {
|
||||
// AppImage runs from a temporary mount; APPIMAGE points to the real file path.
|
||||
@@ -13,15 +18,77 @@ function resolveLaunchPath(): string {
|
||||
return appImagePath || process.execPath;
|
||||
}
|
||||
|
||||
function escapeDesktopEntryExecArgument(argument: string): string {
|
||||
const escapedArgument = argument.replace(/(["\\$`])/g, '\\$1');
|
||||
|
||||
return /[\s"]/u.test(argument)
|
||||
? `"${escapedArgument}"`
|
||||
: escapedArgument;
|
||||
}
|
||||
|
||||
function getLinuxAutoStartDesktopEntryPath(launchPath: string): string {
|
||||
return path.join(app.getPath('home'), '.config', 'autostart', `${path.basename(launchPath)}.desktop`);
|
||||
}
|
||||
|
||||
function buildLinuxAutoStartExecLine(launchPath: string): string {
|
||||
return `Exec=${[escapeDesktopEntryExecArgument(launchPath), ...LINUX_AUTO_START_ARGUMENTS].join(' ')}`;
|
||||
}
|
||||
|
||||
function buildLinuxAutoStartDesktopEntry(launchPath: string): string {
|
||||
const appName = path.basename(launchPath);
|
||||
|
||||
return [
|
||||
'[Desktop Entry]',
|
||||
'Type=Application',
|
||||
'Version=1.0',
|
||||
`Name=${appName}`,
|
||||
`Comment=${appName}startup script`,
|
||||
buildLinuxAutoStartExecLine(launchPath),
|
||||
'StartupNotify=false',
|
||||
'Terminal=false'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
async function synchronizeLinuxAutoStartDesktopEntry(launchPath: string): Promise<void> {
|
||||
if (process.platform !== 'linux') {
|
||||
return;
|
||||
}
|
||||
|
||||
const desktopEntryPath = getLinuxAutoStartDesktopEntryPath(launchPath);
|
||||
const execLine = buildLinuxAutoStartExecLine(launchPath);
|
||||
|
||||
let currentDesktopEntry = '';
|
||||
|
||||
try {
|
||||
currentDesktopEntry = await fsp.readFile(desktopEntryPath, 'utf8');
|
||||
} catch {
|
||||
// Create the desktop entry if auto-launch did not leave one behind.
|
||||
}
|
||||
|
||||
const nextDesktopEntry = currentDesktopEntry
|
||||
? /^Exec=.*$/m.test(currentDesktopEntry)
|
||||
? currentDesktopEntry.replace(/^Exec=.*$/m, execLine)
|
||||
: `${currentDesktopEntry.trimEnd()}\n${execLine}\n`
|
||||
: buildLinuxAutoStartDesktopEntry(launchPath);
|
||||
|
||||
if (nextDesktopEntry === currentDesktopEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
await fsp.mkdir(path.dirname(desktopEntryPath), { recursive: true });
|
||||
await fsp.writeFile(desktopEntryPath, nextDesktopEntry, 'utf8');
|
||||
}
|
||||
|
||||
function getAutoLauncher(): AutoLaunch | null {
|
||||
if (!app.isPackaged) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!autoLauncher) {
|
||||
autoLaunchPath = resolveLaunchPath();
|
||||
autoLauncher = new AutoLaunch({
|
||||
name: app.getName(),
|
||||
path: resolveLaunchPath()
|
||||
path: autoLaunchPath
|
||||
});
|
||||
}
|
||||
|
||||
@@ -37,12 +104,16 @@ async function setAutoStartEnabled(enabled: boolean): Promise<void> {
|
||||
|
||||
const currentlyEnabled = await launcher.isEnabled();
|
||||
|
||||
if (currentlyEnabled === enabled) {
|
||||
if (!enabled && currentlyEnabled === enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
await launcher.enable();
|
||||
if (!currentlyEnabled) {
|
||||
await launcher.enable();
|
||||
}
|
||||
|
||||
await synchronizeLinuxAutoStartDesktopEntry(autoLaunchPath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user