diff --git a/main.ts b/main.ts index 2b9125f..518ca49 100644 --- a/main.ts +++ b/main.ts @@ -709,6 +709,7 @@ if ( // Native resize tracking using Deno 2.9 BrowserWindow events let resizeTimer: ReturnType | undefined; +let sizeSeenFromEvent = false; try { win.addEventListener( "resize", @@ -720,6 +721,7 @@ try { if (w >= 1100 && h >= 700) { settings.windowWidth = w; settings.windowHeight = h; + sizeSeenFromEvent = true; } resizeTimer = setTimeout(() => { if (settings.windowWidth >= 1100 && settings.windowHeight >= 700) { @@ -740,17 +742,28 @@ try { "close", (() => { if (resizeTimer !== undefined) clearTimeout(resizeTimer); - const [fw, fh] = win.getSize(); - if (fw >= 1100 && fh >= 700) { - settings.windowWidth = fw; - settings.windowHeight = fh; + // Prefer the size reported by native resize events. getSize() has + // been observed to return a stale value (the last programmatically + // requested size) instead of the actual user-resized window size, + // which caused the same size to be saved on every close. Only fall + // back to getSize() if no resize event was ever received. + if (!sizeSeenFromEvent) { + try { + const [fw, fh] = win.getSize(); + if (fw >= 1100 && fh >= 700) { + settings.windowWidth = fw; + settings.windowHeight = fh; + } + } catch { /* ok */ } } try { const path = resolveSettingsPath(); Deno.mkdirSync(dirname(path), { recursive: true }); Deno.writeTextFileSync(path, JSON.stringify(settings, null, 2)); console.log( - `${PREFIX} Window size saved on close: ${settings.windowWidth}x${settings.windowHeight}`, + `${PREFIX} Window size saved on close: ${settings.windowWidth}x${settings.windowHeight} (source: ${ + sizeSeenFromEvent ? "resize events" : "getSize()" + })`, ); } catch (err) { console.error( diff --git a/web/app.js b/web/app.js index ff51b4d..4391290 100644 --- a/web/app.js +++ b/web/app.js @@ -126,10 +126,11 @@ async function loadPdf(index) { } loadedIndex = index; + const previousZoom = pdfViewer ? pdfViewer.zoom : 1; if (pdfViewer) { pdfViewer.destroy(); } - pdfViewer = new PdfViewer(pdfContainer); + pdfViewer = new PdfViewer(pdfContainer, { initialZoom: previousZoom }); viewer.classList.remove("loaded"); pdfMessage.hidden = false; pdfMessage.textContent = "Loading PDF\u2026"; diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 2f369f2..9e917d7 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -6,7 +6,7 @@ const ZOOM_MAX = 5; const ZOOM_STEP = 1.2; // multiplicative class PdfViewer { - constructor(container) { + constructor(container, options = {}) { this.container = container; this.generation = 0; this.loadingTask = null; @@ -15,12 +15,18 @@ class PdfViewer { this.renderTasks = new Set(); this.lastUrl = null; this.lastSize = null; - this.zoom = 1; // multiplier on fit-to-width (1 = fit width) + // multiplier on fit-to-width (1 = fit width); can be seeded from the + // previous viewer instance so zoom survives switching documents + this.zoom = Math.min( + ZOOM_MAX, + Math.max(ZOOM_MIN, options.initialZoom ?? 1), + ); this._lastRenderWidth = 0; this._resizeTimer = null; this._zoomTimer = null; this.resizeObserver = null; this._createDOM(); + this._updateZoomLabel(); this._observeResize(); }