05870ef8fa
ScreenSharePickerModal now exposes Auflösung (Auto · 720p · 1080p · 1440p · 4K) and FPS (30 · 60) as separate pill rows instead of bundled quality presets — users can pick "1440p · 30 fps" or "4K · 30 fps" which the old preset list didn't surface. The underlying screenShareSettings framerateOverride slot already existed; the modal just stopped resetting it to null on every start and now plumbs the chosen FPS through to startScreenShare. Cinema-mode fullscreen on Windows had two defects: 1. Maximized → fullscreen left the taskbar drawn on top of the window because DWM kept the maximized work-area constraints. We now unmaximize first so DWM recomposes cleanly and setFullScreen actually covers the whole monitor including the taskbar strip. 2. Esc out of cinema came back as a small floating window even when the user had been maximized before clicking the Vollbild button — the unmaximize from (1) was never undone. We now memo the pre-fullscreen maximized flag per window-id and call win.maximize() once the leave-full-screen event has fired. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
65 lines
2.8 KiB
TypeScript
65 lines
2.8 KiB
TypeScript
// 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<number, boolean>();
|
|
|
|
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;
|
|
}
|
|
});
|
|
}
|