feat(call): split resolution/fps in share picker + restore window state after fullscreen
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>
This commit is contained in:
@@ -9,6 +9,14 @@ 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
|
||||
@@ -16,7 +24,38 @@ export function register(mainWindow: BrowserWindow): void {
|
||||
// registered against (matches autostart.ts's app-singleton shape).
|
||||
const win = BrowserWindow.fromWebContents(evt.sender) ?? mainWindow;
|
||||
if (!win || win.isDestroyed()) return;
|
||||
win.setFullScreen(!!enabled);
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user