mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-09-10 22:04:11 +00:00
feat(window): persist main window size/position across launches (#97)
* feat(window): persist main window size/position across launches The main window always opened at a fixed 1400x900, forcing a manual resize every session. Save the window geometry (normal bounds + maximized flag) to the existing desktop prefs store on close, and restore it in createWindow. Saved bounds are validated by a pure sanitizer against the current display layout before use, so stale state degrades safely instead of producing an off-screen or absurd window: - garbage/partial config -> 1400x900 centered defaults - size clamped between the 800x600 window minimums and the largest display's workArea - position kept only when the window overlaps a display by at least 100x50 px (unplugged monitor / resolution change -> re-center); negative multi-monitor coordinates remain valid - maximized sessions save getNormalBounds() and re-maximize on restore; fullscreen deliberately restores windowed No new dependency; reuses get/setDesktopConfig (atomic write, fail-soft) in soundfont-manager.ts. The store file is already in the reset-app-settings delete-set, so a config reset also resets bounds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: gionnibgud <gionnibgud@gmail.com> * fix(window): don't crash shutdown if bounds persistence write fails The close listener called setDesktopConfig synchronously with no error handling; a disk-full or permissions failure during the write would throw unhandled inside the close handler, risking a shutdown crash. Wrap the write in try/catch and log a warning instead. Flagged by CodeRabbit on PR #97. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: gionnibgud <gionnibgud@gmail.com> --------- Signed-off-by: gionnibgud <gionnibgud@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f66c27b459
commit
6349ed4c5f
+34
-5
@@ -56,7 +56,7 @@ if (process.platform !== 'linux') {
|
||||
}
|
||||
// ──────────────────────────────────────────────────────────────────────────
|
||||
|
||||
import { app, BrowserWindow, ipcMain, dialog, shell, session, crashReporter, powerSaveBlocker, systemPreferences } from 'electron';
|
||||
import { app, BrowserWindow, ipcMain, dialog, shell, session, crashReporter, powerSaveBlocker, systemPreferences, screen } from 'electron';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import { execFileSync } from 'child_process';
|
||||
@@ -125,6 +125,7 @@ import { initSoundfontManager, getDesktopConfig, setDesktopConfig } from './soun
|
||||
import * as updateManager from './update-manager';
|
||||
import type { UpdateChannel } from './update-manager';
|
||||
import { installAppMenu } from './app-menu';
|
||||
import { sanitizeWindowBounds, MIN_WIDTH, MIN_HEIGHT } from './window-bounds';
|
||||
|
||||
// Linux: enable Chromium's PipeWire capturer feature so getUserMedia can see
|
||||
// audio devices on PipeWire-only distros (Fedora 36+, recent Ubuntu, Arch).
|
||||
@@ -455,15 +456,43 @@ function isLocalServiceUrl(url: string, backendPort: number): boolean {
|
||||
}
|
||||
|
||||
function createWindow(port: number): void {
|
||||
// Restore the previous session's window geometry, validated against the
|
||||
// current display layout so stale bounds (unplugged monitor, resolution
|
||||
// change, hand-edited config) can't put the window off-screen. When x/y
|
||||
// are absent Electron centers the window as before.
|
||||
const restored = sanitizeWindowBounds(
|
||||
getDesktopConfig().windowBounds,
|
||||
screen.getAllDisplays().map((d) => d.workArea),
|
||||
);
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1400,
|
||||
height: 900,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
x: restored.x,
|
||||
y: restored.y,
|
||||
width: restored.width,
|
||||
height: restored.height,
|
||||
minWidth: MIN_WIDTH,
|
||||
minHeight: MIN_HEIGHT,
|
||||
title: 'fee[dB]ack',
|
||||
backgroundColor: '#0f172a', // slate-900 to match Slopsmith UI
|
||||
webPreferences: rendererWebPreferences,
|
||||
});
|
||||
if (restored.maximized) mainWindow.maximize();
|
||||
|
||||
// Persist geometry on close. getNormalBounds() so a maximized session
|
||||
// saves the underlying windowed size, restored + re-maximized next launch.
|
||||
// ponytail: fullscreen is deliberately not persisted (launching straight
|
||||
// into fullscreen is jarring, especially on macOS) and we save on close
|
||||
// only — a crash loses the last session's geometry; add debounced
|
||||
// resize/move saving if that ever matters.
|
||||
mainWindow.on('close', () => {
|
||||
if (!mainWindow || mainWindow.isDestroyed()) return;
|
||||
try {
|
||||
setDesktopConfig({
|
||||
windowBounds: { ...mainWindow.getNormalBounds(), maximized: mainWindow.isMaximized() },
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('[main] Failed to persist window bounds on close:', err);
|
||||
}
|
||||
});
|
||||
|
||||
// Forward renderer console to main process stdout
|
||||
mainWindow.webContents.on('console-message', (_event, level, message, line, sourceId) => {
|
||||
|
||||
Reference in New Issue
Block a user