Some checks failed
Deploy Web Apps / deploy (push) Successful in 5m52s
Build Android APK / build-android-apk (push) Failing after 23m15s
Queue Release Build / prepare (push) Successful in 1m42s
Queue Release Build / build-linux (push) Failing after 9m33s
Queue Release Build / build-windows (push) Successful in 26m5s
Queue Release Build / finalize (push) Has been skipped
123 lines
3.4 KiB
TypeScript
123 lines
3.4 KiB
TypeScript
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';
|
|
import { DESKTOP_APP_DISPLAY_NAME, patchLinuxAutostartDesktopEntryNameField } from './desktop-branding.rules';
|
|
import { resolveLaunchPath } from './launch-path';
|
|
|
|
let autoLauncher: AutoLaunch | null = null;
|
|
let autoLaunchPath = '';
|
|
|
|
const LINUX_AUTO_START_ARGUMENTS = ['--no-sandbox', '%U'];
|
|
|
|
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 {
|
|
return [
|
|
'[Desktop Entry]',
|
|
'Type=Application',
|
|
'Version=1.0',
|
|
`Name=${DESKTOP_APP_DISPLAY_NAME}`,
|
|
`Comment=${DESKTOP_APP_DISPLAY_NAME} 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 = patchLinuxAutostartDesktopEntryNameField(
|
|
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: DESKTOP_APP_DISPLAY_NAME,
|
|
path: autoLaunchPath
|
|
});
|
|
}
|
|
|
|
return autoLauncher;
|
|
}
|
|
|
|
async function setAutoStartEnabled(enabled: boolean): Promise<void> {
|
|
const launcher = getAutoLauncher();
|
|
|
|
if (!launcher) {
|
|
return;
|
|
}
|
|
|
|
const currentlyEnabled = await launcher.isEnabled();
|
|
|
|
if (!enabled && currentlyEnabled === enabled) {
|
|
return;
|
|
}
|
|
|
|
if (enabled) {
|
|
if (!currentlyEnabled) {
|
|
await launcher.enable();
|
|
}
|
|
|
|
await synchronizeLinuxAutoStartDesktopEntry(autoLaunchPath);
|
|
return;
|
|
}
|
|
|
|
await launcher.disable();
|
|
}
|
|
|
|
export async function synchronizeAutoStartSetting(enabled = readDesktopSettings().autoStart): Promise<void> {
|
|
try {
|
|
await setAutoStartEnabled(enabled);
|
|
} catch {
|
|
// Auto-launch integration should never block app startup or settings saves.
|
|
}
|
|
}
|