From bc8392ad52c06467c211cae81940be2b4fc0cf56 Mon Sep 17 00:00:00 2001 From: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:19:01 -0800 Subject: [PATCH] Linux: Fixes #8240: Fix print on Linux (#9810) --- packages/app-desktop/InteropServiceHelper.ts | 43 ++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/packages/app-desktop/InteropServiceHelper.ts b/packages/app-desktop/InteropServiceHelper.ts index 7c5441782..ff0c5a2f7 100644 --- a/packages/app-desktop/InteropServiceHelper.ts +++ b/packages/app-desktop/InteropServiceHelper.ts @@ -6,11 +6,12 @@ import { ExportModule } from '@joplin/lib/services/interop/Module'; import { _ } from '@joplin/lib/locale'; import { PluginStates } from '@joplin/lib/services/plugins/reducer'; -const bridge = require('@electron/remote').require('./bridge').default; +import bridge from './services/bridge'; import Setting from '@joplin/lib/models/Setting'; import Note from '@joplin/lib/models/Note'; const { friendlySafeFilename } = require('@joplin/lib/path-utils'); import time from '@joplin/lib/time'; +import { BrowserWindow } from 'electron'; const md5 = require('md5'); const url = require('url'); @@ -45,7 +46,7 @@ export default class InteropServiceHelper { } private static async exportNoteTo_(target: string, noteId: string, options: ExportNoteOptions = {}) { - let win: any = null; + let win: BrowserWindow|null = null; let htmlFile: string = null; const cleanup = () => { @@ -83,8 +84,8 @@ export default class InteropServiceHelper { // contents of the tag are visible in printed // pdfs. // https://github.com/laurent22/joplin/issues/6254. - win.webContents.executeJavaScript('document.querySelectorAll(\'details\').forEach(el=>el.setAttribute(\'open\',\'\'))'); - const data = await win.webContents.printToPDF(options); + await win.webContents.executeJavaScript('document.querySelectorAll(\'details\').forEach(el=>el.setAttribute(\'open\',\'\'))'); + const data = await win.webContents.printToPDF(options as any); resolve(data); } catch (error) { reject(error); @@ -104,21 +105,39 @@ export default class InteropServiceHelper { // https://github.com/electron/electron/issues/28192 // Still doesn't work but at least it doesn't crash // the app. + // + // 2024-01-31: Printing with webContents.print still + // fails on Linux (even if run in the main process). + // As such, we use window.print(), which seems to work. - win.webContents.print(options, (success: boolean, reason: string) => { - // TODO: This is correct but broken in Electron 4. Need to upgrade to 5+ - // It calls the callback right away with "false" even if the document hasn't be print yet. + if (shim.isLinux()) { + await win.webContents.executeJavaScript(` + // Blocks while the print dialog is open + window.print(); + `); - cleanup(); - if (!success && reason !== 'cancelled') reject(new Error(`Could not print: ${reason}`)); - resolve(null); - }); + shim.setTimeout(() => { + // To prevent a crash, the window can only be closed after a timeout. + // This timeout can't be too small, or else it may still crash (e.g. 100ms + // is too short). + // + // See https://github.com/electron/electron/issues/31635 for details + cleanup(); + resolve(null); + }, 1000); + } else { + win.webContents.print(options as any, (success: boolean, reason: string) => { + cleanup(); + if (!success && reason !== 'cancelled') reject(new Error(`Could not print: ${reason}`)); + resolve(null); + }); + } } }, 2000); }); - win.loadURL(url.format({ + void win.loadURL(url.format({ pathname: htmlFile, protocol: 'file:', slashes: true,