feat: boot-экран, стабильность Windows и оптимизация Pixi/пульта
- Экран загрузки (boot.html, bootWindow): статусы, ensureRoots и проверка лицензии, редактор после готовности; закрытие через destroy при closable:false. - Упакованное приложение на Windows: disableHardwareAcceleration, sandbox выкл. вне dev, отложенный показ редактора, ensureWindowBecomesVisible, фокус на splash при second-instance. - Vite: вход boot.html; eslint: игнор release/; тесты boot и maxFPS тикера. - Пульт: позиция курсора кисти через ref/DOM без setState на каждый move; черновик эффекта через rAF; Pixi: maxFPS 32, resolution cap, antialias off, debounce ResizeObserver, меньше частиц poisonCloud, contain на хосте. Made-with: Cursor
This commit is contained in:
+79
-4
@@ -9,16 +9,32 @@ import { ZipProjectStore } from './project/zipStore';
|
||||
import { registerDndAssetProtocol } from './protocol/dndAssetProtocol';
|
||||
import { getAppSemanticVersion, getOptionalBuildNumber } from './versionInfo';
|
||||
import { VideoPlaybackStore } from './video/videoPlaybackStore';
|
||||
import {
|
||||
createBootWindow,
|
||||
destroyBootWindow,
|
||||
setBootWindowStatus,
|
||||
waitForBootWindowReady,
|
||||
} from './windows/bootWindow';
|
||||
import {
|
||||
applyDockIconIfNeeded,
|
||||
closeMultiWindow,
|
||||
createEditorWindowDeferred,
|
||||
createWindows,
|
||||
focusEditorWindow,
|
||||
markAppQuitting,
|
||||
openMultiWindow,
|
||||
togglePresentationFullscreen,
|
||||
waitForEditorWindowReady,
|
||||
} from './windows/createWindows';
|
||||
|
||||
/**
|
||||
* На части конфигураций Windows окно Electron с `file://` остаётся чёрным из‑за GPU/композитора.
|
||||
* Отключаем аппаратное ускорение в упакованном приложении; отключить обход: `DND_DISABLE_GPU=0`.
|
||||
*/
|
||||
if (process.platform === 'win32' && app.isPackaged && process.env.DND_DISABLE_GPU !== '0') {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
app.setAppUserModelId('com.dndplayer.app');
|
||||
}
|
||||
@@ -89,6 +105,68 @@ function emitSessionState(): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Упакованное приложение: экран загрузки → проверки → редактор.
|
||||
* В dev по умолчанию без экрана; тест: `DND_SHOW_BOOT=1`. Отключить везде: `DND_SKIP_BOOT=1`.
|
||||
*/
|
||||
async function runStartupAfterHandlers(licenseService: LicenseService): Promise<void> {
|
||||
const useBootSequence =
|
||||
process.env.DND_SKIP_BOOT !== '1' && (app.isPackaged || process.env.DND_SHOW_BOOT === '1');
|
||||
|
||||
if (!useBootSequence) {
|
||||
createWindows();
|
||||
emitSessionState();
|
||||
emitEffectsState();
|
||||
emitVideoState();
|
||||
return;
|
||||
}
|
||||
|
||||
const splash = createBootWindow();
|
||||
try {
|
||||
await waitForBootWindowReady(splash);
|
||||
} catch (err) {
|
||||
console.error('[boot] splash load failed', err);
|
||||
destroyBootWindow(splash);
|
||||
createWindows();
|
||||
emitSessionState();
|
||||
emitEffectsState();
|
||||
emitVideoState();
|
||||
return;
|
||||
}
|
||||
|
||||
splash.show();
|
||||
setBootWindowStatus(splash, 'Инициализация…');
|
||||
|
||||
try {
|
||||
setBootWindowStatus(splash, 'Подготовка данных…');
|
||||
await projectStore.ensureRoots();
|
||||
} catch (e) {
|
||||
console.error('[boot] ensureRoots', e);
|
||||
}
|
||||
|
||||
setBootWindowStatus(splash, 'Устанавливаем связь…');
|
||||
setBootWindowStatus(splash, 'Проверка лицензии…');
|
||||
try {
|
||||
await licenseService.getStatus();
|
||||
} catch (e) {
|
||||
console.error('[boot] license getStatus', e);
|
||||
}
|
||||
|
||||
setBootWindowStatus(splash, 'Загрузка редактора…');
|
||||
const editor = createEditorWindowDeferred();
|
||||
await waitForEditorWindowReady(editor);
|
||||
setBootWindowStatus(splash, 'Готово');
|
||||
destroyBootWindow(splash);
|
||||
if (!editor.isDestroyed()) {
|
||||
editor.show();
|
||||
editor.focus();
|
||||
}
|
||||
|
||||
emitSessionState();
|
||||
emitEffectsState();
|
||||
emitVideoState();
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await app.whenReady();
|
||||
const licenseService = new LicenseService(app.getPath('userData'));
|
||||
@@ -334,10 +412,7 @@ async function main() {
|
||||
|
||||
installIpcRouter();
|
||||
applyDockIconIfNeeded();
|
||||
createWindows();
|
||||
emitSessionState();
|
||||
emitEffectsState();
|
||||
emitVideoState();
|
||||
await runStartupAfterHandlers(licenseService);
|
||||
|
||||
app.on('activate', () => {
|
||||
focusEditorWindow();
|
||||
|
||||
Reference in New Issue
Block a user