@@ -6,9 +6,9 @@ const __filename = fileURLToPath(import.meta.url)
66const __dirname = path . dirname ( __filename )
77
88import type { BrowserWindowConstructorOptions } from 'electron'
9- import { app , BrowserWindow , ipcMain , screen , nativeTheme } from 'electron'
10- import { isDev } from './config.js'
11- import { appConfig } from './electron-store/configuration.js'
9+ import { app , BrowserWindow , ipcMain , screen } from 'electron'
10+ import { isDev , WINDOW_HEIGHT , WINDOW_WIDTH } from './config.js'
11+ import { appConfig , type AppBounds , type Settings } from './electron-store/configuration.js'
1212import type { ChildProcess } from 'node:child_process'
1313import { spawn , spawnSync } from 'node:child_process'
1414
@@ -18,14 +18,14 @@ let halquit: boolean = false
1818
1919async function createWindow ( ) {
2020 const { width, height } = screen . getPrimaryDisplay ( ) . workAreaSize
21- const appBounds : any = ( appConfig as any ) . get ( 'setting.appBounds' )
21+ const appBounds = appConfig . get < AppBounds | undefined > ( 'setting.appBounds' )
2222 const BrowserWindowOptions : BrowserWindowConstructorOptions = {
23- width : 1366 ,
24- minWidth : 1366 ,
25- height : 768 ,
26- minHeight : 768 ,
23+ width : WINDOW_WIDTH ,
24+ minWidth : WINDOW_WIDTH ,
25+ height : WINDOW_HEIGHT ,
26+ minHeight : WINDOW_HEIGHT ,
2727 webPreferences : {
28- preload : `${ __dirname } /preload.js` ,
28+ preload : `${ __dirname } /preload.js` ,
2929 devTools : false ,
3030 nodeIntegration : false ,
3131 contextIsolation : true
@@ -36,7 +36,9 @@ async function createWindow() {
3636 fullscreen : true
3737 }
3838
39- if ( appBounds !== undefined && appBounds !== null ) { Object . assign ( BrowserWindowOptions , appBounds ) }
39+ if ( appBounds !== undefined && appBounds !== null ) {
40+ Object . assign ( BrowserWindowOptions , appBounds )
41+ }
4042 mainWindow = new BrowserWindow ( BrowserWindowOptions )
4143
4244 // Remove menu bar
@@ -53,11 +55,13 @@ async function createWindow() {
5355 if (
5456 appBounds !== undefined &&
5557 appBounds !== null &&
56- appBounds . width > width &&
57- appBounds . height > height
58- )
59- { mainWindow . maximize ( ) }
60- else { mainWindow . show ( ) }
58+ ( appBounds . width ?? 0 ) > width &&
59+ ( appBounds . height ?? 0 ) > height
60+ ) {
61+ mainWindow . maximize ( )
62+ } else {
63+ mainWindow . show ( )
64+ }
6165
6266 // this will turn off always on top after opening the application
6367 setTimeout ( ( ) => {
@@ -73,60 +77,26 @@ async function createWindow() {
7377 } ) )
7478}
7579
76- // Settings handlers (global)
77- ipcMain . handle ( 'getSettings' , ( ) => ( {
78- diameterMode : ( appConfig as any ) . get ( 'setting.diameterMode' ) ,
79- defaultMetricOnStartup : ( appConfig as any ) . get ( 'setting.defaultMetricOnStartup' ) ,
80- selectedThreadingTab : ( appConfig as any ) . get ( 'setting.selectedThreadingTab' , 0 ) ,
81- selectedTurningTab : ( appConfig as any ) . get ( 'setting.selectedTurningTab' , 0 ) ,
82- selectedPitchTab : ( appConfig as any ) . get ( 'setting.selectedPitchTab' , [ 0 , 0 ] ) ,
83- pitchX : ( appConfig as any ) . get ( 'setting.pitchX' , 0.0 ) ,
84- pitchZ : ( appConfig as any ) . get ( 'setting.pitchZ' , 0.0 ) ,
85- encoderScaleZ : ( appConfig as any ) . get ( 'setting.encoderScaleZ' , 0.001 ) ,
86- encoderScaleX : ( appConfig as any ) . get ( 'setting.encoderScaleX' , - 0.001 ) ,
87- tools : ( appConfig as any ) . get ( 'setting.tools' ) ,
88- currentToolIndex : ( appConfig as any ) . get ( 'setting.currentToolIndex' , 0 ) ,
89- currentToolOffsetX : ( appConfig as any ) . get ( 'setting.currentToolOffsetX' , 0 ) ,
90- currentToolOffsetZ : ( appConfig as any ) . get ( 'setting.currentToolOffsetZ' , 0 )
91- } ) )
92-
93- // IMPORTANT: This handler should save ALL settings passed from useSettings.ts
94- // If you add new settings, make sure they're included both here AND in useSettings.ts
95- // Do NOT create duplicate save logic elsewhere - use the useSettings saveSettings function
96- ipcMain . handle ( 'saveSettings' , ( event , settings ) => {
97- const currentSettings = ( appConfig as any ) . get ( 'setting' , { } )
98- ; ( appConfig as any ) . set ( 'setting' , {
99- ...currentSettings ,
100- diameterMode : settings . diameterMode ,
101- defaultMetricOnStartup : settings . defaultMetricOnStartup ,
102- selectedThreadingTab : settings . selectedThreadingTab ,
103- selectedTurningTab : settings . selectedTurningTab ,
104- selectedPitchTab : settings . selectedPitchTab ,
105- pitchX : settings . pitchX ,
106- pitchZ : settings . pitchZ ,
107- encoderScaleZ : settings . encoderScaleZ ,
108- encoderScaleX : settings . encoderScaleX ,
109- tools : settings . tools ,
110- currentToolIndex : settings . currentToolIndex ,
111- currentToolOffsetX : settings . currentToolOffsetX ,
112- currentToolOffsetZ : settings . currentToolOffsetZ
113- } )
80+ // Settings handlers — transparent passthrough.
81+ // The schema (fields + defaults) lives in elle-frontend/src/composables/useSettings.ts.
82+ // This handler just reads/writes the `setting` blob so adding a new field only touches one file.
83+ ipcMain . handle ( 'getSettings' , ( ) => appConfig . get < Settings > ( 'setting' , { } as Settings ) )
84+
85+ ipcMain . handle ( 'saveSettings' , ( _event , settings : Settings ) => {
86+ const current = appConfig . get < Settings > ( 'setting' , { } as Settings )
87+ appConfig . set ( 'setting' , { ...current , ...settings } )
11488 return true
11589} )
11690
11791app . commandLine . appendSwitch ( 'gtk-version' , '3' )
11892
11993app . whenReady ( ) . then ( async ( ) => {
120- // Force dark mode for the entire application
121- nativeTheme . themeSource = 'dark'
122-
12394 if ( isDev ) {
12495 try {
12596 const { installExt } = await import ( './installDevTool.js' )
12697 await installExt ( )
127- // eslint-disable-next-line @typescript-eslint/no-unused-vars
128- } catch ( _e ) {
129- // Ignore errors during dev tool installation
98+ } catch {
99+ // best-effort: dev tools are optional
130100 }
131101 }
132102 createWindow ( )
@@ -173,13 +143,13 @@ ipcMain.on('quit', () => {
173143} )
174144
175145ipcMain . on ( 'startHAL' , ( ) => {
176- const hal_path = `${ process . cwd ( ) } /elle-hal`
177- const halfile_path = `${ process . cwd ( ) } /elle-hal/lathe.hal`
146+ const hal_path = `${ process . cwd ( ) } /elle-hal`
147+ const halfile_path = `${ process . cwd ( ) } /elle-hal/lathe.hal`
178148 if ( fs . existsSync ( halfile_path ) ) {
179149 try {
180150 cleanMess ( )
181151 const env = process . env
182- env . PATH += `:${ hal_path } `
152+ env . PATH += `:${ hal_path } `
183153 halrun = spawn ( 'unbuffer' , [ 'linuxcnc' , 'lathe.ini' ] , { cwd : hal_path , env : env } )
184154 halrun . stdout ?. on ( 'data' , ( stdout : Buffer ) => {
185155 mainWindow . webContents . send ( 'halStdout' , stdout . toString ( ) )
@@ -190,7 +160,7 @@ ipcMain.on('startHAL', () => {
190160 halrun . stderr ?. on ( 'data' , ( stderr : Buffer ) => {
191161 mainWindow . webContents . send ( 'halStdout' , stderr . toString ( ) )
192162 } )
193- halrun . on ( 'exit' , ( _code : any ) => {
163+ halrun . on ( 'exit' , ( ) => {
194164 mainWindow . webContents . send ( 'halStopped' )
195165 cleanMess ( )
196166 if ( halquit ) {
0 commit comments