feat(editor): настройки экрана презентации при запуске сессии
Выбор монитора и полноэкранного режима в настройках; при «Запустить» окно презентации открывается на выбранном дисплее автоматически. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,8 +2,12 @@ import path from 'node:path';
|
||||
|
||||
import { app, BrowserWindow, screen } from 'electron';
|
||||
|
||||
import type { PresentationSettings } from '../../shared/types/presentationSettings';
|
||||
import { readPresentationSettings } from '../preferences/appPreferences';
|
||||
|
||||
import { windowChromeTitle, type AppWindowKind } from '../../shared/appBranding';
|
||||
import { ipcChannels } from '../../shared/ipc/contracts';
|
||||
import { resolvePresentationDisplay } from './presentationDisplay';
|
||||
|
||||
import { safeConsoleError } from '../safeConsole';
|
||||
|
||||
@@ -517,20 +521,36 @@ export function focusEditorWindow(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function openMultiWindow() {
|
||||
export function openMultiWindow(presentationSettings?: PresentationSettings) {
|
||||
const settings = presentationSettings ?? readPresentationSettings(app.getPath('userData'));
|
||||
let presentation = windows.get('presentation');
|
||||
if (!presentation) {
|
||||
const display = screen.getPrimaryDisplay();
|
||||
const display = resolvePresentationDisplay(settings.displayId);
|
||||
const { x, y, width, height } = display.bounds;
|
||||
presentation = createWindow('presentation');
|
||||
presentation.setBounds({ x, y, width, height });
|
||||
presentation.setMenuBarVisibility(false);
|
||||
presentation.maximize();
|
||||
if (settings.fullScreen) {
|
||||
presentation.setFullScreen(true);
|
||||
} else {
|
||||
presentation.maximize();
|
||||
}
|
||||
}
|
||||
if (!windows.has('control')) {
|
||||
// macOS: parent-child window binding moves child with the parent (unlike Windows behavior we want).
|
||||
// Keep control window independent on darwin.
|
||||
createWindow('control', process.platform === 'darwin' ? undefined : { parent: presentation });
|
||||
const editor = windows.get('editor');
|
||||
const editorDisplay = editor
|
||||
? screen.getDisplayMatching(editor.getBounds())
|
||||
: screen.getPrimaryDisplay();
|
||||
const control = createWindow('control');
|
||||
const area = editorDisplay.workArea;
|
||||
const cw = Math.min(1200, Math.max(640, area.width - 80));
|
||||
const ch = Math.min(800, Math.max(480, area.height - 80));
|
||||
control.setBounds({
|
||||
x: area.x + Math.max(0, Math.round((area.width - cw) / 2)),
|
||||
y: area.y + Math.max(0, Math.round((area.height - ch) / 2)),
|
||||
width: cw,
|
||||
height: ch,
|
||||
});
|
||||
}
|
||||
broadcastMultiWindowStateChanged(true);
|
||||
broadcastPresentationContentSize();
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { screen, type Display } from 'electron';
|
||||
|
||||
import type { DisplayInfo } from '../../shared/types/presentationSettings';
|
||||
|
||||
export function listDisplayInfos(): DisplayInfo[] {
|
||||
const primaryId = screen.getPrimaryDisplay().id;
|
||||
return screen.getAllDisplays().map((d) => displayToInfo(d, d.id === primaryId));
|
||||
}
|
||||
|
||||
function displayToInfo(display: Display, isPrimary: boolean): DisplayInfo {
|
||||
const label = display.label?.trim() || `Display ${String(display.id)}`;
|
||||
return {
|
||||
id: display.id,
|
||||
label,
|
||||
width: display.bounds.width,
|
||||
height: display.bounds.height,
|
||||
isPrimary,
|
||||
};
|
||||
}
|
||||
|
||||
export function resolvePresentationDisplay(displayId: number | null): Display {
|
||||
if (displayId != null) {
|
||||
const found = screen.getAllDisplays().find((d) => d.id === displayId);
|
||||
if (found) return found;
|
||||
}
|
||||
return screen.getPrimaryDisplay();
|
||||
}
|
||||
Reference in New Issue
Block a user