// Window fullscreen adapter — replaces Tauri's // `getCurrentWindow().setFullscreen(...)` from `@tauri-apps/api/window`. // The renderer asks main to flip the OS-level fullscreen flag on the host // BrowserWindow so cinema mode covers the Windows taskbar / macOS menubar // the way Tauri's appWindow.setFullscreen used to. import { BrowserWindow, ipcMain } from 'electron'; import { CHANNELS } from '../ipc-types'; export function register(mainWindow: BrowserWindow): void { // Per-window maximize-before-fullscreen memo. We have to drop the // maximized flag on Windows before setFullScreen so DWM recomposes // cleanly (taskbar quirk), but Electron doesn't remember that the // window WAS maximized — exiting fullscreen would leave it as a small // floating window. Track it ourselves keyed by window-id so a future // multi-window setup doesn't cross-pollute state. const wasMaximized = new Map(); ipcMain.handle(CHANNELS.WINDOW_SET_FULLSCREEN, (evt, enabled: boolean) => { try { // Prefer the BrowserWindow that issued the IPC so multi-window setups // affect the right host; fall back to the main window we were // registered against (matches autostart.ts's app-singleton shape). const win = BrowserWindow.fromWebContents(evt.sender) ?? mainWindow; if (!win || win.isDestroyed()) return; const id = win.id; if (enabled) { // Windows DWM quirk: maximized → fullscreen sometimes leaves the // taskbar drawn on top of the window because DWM keeps the // maximized work-area constraints. Drop the maximize flag first // so setFullScreen covers the whole monitor cleanly. Remember the // pre-fullscreen state so the exit path can restore it. if (process.platform === 'win32') { const was = win.isMaximized(); wasMaximized.set(id, was); if (was) win.unmaximize(); } win.setFullScreen(true); } else { win.setFullScreen(false); // Restore maximize if we dropped it on entry. setFullScreen(false) // emits 'leave-full-screen' asynchronously; maximize() needs to // wait until the window is back in normal mode or it silently // no-ops. The event fires same-tick in Electron 33, but we listen // for it once just to be safe across versions. if (process.platform === 'win32' && wasMaximized.get(id)) { wasMaximized.delete(id); const restore = (): void => { if (!win.isDestroyed()) win.maximize(); }; if (win.isFullScreen()) { win.once('leave-full-screen', restore); } else { restore(); } } } } catch (err: unknown) { console.warn('window setFullscreen failed', err); throw err; } }); }