From 848102905e875115855bfe2ad098f296fc03512b Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sat, 6 Jun 2026 14:03:12 +0530 Subject: [PATCH] refactor(main): extract window creation to src/main/window/ (main only, ascii/table windows removed) --- src/main.js | 72 +++--------------------------------- src/main/window/index.js | 80 ++++++++++++++++++++++++++++++++++++++++ src/main/window/state.js | 27 ++++++++++++++ 3 files changed, 112 insertions(+), 67 deletions(-) create mode 100644 src/main/window/index.js create mode 100644 src/main/window/state.js diff --git a/src/main.js b/src/main.js index 8a15265..f60840e 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,7 @@ const GitOperations = require('./main/GitOperations'); const { getAllowedDirectories, validatePath, resolveWritablePath, isPathAccessible } = require('./main/utils/paths'); const fileOps = require('./main/files'); const menu = require('./main/menu'); +const { createMainWindow } = require('./main/window'); // Add MiKTeX to PATH for LaTeX support if (process.platform === 'win32') { @@ -387,71 +388,6 @@ function checkPandocAvailability() { }); } -function createWindow() { - mainWindow = new BrowserWindow({ - width: 1200, - height: 800, - show: false, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - spellcheck: true - }, - icon: path.join(__dirname, '../assets/icon.png') - }); - - mainWindow.loadFile(path.join(__dirname, 'index.html')); - - // Show window only after content is ready — avoids blank flash - mainWindow.once('ready-to-show', () => { - mainWindow.show(); - }); - - menu.register(mainWindow); - - mainWindow.on('closed', () => { - mainWindow = null; - }); - - // Spell check context menu - mainWindow.webContents.on('context-menu', (event, params) => { - const { Menu, MenuItem } = require('electron'); - const menu = new Menu(); - - // Add spell check suggestions - if (params.misspelledWord) { - for (const suggestion of params.dictionarySuggestions) { - menu.append(new MenuItem({ - label: suggestion, - click: () => mainWindow.webContents.replaceMisspelling(suggestion) - })); - } - if (params.dictionarySuggestions.length > 0) { - menu.append(new MenuItem({ type: 'separator' })); - } - menu.append(new MenuItem({ - label: 'Add to Dictionary', - click: () => mainWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord) - })); - menu.append(new MenuItem({ type: 'separator' })); - } - - // Standard context menu items - menu.append(new MenuItem({ role: 'cut' })); - menu.append(new MenuItem({ role: 'copy' })); - menu.append(new MenuItem({ role: 'paste' })); - menu.append(new MenuItem({ role: 'selectAll' })); - - menu.popup(); - }); - - // Wait for the page to fully load before sending file data - mainWindow.webContents.on('did-finish-load', () => { - console.log('Window finished loading'); - // Don't open file here - wait for renderer-ready signal - // The renderer will send renderer-ready when TabManager is initialized - }); -} // Show About Dialog with logo @@ -3127,7 +3063,8 @@ app.whenReady().then(() => { return; // Don't create window for CLI operations } - createWindow(); + mainWindow = createMainWindow(); + mainWindow.on('closed', () => { mainWindow = null; }); // Register file ops IPC handlers fileOps.register({ @@ -3178,7 +3115,8 @@ app.on('window-all-closed', () => { app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); + mainWindow = createMainWindow(); + mainWindow.on('closed', () => { mainWindow = null; }); } }); diff --git a/src/main/window/index.js b/src/main/window/index.js new file mode 100644 index 0000000..caf20f4 --- /dev/null +++ b/src/main/window/index.js @@ -0,0 +1,80 @@ +// src/main/window/index.js +// Main window creation + +const { BrowserWindow } = require('electron'); +const path = require('path'); +const state = require('./state'); +const menu = require('../menu'); + +function createMainWindow() { + const bounds = state.load(); + const win = new BrowserWindow({ + width: bounds.width, + height: bounds.height, + x: bounds.x, + y: bounds.y, + show: false, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + spellcheck: true + }, + icon: path.join(__dirname, '../../assets/icon.png') + }); + + win.loadFile(path.join(__dirname, '../../index.html')); + + // Show window only after content is ready — avoids blank flash + win.once('ready-to-show', () => { + win.show(); + }); + + menu.register(win); + + win.on('closed', () => { + state.save(win); + }); + + // Spell check context menu + win.webContents.on('context-menu', (event, params) => { + const { Menu, MenuItem } = require('electron'); + const ctxMenu = new Menu(); + + // Add spell check suggestions + if (params.misspelledWord) { + for (const suggestion of params.dictionarySuggestions) { + ctxMenu.append(new MenuItem({ + label: suggestion, + click: () => win.webContents.replaceMisspelling(suggestion) + })); + } + if (params.dictionarySuggestions.length > 0) { + ctxMenu.append(new MenuItem({ type: 'separator' })); + } + ctxMenu.append(new MenuItem({ + label: 'Add to Dictionary', + click: () => win.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord) + })); + ctxMenu.append(new MenuItem({ type: 'separator' })); + } + + // Standard context menu items + ctxMenu.append(new MenuItem({ role: 'cut' })); + ctxMenu.append(new MenuItem({ role: 'copy' })); + ctxMenu.append(new MenuItem({ role: 'paste' })); + ctxMenu.append(new MenuItem({ role: 'selectAll' })); + + ctxMenu.popup(); + }); + + // Wait for the page to fully load before sending file data + win.webContents.on('did-finish-load', () => { + console.log('Window finished loading'); + // Don't open file here - wait for renderer-ready signal + // The renderer will send renderer-ready when TabManager is initialized + }); + + return win; +} + +module.exports = { createMainWindow }; diff --git a/src/main/window/state.js b/src/main/window/state.js new file mode 100644 index 0000000..4499ea5 --- /dev/null +++ b/src/main/window/state.js @@ -0,0 +1,27 @@ +// src/main/window/state.js +// Window state persistence (size, position) + +const { app } = require('electron'); +const path = require('path'); +const fs = require('fs'); + +const stateFile = path.join(app.getPath('userData'), 'window-state.json'); + +function load() { + try { + return JSON.parse(fs.readFileSync(stateFile, 'utf8')); + } catch { + return { width: 1200, height: 800 }; + } +} + +function save(win) { + const bounds = win.getBounds(); + try { + fs.writeFileSync(stateFile, JSON.stringify(bounds)); + } catch { + /* ignore */ + } +} + +module.exports = { load, save };