feat: add 'Close launcher on game start' option and improve app termination behavior (#93)

* update main branch to release/v2.0.2b (#86)

* add more linux pkgs, create auto-release and pre-release feature for Github Actions

* removed package-lock from gitignore

* update .gitignore for local build

* add package-lock.json to maintain stability development

* update version to 2.0.2b also add deps for rpm and arch

* update 2.0.2b: add arm64 support, product and executable name, maintainers; remove snap;

* update 2.0.2b: add latest.yml for win & linux, arm64 support; remove snap

* fix release build naming

* Prepare release v2.0.2b

* feat: add 'Close launcher on game start' option and improve app termination behavior

- Added 'Close launcher on game start' setting in GUI and backend.
- Implemented automatic app quit after game launch if setting is enabled.
- Added Cmd+Q (Mac) and Ctrl+Q/Alt+F4 (Win/Linux) shortcuts to quit the app.
- Updated 'window-close' handler to fully quit the app instead of just closing the window.
- Added i18n support for the new setting in English, Spanish, and Portuguese.

---------

Co-authored-by: Fazri Gading <fazrigading@gmail.com>
Co-authored-by: Arnav Singh <hi.arnavsingh3@gmail.com>
This commit is contained in:
Arnav Singh
2026-01-22 15:41:16 +05:30
committed by GitHub
parent a8da559e93
commit 68d697576a
11 changed files with 184 additions and 67 deletions

94
main.js
View File

@@ -2,7 +2,8 @@ const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '.env') });
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
const fs = require('fs');
const { launchGame, launchGameWithVersionCheck, installGame, saveUsername, loadUsername, saveChatUsername, loadChatUsername, saveChatColor, loadChatColor, saveJavaPath, loadJavaPath, saveInstallPath, loadInstallPath, saveDiscordRPC, loadDiscordRPC, saveLanguage, loadLanguage, isGameInstalled, uninstallGame, repairGame, getHytaleNews, handleFirstLaunchCheck, proposeGameUpdate, markAsLaunched } = require('./backend/launcher');
const { launchGame, launchGameWithVersionCheck, installGame, saveUsername, loadUsername, saveChatUsername, loadChatUsername, saveChatColor, loadChatColor, saveJavaPath, loadJavaPath, saveInstallPath, loadInstallPath, saveDiscordRPC, loadDiscordRPC, saveLanguage, loadLanguage, saveCloseLauncherOnStart, loadCloseLauncherOnStart, isGameInstalled, uninstallGame, repairGame, getHytaleNews, handleFirstLaunchCheck, proposeGameUpdate, markAsLaunched } = require('./backend/launcher');
const UpdateManager = require('./backend/updateManager');
const logger = require('./backend/logger');
const profileManager = require('./backend/managers/profileManager');
@@ -186,10 +187,21 @@ function createWindow() {
if (input.key === 'F12') {
event.preventDefault();
}
if (input.key === 'F5') {
event.preventDefault();
}
});
if (input.key === 'F5') {
event.preventDefault();
}
// Close application shortcuts
const isMac = process.platform === 'darwin';
const quitShortcut = (isMac && input.meta && input.key.toLowerCase() === 'q') ||
(!isMac && input.control && input.key.toLowerCase() === 'q') ||
(!isMac && input.alt && input.key === 'F4');
if (quitShortcut) {
app.quit();
}
});
mainWindow.webContents.on('context-menu', (e) => {
@@ -333,15 +345,14 @@ app.on('before-quit', () => {
cleanupDiscordRPC();
});
app.on('window-all-closed', () => {
console.log('=== LAUNCHER CLOSING ===');
cleanupDiscordRPC();
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('window-all-closed', () => {
console.log('=== LAUNCHER CLOSING ===');
cleanupDiscordRPC();
app.quit();
});
ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, gpuPreference) => {
try {
@@ -358,9 +369,20 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
}
};
const result = await launchGameWithVersionCheck(playerName, progressCallback, javaPath, installPath, gpuPreference);
return result;
const result = await launchGameWithVersionCheck(playerName, progressCallback, javaPath, installPath, gpuPreference);
if (result.success && result.launched) {
const closeOnStart = loadCloseLauncherOnStart();
if (closeOnStart) {
console.log('Close Launcher on start enabled, quitting application...');
setTimeout(() => {
app.quit();
}, 1000);
}
}
return result;
} catch (error) {
console.error('Launch error:', error);
const errorMessage = error.message || error.toString();
@@ -475,11 +497,21 @@ ipcMain.handle('save-language', (event, language) => {
return { success: true };
});
ipcMain.handle('load-language', () => {
return loadLanguage();
});
ipcMain.handle('select-install-path', async () => {
ipcMain.handle('load-language', () => {
return loadLanguage();
});
ipcMain.handle('save-close-launcher', (event, enabled) => {
saveCloseLauncherOnStart(enabled);
return { success: true };
});
ipcMain.handle('load-close-launcher', () => {
return loadCloseLauncherOnStart();
});
ipcMain.handle('select-install-path', async () => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ['openDirectory'],
title: 'Select Installation Folder'
@@ -804,11 +836,10 @@ ipcMain.handle('open-download-page', async () => {
try {
await shell.openExternal(updateManager.getDownloadUrl());
setTimeout(() => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.close();
}
}, 1000);
setTimeout(() => {
app.quit();
}, 1000);
return { success: true };
} catch (error) {
@@ -850,11 +881,10 @@ ipcMain.handle('get-detected-gpu', () => {
return global.detectedGpu;
});
ipcMain.handle('window-close', () => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.close();
}
});
ipcMain.handle('window-close', () => {
app.quit();
});
ipcMain.handle('window-minimize', () => {
if (mainWindow && !mainWindow.isDestroyed()) {