remember "allow multiple instances" #371

pull/1474/head
Mikael Finstad 3 years ago
parent d252ed3a14
commit 86f451539a
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -121,6 +121,7 @@ const defaults = {
cleanupChoices: {
trashTmpFiles: true, askForCleanup: true,
},
allowMultipleInstances: false,
};
// For portable app: https://github.com/mifi/lossless-cut/issues/645

@ -158,9 +158,7 @@ function safeRequestSingleInstanceLock(additionalData) {
return app.requestSingleInstanceLock(additionalData);
}
if (!argv.allowMultipleInstances && !safeRequestSingleInstanceLock({ argv: process.argv })) {
app.quit();
} else {
function initApp() {
// On macOS, the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the open-file and open-url events will be emitted for that.
// However when users start your app in command line, the system's single instance mechanism will be bypassed, and you have to use this method to ensure single instance.
// This can be tested with one terminal: npx electron .
@ -178,46 +176,6 @@ if (!argv.allowMultipleInstances && !safeRequestSingleInstanceLock({ argv: proce
if (argv2._) openFilesEventually(argv2._);
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
await configStore.init();
logger.info('CLI arguments', argv);
// Only if no files to open already (open-file might have already added some files)
if (filesToOpen.length === 0) filesToOpen = argv._;
const { settingsJson } = argv;
({ disableNetworking } = argv);
if (settingsJson != null) {
logger.info('initializing settings', settingsJson);
Object.entries(JSON5.parse(settingsJson)).forEach(([key, value]) => {
configStore.set(key, value);
});
}
if (isDev) {
const { default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer'); // eslint-disable-line global-require,import/no-extraneous-dependencies
installExtension(REACT_DEVELOPER_TOOLS)
.then(name => logger.info('Added Extension', name))
.catch(err => logger.error('Failed to add extension', err));
}
createWindow();
updateMenu();
const enableUpdateCheck = configStore.get('enableUpdateCheck');
if (!disableNetworking && enableUpdateCheck && !isStoreBuild) {
newVersion = await checkNewVersion();
// newVersion = '1.2.3';
if (newVersion) updateMenu();
}
});
// Quit when all windows are closed.
app.on('window-all-closed', () => {
app.quit();
@ -261,6 +219,71 @@ if (!argv.allowMultipleInstances && !safeRequestSingleInstanceLock({ argv: proce
});
}
// This promise will be fulfilled when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
// Call this immediately, to make sure we don't miss it (race condition)
const readyPromise = app.whenReady();
(async () => {
try {
logger.info('Initializing config store');
await configStore.init();
// todo remove backwards compat:
if (argv.allowMultipleInstances) configStore.set('allowMultipleInstances', true);
const allowMultipleInstances = configStore.get('allowMultipleInstances');
if (!allowMultipleInstances && !safeRequestSingleInstanceLock({ argv: process.argv })) {
logger.info('Found running instance, quitting');
app.quit();
return;
}
initApp();
logger.info('Waiting for app to become ready');
await readyPromise;
logger.info('CLI arguments', argv);
// Only if no files to open already (open-file might have already added some files)
if (filesToOpen.length === 0) filesToOpen = argv._;
const { settingsJson } = argv;
({ disableNetworking } = argv);
if (settingsJson != null) {
logger.info('initializing settings', settingsJson);
Object.entries(JSON5.parse(settingsJson)).forEach(([key, value]) => {
configStore.set(key, value);
});
}
if (isDev) {
const { default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer'); // eslint-disable-line global-require,import/no-extraneous-dependencies
installExtension(REACT_DEVELOPER_TOOLS)
.then(name => logger.info('Added Extension', name))
.catch(err => logger.error('Failed to add extension', err));
}
createWindow();
updateMenu();
const enableUpdateCheck = configStore.get('enableUpdateCheck');
if (!disableNetworking && enableUpdateCheck && !isStoreBuild) {
newVersion = await checkNewVersion();
// newVersion = '1.2.3';
if (newVersion) updateMenu();
}
} catch (err) {
logger.error('Failed to initialize', err);
}
})();
function focusWindow() {
try {
app.focus({ steal: true });

@ -32,7 +32,7 @@ const Settings = memo(({
}) => {
const { t } = useTranslation();
const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, enableTransferTimestamps, setEnableTransferTimestamps, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, setEnableOverwriteOutput, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck } = useUserSettings();
const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, enableTransferTimestamps, setEnableTransferTimestamps, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, setEnableOverwriteOutput, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck, allowMultipleInstances, setAllowMultipleInstances } = useUserSettings();
const onLangChange = useCallback((e) => {
const { value } = e.target;
@ -335,6 +335,17 @@ const Settings = memo(({
</Row>
)}
<Row>
<KeyCell>{t('Allow multiple instances of LosslessCut to run concurrently? (experimental)')}</KeyCell>
<Table.TextCell>
<Checkbox
label={t('Allow multiple instances')}
checked={allowMultipleInstances}
onChange={e => setAllowMultipleInstances(e.target.checked)}
/>
</Table.TextCell>
</Row>
<Row>
<KeyCell>{t('Enable HEVC / H265 hardware decoding (you may need to turn this off if you have problems with HEVC files)')}</KeyCell>
<Table.TextCell>

@ -131,6 +131,8 @@ export default () => {
useEffect(() => safeSetConfig({ enableUpdateCheck }), [enableUpdateCheck]);
const [cleanupChoices, setCleanupChoices] = useState(safeGetConfigInitial('cleanupChoices'));
useEffect(() => safeSetConfig({ cleanupChoices }), [cleanupChoices]);
const [allowMultipleInstances, setAllowMultipleInstances] = useState(safeGetConfigInitial('allowMultipleInstances'));
useEffect(() => safeSetConfig({ allowMultipleInstances }), [allowMultipleInstances]);
const resetKeyBindings = useCallback(() => {
@ -240,5 +242,7 @@ export default () => {
setEnableUpdateCheck,
cleanupChoices,
setCleanupChoices,
allowMultipleInstances,
setAllowMultipleInstances,
};
};

Loading…
Cancel
Save