From 7297f7c339186f8af50f4f0ed3734e4ad4b47aed Mon Sep 17 00:00:00 2001 From: haoyuren <13851610112@163.com> Date: Thu, 30 Jul 2026 09:00:55 +0800 Subject: Cross-platform support: Windows build target and CI release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Normalize watcher paths to forward slashes (Windows events use backslashes; all sync maps are '/'-keyed), path.delimiter for PATH/TEXINPUTS, dirname() instead of '/'-substring splits, bridge log in os.tmpdir() - Platform-aware TeX search paths (TeX Live / MiKTeX on Windows), terminal shell default (COMSPEC/powershell), native window frame off macOS - electron-builder: NSIS target + win icon + GitHub publish provider - GitHub Actions workflow builds the Windows installer on tag push (node-pty needs MSVC — cannot cross-compile from macOS) and attaches it to the release Co-Authored-By: Claude Fable 5 --- src/main/index.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'src/main/index.ts') diff --git a/src/main/index.ts b/src/main/index.ts index 4f23762..8dffc26 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,7 +2,7 @@ // Licensed under AGPL-3.0 - see LICENSE file import { app, BrowserWindow, ipcMain, dialog, shell, net } from 'electron' -import { join, basename, dirname, relative, extname } from 'path' +import { join, basename, dirname, relative, extname, delimiter } from 'path' import { copyFile, readFile, writeFile, mkdir as mkdirAsync, unlink, readdir, stat, rename as fsRename, rm, cp } from 'fs/promises' import { existsSync } from 'fs' import { spawn } from 'child_process' @@ -125,8 +125,11 @@ function createWindow(): void { height: 900, minWidth: 900, minHeight: 600, - titleBarStyle: 'hiddenInset', - trafficLightPosition: { x: 15, y: 15 }, + // Frameless inset title bar is a macOS affordance; use the native + // frame elsewhere + ...(process.platform === 'darwin' + ? { titleBarStyle: 'hiddenInset' as const, trafficLightPosition: { x: 15, y: 15 } } + : {}), webPreferences: { preload: join(__dirname, '../preload/index.js'), sandbox: false, @@ -255,19 +258,25 @@ ipcMain.handle('settings:setApiKeys', async (_e, keys: Record) = // ── LaTeX Compilation ──────────────────────────────────────────── -// Ensure TeX binaries are in PATH (Electron launched from Finder may miss them) -const texPaths = ['/Library/TeX/texbin', '/usr/local/texlive/2024/bin/universal-darwin', '/usr/texbin', '/opt/homebrew/bin'] +// Ensure TeX binaries are in PATH (GUI-launched apps may miss them) +const texPaths = process.platform === 'win32' + ? [ + 'C:\\texlive\\2025\\bin\\windows', + 'C:\\texlive\\2024\\bin\\windows', + join(process.env.LOCALAPPDATA || '', 'Programs', 'MiKTeX', 'miktex', 'bin', 'x64') + ] + : ['/Library/TeX/texbin', '/usr/local/texlive/2024/bin/universal-darwin', '/usr/texbin', '/opt/homebrew/bin'] const currentPath = process.env.PATH || '' for (const p of texPaths) { if (!currentPath.includes(p)) { - process.env.PATH = `${p}:${process.env.PATH}` + process.env.PATH = `${p}${delimiter}${process.env.PATH}` } } // SyncTeX: PDF position → source file:line (inverse search) ipcMain.handle('synctex:editFromPdf', async (_e, pdfPath: string, page: number, x: number, y: number) => { return new Promise<{ file: string; line: number } | null>((resolve) => { - const pdfDir = pdfPath.substring(0, pdfPath.lastIndexOf('/')) + const pdfDir = dirname(pdfPath) console.log(`[synctex] edit -o ${page}:${x}:${y}:${pdfPath} (cwd: ${pdfDir})`) const proc = spawn('synctex', ['edit', '-o', `${page}:${x}:${y}:${pdfPath}`], { env: process.env, @@ -418,8 +427,10 @@ ipcMain.handle('pty:spawn', async (_e, id: string, cwd: string, cmd?: string, ar ptyInstances.delete(id) } - const shellPath = cmd || process.env.SHELL || '/bin/zsh' - const shellArgs = args || ['-l'] + const shellPath = cmd || (process.platform === 'win32' + ? process.env.COMSPEC || 'powershell.exe' + : process.env.SHELL || '/bin/zsh') + const shellArgs = args || (process.platform === 'win32' ? [] : ['-l']) const ptyEnv: Record = { ...(process.env as Record), TERM: 'xterm-256color', -- cgit v1.2.3