From 80bf53348355f2792d4e6a925630c5befc7a52a2 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sun, 26 Oct 2025 20:30:30 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20print=20preview,=20file=20loading,=20and?= =?UTF-8?q?=20PDF=20export=20-=20complete=20code=20analysis=20and=20fixes?= =?UTF-8?q?=20CRITICAL=20PRINT=20PREVIEW=20FIX:=20-=20FOUND:=20Redundant?= =?UTF-8?q?=20ipcMain=20handlers=20creating=20message=20loop=20at=20lines?= =?UTF-8?q?=201171-1182=20-=20Menu=20sends=20'print-preview'=20to=20render?= =?UTF-8?q?er=20=E2=9C=85=20-=20ipcMain.on('print-preview')=20was=20re-sen?= =?UTF-8?q?ding=20to=20renderer=20=E2=9D=8C=20(REMOVED)=20-=20Renderer=20h?= =?UTF-8?q?ideUI,=20waits=20300ms,=20sends=20'do-print'=20to=20main=20?= =?UTF-8?q?=E2=9C=85=20-=20Main=20process=20prints=20immediately=20(no=20e?= =?UTF-8?q?xtra=20delay=20needed)=20-=20Print=20now=20correctly=20captures?= =?UTF-8?q?=20hidden=20UI=20and=20shows=20preview=20content=20FILE=20LOADI?= =?UTF-8?q?NG=20ON=20DOUBLE-CLICK=20FIX:=20-=20FOUND:=20theme-changed=20ha?= =?UTF-8?q?ndler=20waiting=201500ms=20was=20too=20long=20-=20Changed=20fro?= =?UTF-8?q?m=20setTimeout=201500ms=20to=20requestAnimationFrame=20(respect?= =?UTF-8?q?s=20browser=20rendering)=20-=20renderer-ready=20signal=20sent?= =?UTF-8?q?=20after=20next=20animation=20frame=20-=20openFileFromPath=20no?= =?UTF-8?q?w=20sends=20file-opened=20immediately=20when=20rendererReady=20?= =?UTF-8?q?-=20Files=20now=20load=20and=20render=20quickly=20on=20first=20?= =?UTF-8?q?double-click=20-=20Proper=20async=20timing:=20DOMContentLoaded?= =?UTF-8?q?=20=E2=86=92=20theme=20request=20=E2=86=92=20theme=20applied=20?= =?UTF-8?q?=E2=86=92=20ready=20PDF=20EXPORT=20FALLBACK=20FIX:=20-=20When?= =?UTF-8?q?=20Pandoc=20PDF=20engines=20(XeLaTeX,=20PDFLaTeX,=20LuaLaTeX)?= =?UTF-8?q?=20unavailable=20-=20System=20now=20falls=20back=20to=20Electro?= =?UTF-8?q?n's=20built-in=20PDF=20export=20-=20Users=20get=20working=20PDF?= =?UTF-8?q?=20export=20even=20without=20LaTeX=20installed=20-=20No=20error?= =?UTF-8?q?=20dialog,=20seamless=20fallback=20to=20working=20solution=20Co?= =?UTF-8?q?de=20Analysis=20Summary:=201.=20Print:=20Eliminated=20message?= =?UTF-8?q?=20loop=20duplication=20(removed=2015=20redundant=20lines)=202.?= =?UTF-8?q?=20File=20Loading:=20Fixed=20timing=20with=20requestAnimationFr?= =?UTF-8?q?ame=20+=20immediate=20send=203.=20PDF:=20Added=20graceful=20fal?= =?UTF-8?q?lback=20instead=20of=20error=20dialog=20All=20dependencies=20al?= =?UTF-8?q?ready=20present:=20-=20html2pdf.js=20=E2=9C=85=20-=20pdf-lib=20?= =?UTF-8?q?=E2=9C=85=20-=20pdfkit=20=E2=9C=85=20=F0=9F=A4=96=20Generated?= =?UTF-8?q?=20with=20[Claude=20Code](https://claude.com/claude-code)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 49 +++++++++++++------------------------------------ src/renderer.js | 6 +++--- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/src/main.js b/src/main.js index c1227f4..de25012 100644 --- a/src/main.js +++ b/src/main.js @@ -784,13 +784,9 @@ function performExportWithOptions(format, options) { function tryPdfFallback(inputFile, outputFile, engines, index, options, lastError) { if (index >= engines.length) { - dialog.showErrorBox('PDF Export Error', - `Failed to export PDF with all available engines. Please ensure you have one of the following installed:\n` + - `• XeLaTeX (recommended): sudo apt-get install texlive-xetex\n` + - `• PDFLaTeX: sudo apt-get install texlive-latex-base\n` + - `• LuaLaTeX: sudo apt-get install texlive-luatex\n\n` + - `Last error: ${lastError.message}` - ); + // All Pandoc PDF engines failed, fallback to Electron's built-in PDF export + console.log('All Pandoc PDF engines failed, falling back to Electron PDF export'); + exportToPDFElectron(outputFile); return; } @@ -1167,33 +1163,17 @@ ipcMain.on('set-current-file', (event, filePath) => { currentFile = filePath; }); -// Handle print preview - send signal to renderer to prepare -ipcMain.on('print-preview', (event) => { - if (mainWindow) { - mainWindow.webContents.send('print-preview'); - } -}); - -// Handle print preview with styles - send signal to renderer to prepare -ipcMain.on('print-preview-styled', (event) => { - if (mainWindow) { - mainWindow.webContents.send('print-preview-styled'); - } -}); - // Handle actual printing when renderer is ready ipcMain.on('do-print', (event, { withStyles }) => { if (mainWindow) { - // Renderer has already hidden UI and prepared the page - // Small delay to ensure everything is rendered - setTimeout(() => { - mainWindow.webContents.print({ - silent: false, - printBackground: withStyles, - color: true, - margin: { marginType: 'default' } - }); - }, 50); + // Renderer has already hidden UI, waited 300ms, and prepared the page + // Print immediately - DOM is fully rendered + mainWindow.webContents.print({ + silent: false, + printBackground: withStyles, + color: true, + margin: { marginType: 'default' } + }); } }); @@ -1665,11 +1645,8 @@ function openFileFromPath(filePath) { currentFile = filePath; const content = fs.readFileSync(filePath, 'utf-8'); if (mainWindow && mainWindow.webContents && rendererReady) { - // Add delay to ensure renderer is fully prepared to display the file - // Wait for theme, preview pane, and all CSS to be fully loaded - setTimeout(() => { - mainWindow.webContents.send('file-opened', { path: filePath, content }); - }, 2000); + // Send file immediately - renderer-ready means UI is initialized + mainWindow.webContents.send('file-opened', { path: filePath, content }); } else { // Store file to open after renderer is ready app.pendingFile = filePath; diff --git a/src/renderer.js b/src/renderer.js index dd63810..0435375 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -1100,11 +1100,11 @@ ipcRenderer.on('toggle-find', () => { ipcRenderer.on('theme-changed', (event, theme) => { document.body.className = `theme-${theme}`; - // After theme is applied, wait a bit longer and then signal renderer is ready + // After theme is applied, wait for next frame then signal renderer is ready // This ensures complete UI initialization before files are opened - setTimeout(() => { + requestAnimationFrame(() => { ipcRenderer.send('renderer-ready'); - }, 1500); + }); }); // Undo/Redo handlers