@theia/core 1.46.0-next.153 → 1.46.0-next.196
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/i18n/nls.cs.json +5 -2
- package/i18n/nls.de.json +5 -2
- package/i18n/nls.es.json +5 -2
- package/i18n/nls.fr.json +5 -2
- package/i18n/nls.hu.json +5 -2
- package/i18n/nls.it.json +5 -2
- package/i18n/nls.ja.json +5 -2
- package/i18n/nls.json +5 -2
- package/i18n/nls.pl.json +5 -2
- package/i18n/nls.pt-br.json +5 -2
- package/i18n/nls.pt-pt.json +5 -2
- package/i18n/nls.ru.json +5 -2
- package/i18n/nls.zh-cn.json +5 -2
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +6 -1
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/electron-browser/preload.d.ts.map +1 -1
- package/lib/electron-browser/preload.js +3 -0
- package/lib/electron-browser/preload.js.map +1 -1
- package/lib/electron-common/electron-api.d.ts +2 -0
- package/lib/electron-common/electron-api.d.ts.map +1 -1
- package/lib/electron-common/electron-api.js +2 -1
- package/lib/electron-common/electron-api.js.map +1 -1
- package/lib/electron-main/electron-api-main.d.ts.map +1 -1
- package/lib/electron-main/electron-api-main.js +3 -0
- package/lib/electron-main/electron-api-main.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +17 -1
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +84 -4
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/theia-electron-window.d.ts +6 -0
- package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
- package/lib/electron-main/theia-electron-window.js +3 -1
- package/lib/electron-main/theia-electron-window.js.map +1 -1
- package/lib/node/application-server.js +3 -3
- package/lib/node/application-server.js.map +1 -1
- package/package.json +6 -6
- package/src/browser/tree/tree-widget.tsx +7 -1
- package/src/electron-browser/preload.ts +4 -1
- package/src/electron-common/electron-api.ts +2 -0
- package/src/electron-main/electron-api-main.ts +6 -1
- package/src/electron-main/electron-main-application.ts +102 -7
- package/src/electron-main/theia-electron-window.ts +9 -1
- package/src/node/application-server.ts +3 -3
|
@@ -56,6 +56,7 @@ export interface TheiaCoreAPI {
|
|
|
56
56
|
focusWindow(name?: string): void;
|
|
57
57
|
|
|
58
58
|
showItemInFolder(fsPath: string): void;
|
|
59
|
+
openWithSystemApp(fsPath: string): void;
|
|
59
60
|
|
|
60
61
|
getTitleBarStyleAtStartup(): Promise<string>;
|
|
61
62
|
setTitleBarStyle(style: string): void;
|
|
@@ -112,6 +113,7 @@ export const CHANNEL_FOCUS_WINDOW = 'FocusWindow';
|
|
|
112
113
|
export const CHANNEL_SHOW_OPEN = 'ShowOpenDialog';
|
|
113
114
|
export const CHANNEL_SHOW_SAVE = 'ShowSaveDialog';
|
|
114
115
|
export const CHANNEL_SHOW_ITEM_IN_FOLDER = 'ShowItemInFolder';
|
|
116
|
+
export const CHANNEL_OPEN_WITH_SYSTEM_APP = 'OpenWithSystemApp';
|
|
115
117
|
export const CHANNEL_ATTACH_SECURITY_TOKEN = 'AttachSecurityToken';
|
|
116
118
|
|
|
117
119
|
export const CHANNEL_GET_TITLE_STYLE_AT_STARTUP = 'GetTitleStyleAtStartup';
|
|
@@ -53,7 +53,8 @@ import {
|
|
|
53
53
|
CHANNEL_REQUEST_SECONDARY_CLOSE,
|
|
54
54
|
CHANNEL_SET_BACKGROUND_COLOR,
|
|
55
55
|
CHANNEL_WC_METADATA,
|
|
56
|
-
CHANNEL_ABOUT_TO_CLOSE
|
|
56
|
+
CHANNEL_ABOUT_TO_CLOSE,
|
|
57
|
+
CHANNEL_OPEN_WITH_SYSTEM_APP
|
|
57
58
|
} from '../electron-common/electron-api';
|
|
58
59
|
import { ElectronMainApplication, ElectronMainApplicationContribution } from './electron-main-application';
|
|
59
60
|
import { Disposable, DisposableCollection, isOSX, MaybePromise } from '../common';
|
|
@@ -164,6 +165,10 @@ export class TheiaMainApi implements ElectronMainApplicationContribution {
|
|
|
164
165
|
shell.showItemInFolder(fsPath);
|
|
165
166
|
});
|
|
166
167
|
|
|
168
|
+
ipcMain.on(CHANNEL_OPEN_WITH_SYSTEM_APP, (event, fsPath) => {
|
|
169
|
+
shell.openPath(fsPath);
|
|
170
|
+
});
|
|
171
|
+
|
|
167
172
|
ipcMain.handle(CHANNEL_GET_TITLE_STYLE_AT_STARTUP, event => application.getTitleBarStyleAtStartup(event.sender));
|
|
168
173
|
|
|
169
174
|
ipcMain.on(CHANNEL_SET_TITLE_STYLE, (event, style) => application.setTitleBarStyle(event.sender, style));
|
|
@@ -22,16 +22,16 @@ import { AddressInfo } from 'net';
|
|
|
22
22
|
import { promises as fs } from 'fs';
|
|
23
23
|
import { existsSync, mkdirSync } from 'fs-extra';
|
|
24
24
|
import { fork, ForkOptions } from 'child_process';
|
|
25
|
-
import { DefaultTheme, FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
|
|
25
|
+
import { DefaultTheme, ElectronFrontendApplicationConfig, FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
|
|
26
26
|
import URI from '../common/uri';
|
|
27
27
|
import { FileUri } from '../common/file-uri';
|
|
28
|
-
import { Deferred } from '../common/promise-util';
|
|
28
|
+
import { Deferred, timeout } from '../common/promise-util';
|
|
29
29
|
import { MaybePromise } from '../common/types';
|
|
30
30
|
import { ContributionProvider } from '../common/contribution-provider';
|
|
31
31
|
import { ElectronSecurityTokenService } from './electron-security-token-service';
|
|
32
32
|
import { ElectronSecurityToken } from '../electron-common/electron-token';
|
|
33
33
|
import Storage = require('electron-store');
|
|
34
|
-
import { Disposable, DisposableCollection, isOSX, isWindows } from '../common';
|
|
34
|
+
import { CancellationTokenSource, Disposable, DisposableCollection, isOSX, isWindows } from '../common';
|
|
35
35
|
import { DEFAULT_WINDOW_HASH, WindowSearchParams } from '../common/window';
|
|
36
36
|
import { TheiaBrowserWindowOptions, TheiaElectronWindow, TheiaElectronWindowFactory } from './theia-electron-window';
|
|
37
37
|
import { ElectronMainApplicationGlobals } from './electron-main-constants';
|
|
@@ -182,6 +182,7 @@ export class ElectronMainApplication {
|
|
|
182
182
|
protected windows = new Map<number, TheiaElectronWindow>();
|
|
183
183
|
protected restarting = false;
|
|
184
184
|
|
|
185
|
+
/** Used to temporarily store the reference to an early created main window */
|
|
185
186
|
protected initialWindow?: BrowserWindow;
|
|
186
187
|
|
|
187
188
|
get config(): FrontendApplicationConfig {
|
|
@@ -287,16 +288,109 @@ export class ElectronMainApplication {
|
|
|
287
288
|
return this.didUseNativeWindowFrameOnStart.get(webContents.id) ? 'native' : 'custom';
|
|
288
289
|
}
|
|
289
290
|
|
|
291
|
+
protected async determineSplashScreenBounds(initialWindowBounds: { x: number, y: number, width: number, height: number }):
|
|
292
|
+
Promise<{ x: number, y: number, width: number, height: number }> {
|
|
293
|
+
const splashScreenOptions = this.getSplashScreenOptions();
|
|
294
|
+
const width = splashScreenOptions?.width ?? 640;
|
|
295
|
+
const height = splashScreenOptions?.height ?? 480;
|
|
296
|
+
|
|
297
|
+
// determine the screen on which to show the splash screen via the center of the window to show
|
|
298
|
+
const windowCenterPoint = { x: initialWindowBounds.x + (initialWindowBounds.width / 2), y: initialWindowBounds.y + (initialWindowBounds.height / 2) };
|
|
299
|
+
const { bounds } = screen.getDisplayNearestPoint(windowCenterPoint);
|
|
300
|
+
|
|
301
|
+
// place splash screen center of screen
|
|
302
|
+
const screenCenterPoint = { x: bounds.x + (bounds.width / 2), y: bounds.y + (bounds.height / 2) };
|
|
303
|
+
const x = screenCenterPoint.x - (width / 2);
|
|
304
|
+
const y = screenCenterPoint.y - (height / 2);
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
x, y, width, height
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
protected isShowWindowEarly(): boolean {
|
|
312
|
+
return !!this.config.electron.showWindowEarly &&
|
|
313
|
+
!('THEIA_ELECTRON_NO_EARLY_WINDOW' in process.env && process.env.THEIA_ELECTRON_NO_EARLY_WINDOW === '1');
|
|
314
|
+
}
|
|
315
|
+
|
|
290
316
|
protected showInitialWindow(): void {
|
|
291
|
-
if (this.
|
|
292
|
-
!('THEIA_ELECTRON_NO_EARLY_WINDOW' in process.env && process.env.THEIA_ELECTRON_NO_EARLY_WINDOW === '1')) {
|
|
293
|
-
console.log('Showing main window early');
|
|
317
|
+
if (this.isShowWindowEarly() || this.isShowSplashScreen()) {
|
|
294
318
|
app.whenReady().then(async () => {
|
|
295
319
|
const options = await this.getLastWindowOptions();
|
|
320
|
+
// If we want to show a splash screen, don't auto open the main window
|
|
321
|
+
if (this.isShowSplashScreen()) {
|
|
322
|
+
options.preventAutomaticShow = true;
|
|
323
|
+
}
|
|
296
324
|
this.initialWindow = await this.createWindow({ ...options });
|
|
297
|
-
|
|
325
|
+
|
|
326
|
+
if (this.isShowSplashScreen()) {
|
|
327
|
+
console.log('Showing splash screen');
|
|
328
|
+
this.configureAndShowSplashScreen(this.initialWindow);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Show main window early if windows shall be shown early and splash screen is not configured
|
|
332
|
+
if (this.isShowWindowEarly() && !this.isShowSplashScreen()) {
|
|
333
|
+
console.log('Showing main window early');
|
|
334
|
+
this.initialWindow.show();
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
protected async configureAndShowSplashScreen(mainWindow: BrowserWindow): Promise<BrowserWindow> {
|
|
341
|
+
const splashScreenOptions = this.getSplashScreenOptions()!;
|
|
342
|
+
console.debug('SplashScreen options', splashScreenOptions);
|
|
343
|
+
|
|
344
|
+
const splashScreenBounds = await this.determineSplashScreenBounds(mainWindow.getBounds());
|
|
345
|
+
const splashScreenWindow = new BrowserWindow({
|
|
346
|
+
...splashScreenBounds,
|
|
347
|
+
frame: false,
|
|
348
|
+
alwaysOnTop: true,
|
|
349
|
+
show: false,
|
|
350
|
+
transparent: true,
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (this.isShowWindowEarly()) {
|
|
354
|
+
console.log('Showing splash screen early');
|
|
355
|
+
splashScreenWindow.show();
|
|
356
|
+
} else {
|
|
357
|
+
splashScreenWindow.on('ready-to-show', () => {
|
|
358
|
+
splashScreenWindow.show();
|
|
298
359
|
});
|
|
299
360
|
}
|
|
361
|
+
|
|
362
|
+
splashScreenWindow.loadFile(path.resolve(this.globals.THEIA_APP_PROJECT_PATH, splashScreenOptions.content!).toString());
|
|
363
|
+
|
|
364
|
+
// close splash screen and show main window once frontend is ready or a timeout is hit
|
|
365
|
+
const cancelTokenSource = new CancellationTokenSource();
|
|
366
|
+
const minTime = timeout(splashScreenOptions.minDuration ?? 0, cancelTokenSource.token);
|
|
367
|
+
const maxTime = timeout(splashScreenOptions.maxDuration ?? 30000, cancelTokenSource.token);
|
|
368
|
+
|
|
369
|
+
const showWindowAndCloseSplashScreen = () => {
|
|
370
|
+
cancelTokenSource.cancel();
|
|
371
|
+
if (!mainWindow.isVisible()) {
|
|
372
|
+
mainWindow.show();
|
|
373
|
+
}
|
|
374
|
+
splashScreenWindow.close();
|
|
375
|
+
};
|
|
376
|
+
TheiaRendererAPI.onApplicationStateChanged(mainWindow.webContents, state => {
|
|
377
|
+
if (state === 'ready') {
|
|
378
|
+
minTime.then(() => showWindowAndCloseSplashScreen());
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
maxTime.then(() => showWindowAndCloseSplashScreen());
|
|
382
|
+
return splashScreenWindow;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
protected isShowSplashScreen(): boolean {
|
|
386
|
+
return typeof this.config.electron.splashScreenOptions === 'object' && !!this.config.electron.splashScreenOptions.content;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
protected getSplashScreenOptions(): ElectronFrontendApplicationConfig.SplashScreenOptions | undefined {
|
|
390
|
+
if (this.isShowSplashScreen()) {
|
|
391
|
+
return this.config.electron.splashScreenOptions;
|
|
392
|
+
}
|
|
393
|
+
return undefined;
|
|
300
394
|
}
|
|
301
395
|
|
|
302
396
|
/**
|
|
@@ -316,6 +410,7 @@ export class ElectronMainApplication {
|
|
|
316
410
|
electronWindow.window.on('focus', () => TheiaRendererAPI.sendWindowEvent(electronWindow.window.webContents, 'focus'));
|
|
317
411
|
this.attachSaveWindowState(electronWindow.window);
|
|
318
412
|
this.configureNativeSecondaryWindowCreation(electronWindow.window);
|
|
413
|
+
|
|
319
414
|
return electronWindow.window;
|
|
320
415
|
}
|
|
321
416
|
|
|
@@ -37,6 +37,12 @@ export interface TheiaBrowserWindowOptions extends BrowserWindowConstructorOptio
|
|
|
37
37
|
* in which case we want to invalidate the stored options and use the default options instead.
|
|
38
38
|
*/
|
|
39
39
|
screenLayout?: string;
|
|
40
|
+
/**
|
|
41
|
+
* By default, the window will be shown as soon as the content is ready to render.
|
|
42
|
+
* This can be prevented by handing over preventAutomaticShow: `true`.
|
|
43
|
+
* Use this for fine-grained control over when to show the window, e.g. to coordinate with a splash screen.
|
|
44
|
+
*/
|
|
45
|
+
preventAutomaticShow?: boolean;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
export const TheiaBrowserWindowOptions = Symbol('TheiaBrowserWindowOptions');
|
|
@@ -76,7 +82,9 @@ export class TheiaElectronWindow {
|
|
|
76
82
|
protected init(): void {
|
|
77
83
|
this._window = new BrowserWindow(this.options);
|
|
78
84
|
this._window.setMenuBarVisibility(false);
|
|
79
|
-
this.
|
|
85
|
+
if (!this.options.preventAutomaticShow) {
|
|
86
|
+
this.attachReadyToShow();
|
|
87
|
+
}
|
|
80
88
|
this.restoreMaximizedState();
|
|
81
89
|
this.attachCloseListeners();
|
|
82
90
|
this.trackApplicationState();
|
|
@@ -26,9 +26,9 @@ export class ApplicationServerImpl implements ApplicationServer {
|
|
|
26
26
|
protected readonly applicationPackage: ApplicationPackage;
|
|
27
27
|
|
|
28
28
|
getExtensionsInfos(): Promise<ExtensionInfo[]> {
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
return Promise.resolve(
|
|
29
|
+
// @ts-expect-error
|
|
30
|
+
const appInfo: ExtensionInfo[] = globalThis.extensionInfo;
|
|
31
|
+
return Promise.resolve(appInfo);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
getApplicationInfo(): Promise<ApplicationInfo | undefined> {
|