feat: system settings tab — launch at login and prevent-sleep toggles
AppSettings.system persisted through the existing settings IPC; the main process applies real side effects at startup and on every save via app.setLoginItemSettings and powerSaveBlocker.
This commit is contained in:
1 parent
db0eae5efd
commit
18506c926a
6 files changed
+116
-8
No files matched your search
@@ -2,6 +2,7 @@ import { app, BrowserWindow, shell } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { registerIpc } from './ipc'
|
||||
import { killAllPtys } from './pty'
|
||||
import { applyStartupSystemSettings, loadSettings } from './settingsStore'
|
||||
|
||||
function createWindow(): void {
|
||||
const win = new BrowserWindow({
|
||||
@@ -42,6 +43,9 @@ function createWindow(): void {
|
||||
|
||||
app.whenReady().then(() => {
|
||||
registerIpc()
|
||||
// OS-level effects (login item, sleep blocker) must apply even if the
|
||||
// settings dialog is never opened this run.
|
||||
applyStartupSystemSettings(loadSettings())
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app, ipcMain } from 'electron'
|
||||
import { app, ipcMain, powerSaveBlocker } from 'electron'
|
||||
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { Ipc } from '../shared/ipc'
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
DEFAULT_SETTINGS,
|
||||
type AppSettings,
|
||||
type HighlightRule,
|
||||
type SystemSettings,
|
||||
type TerminalSettings
|
||||
} from '../shared/settings'
|
||||
import type { TerminalTheme } from '../shared/theme'
|
||||
@@ -14,6 +15,8 @@ import { broadcast } from './broadcast'
|
||||
|
||||
const settingsPath = (): string => join(app.getPath('userData'), 'settings.json')
|
||||
|
||||
const DEFAULT_SYSTEM: SystemSettings = { launchAtLogin: false, preventSleep: false }
|
||||
|
||||
const TERMINAL_KEYS = new Set(Object.keys(DEFAULT_SETTINGS.terminal) as (keyof TerminalSettings)[])
|
||||
|
||||
/** Light structural check for a persisted highlight rule. */
|
||||
@@ -66,9 +69,53 @@ function deepMerge(raw: unknown): { settings: AppSettings; errors: string[] } {
|
||||
}
|
||||
}
|
||||
|
||||
let system: unknown = DEFAULT_SYSTEM
|
||||
if (raw !== null && typeof raw === 'object') {
|
||||
const sys = (raw as { system?: unknown }).system
|
||||
if (sys !== null && typeof sys === 'object') {
|
||||
const candidate = sys as Record<string, unknown>
|
||||
system = {
|
||||
launchAtLogin: candidate.launchAtLogin === true,
|
||||
preventSleep: candidate.preventSleep === true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const themes: TerminalTheme[] = Array.isArray(customThemes) ? (customThemes as TerminalTheme[]) : []
|
||||
|
||||
return { settings: { terminal, customThemes: themes, highlightRules: sanitizeRules(highlightRules) }, errors }
|
||||
return {
|
||||
settings: {
|
||||
terminal,
|
||||
customThemes: themes,
|
||||
highlightRules: sanitizeRules(highlightRules),
|
||||
system: system as SystemSettings
|
||||
},
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
||||
// ---- real system side effects ------------------------------------------------
|
||||
|
||||
let sleepBlockerId: number | undefined
|
||||
|
||||
/** Apply OS-level effects of the system settings (login item, sleep blocker). */
|
||||
function applySystemSettings(system: SystemSettings): void {
|
||||
try {
|
||||
app.setLoginItemSettings({ openAtLogin: system.launchAtLogin })
|
||||
} catch (err) {
|
||||
console.error('[settings] setLoginItemSettings failed', err)
|
||||
}
|
||||
if (system.preventSleep && sleepBlockerId === undefined) {
|
||||
sleepBlockerId = powerSaveBlocker.start('prevent-app-suspension')
|
||||
} else if (!system.preventSleep && sleepBlockerId !== undefined) {
|
||||
powerSaveBlocker.stop(sleepBlockerId)
|
||||
sleepBlockerId = undefined
|
||||
}
|
||||
}
|
||||
|
||||
/** Apply system side effects for the settings loaded at startup. */
|
||||
export function applyStartupSystemSettings(settings: AppSettings): void {
|
||||
applySystemSettings(settings.system)
|
||||
}
|
||||
|
||||
export function loadSettings(): AppSettings {
|
||||
@@ -80,7 +127,8 @@ export function loadSettings(): AppSettings {
|
||||
return {
|
||||
terminal: { ...DEFAULT_SETTINGS.terminal },
|
||||
customThemes: [...DEFAULT_SETTINGS.customThemes],
|
||||
highlightRules: DEFAULT_HIGHLIGHT_RULES.map((rule) => ({ ...rule }))
|
||||
highlightRules: DEFAULT_HIGHLIGHT_RULES.map((rule) => ({ ...rule })),
|
||||
system: { ...DEFAULT_SYSTEM }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,8 +137,10 @@ export function saveSettings(next: AppSettings): AppSettings {
|
||||
const merged = deepMerge({
|
||||
terminal: next.terminal,
|
||||
customThemes: next.customThemes,
|
||||
highlightRules: next.highlightRules
|
||||
highlightRules: next.highlightRules,
|
||||
system: next.system ?? DEFAULT_SYSTEM
|
||||
}).settings
|
||||
applySystemSettings(merged.system)
|
||||
const pretty = JSON.stringify(merged, null, 2)
|
||||
|
||||
mkdirSync(app.getPath('userData'), { recursive: true })
|
||||
|
||||
Reference in new issue
Block a user