feat(window): frameless QuickCaptureWindow centered on primary display

Task 18 of the slice plan. Lazy-creates a 640x280 alwaysOnTop
frameless window centered on the primary display's work area
(1/3 from the top). skipTaskbar to keep it out of the alt-tab
list. Auto-hides on blur so capturing-then-clicking-elsewhere
dismisses cleanly. Singleton pattern; show/hide rather than
recreate to keep the <100ms hotkey latency target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
altair823
2026-04-25 12:12:53 +09:00
parent a2be6ed47f
commit 7bd8276493

View File

@@ -0,0 +1,40 @@
import { BrowserWindow, screen } from 'electron';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
let win: BrowserWindow | null = null;
const __dirname = fileURLToPath(new URL('.', import.meta.url));
export function getQuickCaptureWindow(): BrowserWindow | null { return win; }
export function createQuickCaptureWindow(): BrowserWindow {
if (win && !win.isDestroyed()) return win;
const primary = screen.getPrimaryDisplay();
const W = 640, H = 280;
const x = Math.round((primary.workArea.width - W) / 2 + primary.workArea.x);
const y = Math.round((primary.workArea.height - H) / 3 + primary.workArea.y);
win = new BrowserWindow({
width: W, height: H, x, y,
frame: false, show: false, alwaysOnTop: true,
skipTaskbar: true, resizable: false,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
contextIsolation: true, nodeIntegration: false, sandbox: false
}
});
if (process.env.ELECTRON_RENDERER_URL) {
win.loadURL(`${process.env.ELECTRON_RENDERER_URL}/quickcapture/index.html`);
} else {
win.loadFile(join(__dirname, '../renderer/quickcapture/index.html'));
}
win.on('blur', () => { if (win?.isVisible()) win.hide(); });
return win;
}
export function showQuickCapture(): void {
const w = createQuickCaptureWindow();
w.show(); w.focus();
}