1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
18 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
19 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
20 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
21 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
22 | };
|
23 | var __metadata = (this && this.__metadata) || function (k, v) {
|
24 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
25 | };
|
26 | Object.defineProperty(exports, "__esModule", { value: true });
|
27 | exports.ElectronMainApplication = exports.ElectronMainProcessArgv = exports.ElectronMainApplicationContribution = exports.ElectronMainApplicationGlobals = void 0;
|
28 | const inversify_1 = require("inversify");
|
29 | const electron_1 = require("../../electron-shared/electron");
|
30 | const path = require("path");
|
31 | const fs_1 = require("fs");
|
32 | const child_process_1 = require("child_process");
|
33 | const application_props_1 = require("@theia/application-package/lib/application-props");
|
34 | const file_uri_1 = require("../node/file-uri");
|
35 | const promise_util_1 = require("../common/promise-util");
|
36 | const contribution_provider_1 = require("../common/contribution-provider");
|
37 | const electron_security_token_service_1 = require("./electron-security-token-service");
|
38 | const electron_token_1 = require("../electron-common/electron-token");
|
39 | const Storage = require("electron-store");
|
40 | const common_1 = require("../common");
|
41 | const window_1 = require("../common/window");
|
42 | const theia_electron_window_1 = require("./theia-electron-window");
|
43 | const electron_main_constants_1 = require("./electron-main-constants");
|
44 | Object.defineProperty(exports, "ElectronMainApplicationGlobals", { enumerable: true, get: function () { return electron_main_constants_1.ElectronMainApplicationGlobals; } });
|
45 | const event_utils_1 = require("./event-utils");
|
46 | const electron_api_main_1 = require("./electron-api-main");
|
47 | const frontend_application_state_1 = require("../common/frontend-application-state");
|
48 | const dynamic_require_1 = require("../node/dynamic-require");
|
49 | const createYargs = require('yargs/yargs');
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | exports.ElectronMainApplicationContribution = Symbol('ElectronMainApplicationContribution');
|
70 |
|
71 |
|
72 | let ElectronMainProcessArgv = class ElectronMainProcessArgv {
|
73 | get processArgvBinIndex() {
|
74 |
|
75 |
|
76 | if (this.isBundledElectronApp) {
|
77 | return 0;
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 | return 1;
|
83 | }
|
84 | get isBundledElectronApp() {
|
85 |
|
86 |
|
87 | return this.isElectronApp && !process.defaultApp;
|
88 | }
|
89 | get isElectronApp() {
|
90 |
|
91 |
|
92 | return !!process.versions.electron;
|
93 | }
|
94 | getProcessArgvWithoutBin(argv = process.argv) {
|
95 | return argv.slice(this.processArgvBinIndex + 1);
|
96 | }
|
97 | getProcessArgvBin(argv = process.argv) {
|
98 | return argv[this.processArgvBinIndex];
|
99 | }
|
100 | };
|
101 | ElectronMainProcessArgv = __decorate([
|
102 | (0, inversify_1.injectable)()
|
103 | ], ElectronMainProcessArgv);
|
104 | exports.ElectronMainProcessArgv = ElectronMainProcessArgv;
|
105 | let ElectronMainApplication = class ElectronMainApplication {
|
106 | constructor() {
|
107 | this.electronStore = new Storage();
|
108 | this._backendPort = new promise_util_1.Deferred();
|
109 | this.backendPort = this._backendPort.promise;
|
110 | this.useNativeWindowFrame = true;
|
111 | this.didUseNativeWindowFrameOnStart = new Map();
|
112 | this.windows = new Map();
|
113 | this.restarting = false;
|
114 | }
|
115 | get config() {
|
116 | if (!this._config) {
|
117 | throw new Error('You have to start the application first.');
|
118 | }
|
119 | return this._config;
|
120 | }
|
121 | async start(config) {
|
122 | this.useNativeWindowFrame = this.getTitleBarStyle(config) === 'native';
|
123 | this._config = config;
|
124 | this.hookApplicationEvents();
|
125 | this.showInitialWindow();
|
126 | const port = await this.startBackend();
|
127 | this._backendPort.resolve(port);
|
128 | await electron_1.app.whenReady();
|
129 | await this.attachElectronSecurityToken(port);
|
130 | await this.startContributions();
|
131 | await this.launch({
|
132 | secondInstance: false,
|
133 | argv: this.processArgv.getProcessArgvWithoutBin(process.argv),
|
134 | cwd: process.cwd()
|
135 | });
|
136 | }
|
137 | getTitleBarStyle(config) {
|
138 | var _a;
|
139 | if (common_1.isOSX) {
|
140 | return 'native';
|
141 | }
|
142 | const storedFrame = (_a = this.electronStore.get('windowstate')) === null || _a === void 0 ? void 0 : _a.frame;
|
143 | if (storedFrame !== undefined) {
|
144 | return !!storedFrame ? 'native' : 'custom';
|
145 | }
|
146 | if (config.preferences && config.preferences['window.titleBarStyle']) {
|
147 | const titleBarStyle = config.preferences['window.titleBarStyle'];
|
148 | if (titleBarStyle === 'native' || titleBarStyle === 'custom') {
|
149 | return titleBarStyle;
|
150 | }
|
151 | }
|
152 | return common_1.isWindows ? 'custom' : 'native';
|
153 | }
|
154 | setTitleBarStyle(webContents, style) {
|
155 | this.useNativeWindowFrame = common_1.isOSX || style === 'native';
|
156 | this.saveState(webContents);
|
157 | }
|
158 | setBackgroundColor(webContents, backgroundColor) {
|
159 | this.customBackgroundColor = backgroundColor;
|
160 | this.saveState(webContents);
|
161 | }
|
162 | saveState(webContents) {
|
163 | const browserWindow = electron_1.BrowserWindow.fromWebContents(webContents);
|
164 | if (browserWindow) {
|
165 | this.saveWindowState(browserWindow);
|
166 | }
|
167 | else {
|
168 | console.warn(`no BrowserWindow with id: ${webContents.id}`);
|
169 | }
|
170 | }
|
171 | |
172 |
|
173 |
|
174 |
|
175 | getTitleBarStyleAtStartup(webContents) {
|
176 | return this.didUseNativeWindowFrameOnStart.get(webContents.id) ? 'native' : 'custom';
|
177 | }
|
178 | showInitialWindow() {
|
179 | if (this.config.electron.showWindowEarly) {
|
180 | electron_1.app.whenReady().then(async () => {
|
181 | const options = await this.getLastWindowOptions();
|
182 | this.initialWindow = await this.createWindow({ ...options });
|
183 | this.initialWindow.show();
|
184 | });
|
185 | }
|
186 | }
|
187 | async launch(params) {
|
188 | createYargs(params.argv, params.cwd)
|
189 | .command('$0 [file]', false, cmd => cmd
|
190 | .positional('file', { type: 'string' }), args => this.handleMainCommand(params, { file: args.file })).parse();
|
191 | }
|
192 | |
193 |
|
194 |
|
195 |
|
196 |
|
197 | async createWindow(asyncOptions = this.getDefaultTheiaWindowOptions()) {
|
198 | let options = await asyncOptions;
|
199 | options = this.avoidOverlap(options);
|
200 | const electronWindow = this.windowFactory(options, this.config);
|
201 | const id = electronWindow.window.webContents.id;
|
202 | this.windows.set(id, electronWindow);
|
203 | electronWindow.onDidClose(() => this.windows.delete(id));
|
204 | electronWindow.window.on('maximize', () => electron_api_main_1.TheiaRendererAPI.sendWindowEvent(electronWindow.window.webContents, 'maximize'));
|
205 | electronWindow.window.on('unmaximize', () => electron_api_main_1.TheiaRendererAPI.sendWindowEvent(electronWindow.window.webContents, 'unmaximize'));
|
206 | electronWindow.window.on('focus', () => electron_api_main_1.TheiaRendererAPI.sendWindowEvent(electronWindow.window.webContents, 'focus'));
|
207 | this.attachSaveWindowState(electronWindow.window);
|
208 | this.configureNativeSecondaryWindowCreation(electronWindow.window);
|
209 | return electronWindow.window;
|
210 | }
|
211 | async getLastWindowOptions() {
|
212 | const previousWindowState = this.electronStore.get('windowstate');
|
213 | const windowState = (previousWindowState === null || previousWindowState === void 0 ? void 0 : previousWindowState.screenLayout) === this.getCurrentScreenLayout()
|
214 | ? previousWindowState
|
215 | : this.getDefaultTheiaWindowOptions();
|
216 | return {
|
217 | frame: this.useNativeWindowFrame,
|
218 | ...this.getDefaultOptions(),
|
219 | ...windowState
|
220 | };
|
221 | }
|
222 | avoidOverlap(options) {
|
223 | const existingWindowsBounds = electron_1.BrowserWindow.getAllWindows().map(window => window.getBounds());
|
224 | if (existingWindowsBounds.length > 0) {
|
225 | while (existingWindowsBounds.some(window => window.x === options.x || window.y === options.y)) {
|
226 |
|
227 | if (options.isMaximized || options.isFullScreen) {
|
228 | options = this.getDefaultTheiaWindowOptions();
|
229 | }
|
230 | options.x = options.x + 30;
|
231 | options.y = options.y + 30;
|
232 | }
|
233 | }
|
234 | return options;
|
235 | }
|
236 | getDefaultOptions() {
|
237 | var _a, _b;
|
238 | return {
|
239 | show: false,
|
240 | title: this.config.applicationName,
|
241 | backgroundColor: application_props_1.DefaultTheme.defaultBackgroundColor(((_a = this.config.electron.windowOptions) === null || _a === void 0 ? void 0 : _a.darkTheme) || electron_1.nativeTheme.shouldUseDarkColors),
|
242 | minWidth: 200,
|
243 | minHeight: 120,
|
244 | webPreferences: {
|
245 |
|
246 | contextIsolation: true,
|
247 | sandbox: false,
|
248 | nodeIntegration: false,
|
249 |
|
250 |
|
251 | nodeIntegrationInWorker: false,
|
252 | preload: path.resolve(this.globals.THEIA_APP_PROJECT_PATH, 'lib', 'frontend', 'preload.js').toString()
|
253 | },
|
254 | ...((_b = this.config.electron) === null || _b === void 0 ? void 0 : _b.windowOptions) || {},
|
255 | };
|
256 | }
|
257 | async openDefaultWindow(params) {
|
258 | const options = this.getDefaultTheiaWindowOptions();
|
259 | const [uri, electronWindow] = await Promise.all([this.createWindowUri(params), this.reuseOrCreateWindow(options)]);
|
260 | electronWindow.loadURL(uri.withFragment(window_1.DEFAULT_WINDOW_HASH).toString(true));
|
261 | return electronWindow;
|
262 | }
|
263 | async openWindowWithWorkspace(workspacePath) {
|
264 | const options = await this.getLastWindowOptions();
|
265 | const [uri, electronWindow] = await Promise.all([this.createWindowUri(), this.reuseOrCreateWindow(options)]);
|
266 | electronWindow.loadURL(uri.withFragment(encodeURI(workspacePath)).toString(true));
|
267 | return electronWindow;
|
268 | }
|
269 | async reuseOrCreateWindow(asyncOptions) {
|
270 | if (!this.initialWindow) {
|
271 | return this.createWindow(asyncOptions);
|
272 | }
|
273 |
|
274 | const window = this.initialWindow;
|
275 | this.initialWindow = undefined;
|
276 | return window;
|
277 | }
|
278 |
|
279 | configureNativeSecondaryWindowCreation(electronWindow) {
|
280 | electronWindow.webContents.setWindowOpenHandler(() => {
|
281 | const { minWidth, minHeight } = this.getDefaultOptions();
|
282 | const options = {
|
283 | ...this.getDefaultTheiaWindowBounds(),
|
284 |
|
285 |
|
286 |
|
287 | frame: true,
|
288 | minWidth,
|
289 | minHeight
|
290 | };
|
291 | if (!this.useNativeWindowFrame) {
|
292 |
|
293 |
|
294 | options.icon = electron_1.nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12P4DwQACfsD/WMmxY8AAAAASUVORK5CYII=');
|
295 | }
|
296 | return {
|
297 | action: 'allow',
|
298 | overrideBrowserWindowOptions: options,
|
299 | };
|
300 | });
|
301 | }
|
302 | |
303 |
|
304 |
|
305 | requestStop() {
|
306 | electron_1.app.quit();
|
307 | }
|
308 | async handleMainCommand(params, options) {
|
309 | if (params.secondInstance === false) {
|
310 | await this.openWindowWithWorkspace('');
|
311 | }
|
312 | else if (options.file === undefined) {
|
313 | await this.openDefaultWindow();
|
314 | }
|
315 | else {
|
316 | let workspacePath;
|
317 | try {
|
318 | workspacePath = await fs_1.promises.realpath(path.resolve(params.cwd, options.file));
|
319 | }
|
320 | catch {
|
321 | console.error(`Could not resolve the workspace path. "${options.file}" is not a valid 'file' option. Falling back to the default workspace location.`);
|
322 | }
|
323 | if (workspacePath === undefined) {
|
324 | await this.openDefaultWindow();
|
325 | }
|
326 | else {
|
327 | await this.openWindowWithWorkspace(workspacePath);
|
328 | }
|
329 | }
|
330 | }
|
331 | async createWindowUri(params = {}) {
|
332 | if (!('port' in params)) {
|
333 | params.port = (await this.backendPort).toString();
|
334 | }
|
335 | const query = Object.entries(params).map(([name, value]) => `${name}=${value}`).join('&');
|
336 | return file_uri_1.FileUri.create(this.globals.THEIA_FRONTEND_HTML_PATH)
|
337 | .withQuery(query);
|
338 | }
|
339 | getDefaultTheiaWindowOptions() {
|
340 | return {
|
341 | frame: this.useNativeWindowFrame,
|
342 | isFullScreen: false,
|
343 | isMaximized: false,
|
344 | ...this.getDefaultTheiaWindowBounds(),
|
345 | ...this.getDefaultOptions()
|
346 | };
|
347 | }
|
348 | getDefaultTheiaWindowBounds() {
|
349 |
|
350 |
|
351 |
|
352 |
|
353 | const { bounds } = electron_1.screen.getDisplayNearestPoint(electron_1.screen.getCursorScreenPoint());
|
354 | const height = Math.round(bounds.height * (2 / 3));
|
355 | const width = Math.round(bounds.width * (2 / 3));
|
356 | const y = Math.round(bounds.y + (bounds.height - height) / 2);
|
357 | const x = Math.round(bounds.x + (bounds.width - width) / 2);
|
358 | return {
|
359 | width,
|
360 | height,
|
361 | x,
|
362 | y
|
363 | };
|
364 | }
|
365 | |
366 |
|
367 |
|
368 | attachSaveWindowState(electronWindow) {
|
369 | const windowStateListeners = new common_1.DisposableCollection();
|
370 | let delayedSaveTimeout;
|
371 | const saveWindowStateDelayed = () => {
|
372 | if (delayedSaveTimeout) {
|
373 | clearTimeout(delayedSaveTimeout);
|
374 | }
|
375 | delayedSaveTimeout = setTimeout(() => this.saveWindowState(electronWindow), 1000);
|
376 | };
|
377 | (0, event_utils_1.createDisposableListener)(electronWindow, 'close', () => {
|
378 | this.saveWindowState(electronWindow);
|
379 | }, windowStateListeners);
|
380 | (0, event_utils_1.createDisposableListener)(electronWindow, 'resize', saveWindowStateDelayed, windowStateListeners);
|
381 | (0, event_utils_1.createDisposableListener)(electronWindow, 'move', saveWindowStateDelayed, windowStateListeners);
|
382 | windowStateListeners.push(common_1.Disposable.create(() => { try {
|
383 | this.didUseNativeWindowFrameOnStart.delete(electronWindow.webContents.id);
|
384 | }
|
385 | catch { } }));
|
386 | this.didUseNativeWindowFrameOnStart.set(electronWindow.webContents.id, this.useNativeWindowFrame);
|
387 | electronWindow.once('closed', () => windowStateListeners.dispose());
|
388 | }
|
389 | saveWindowState(electronWindow) {
|
390 |
|
391 | if (!electronWindow) {
|
392 | return;
|
393 | }
|
394 | try {
|
395 | const bounds = electronWindow.getBounds();
|
396 | const options = {
|
397 | isFullScreen: electronWindow.isFullScreen(),
|
398 | isMaximized: electronWindow.isMaximized(),
|
399 | width: bounds.width,
|
400 | height: bounds.height,
|
401 | x: bounds.x,
|
402 | y: bounds.y,
|
403 | frame: this.useNativeWindowFrame,
|
404 | screenLayout: this.getCurrentScreenLayout(),
|
405 | backgroundColor: this.customBackgroundColor
|
406 | };
|
407 | this.electronStore.set('windowstate', options);
|
408 | }
|
409 | catch (e) {
|
410 | console.error('Error while saving window state:', e);
|
411 | }
|
412 | }
|
413 | |
414 |
|
415 |
|
416 | getCurrentScreenLayout() {
|
417 | return electron_1.screen.getAllDisplays().map(display => `${display.bounds.x}:${display.bounds.y}:${display.bounds.width}:${display.bounds.height}`).sort().join('-');
|
418 | }
|
419 | |
420 |
|
421 |
|
422 |
|
423 |
|
424 | async startBackend() {
|
425 |
|
426 | const noBackendFork = process.argv.indexOf('--no-cluster') !== -1;
|
427 |
|
428 |
|
429 |
|
430 | process.env.THEIA_APP_PROJECT_PATH = this.globals.THEIA_APP_PROJECT_PATH;
|
431 |
|
432 |
|
433 | process.env.THEIA_ELECTRON_VERSION = process.versions.electron;
|
434 | if (noBackendFork) {
|
435 | process.env[electron_token_1.ElectronSecurityToken] = JSON.stringify(this.electronSecurityToken);
|
436 |
|
437 | (0, dynamic_require_1.dynamicRequire)(this.globals.THEIA_BACKEND_MAIN_PATH);
|
438 |
|
439 | const address = await globalThis.serverAddress;
|
440 | return address.port;
|
441 | }
|
442 | else {
|
443 | const backendProcess = (0, child_process_1.fork)(this.globals.THEIA_BACKEND_MAIN_PATH, this.processArgv.getProcessArgvWithoutBin(), await this.getForkOptions());
|
444 | return new Promise((resolve, reject) => {
|
445 |
|
446 | backendProcess.on('message', (address) => {
|
447 | resolve(address.port);
|
448 | });
|
449 | backendProcess.on('error', error => {
|
450 | reject(error);
|
451 | });
|
452 | backendProcess.on('exit', () => {
|
453 | reject(new Error('backend process exited'));
|
454 | });
|
455 | electron_1.app.on('quit', () => {
|
456 |
|
457 |
|
458 | if (backendProcess.exitCode === null && backendProcess.signalCode === null) {
|
459 | try {
|
460 |
|
461 |
|
462 | if (backendProcess.pid) {
|
463 | process.kill(backendProcess.pid);
|
464 | }
|
465 | }
|
466 | catch (error) {
|
467 |
|
468 | if (error.code === 'ESRCH') {
|
469 | return;
|
470 | }
|
471 | throw error;
|
472 | }
|
473 | }
|
474 | });
|
475 | });
|
476 | }
|
477 | }
|
478 | async getForkOptions() {
|
479 | return {
|
480 |
|
481 |
|
482 | detached: process.platform !== 'win32',
|
483 | env: {
|
484 | ...process.env,
|
485 | [electron_token_1.ElectronSecurityToken]: JSON.stringify(this.electronSecurityToken),
|
486 | },
|
487 | };
|
488 | }
|
489 | async attachElectronSecurityToken(port) {
|
490 | await this.electronSecurityTokenService.setElectronSecurityTokenCookie(`http://localhost:${port}`);
|
491 | }
|
492 | hookApplicationEvents() {
|
493 | electron_1.app.on('will-quit', this.onWillQuit.bind(this));
|
494 | electron_1.app.on('second-instance', this.onSecondInstance.bind(this));
|
495 | electron_1.app.on('window-all-closed', this.onWindowAllClosed.bind(this));
|
496 | }
|
497 | onWillQuit(event) {
|
498 | this.stopContributions();
|
499 | }
|
500 | async onSecondInstance(event, argv, cwd) {
|
501 | const electronWindows = electron_1.BrowserWindow.getAllWindows();
|
502 | if (electronWindows.length > 0) {
|
503 | const electronWindow = electronWindows[0];
|
504 | if (electronWindow.isMinimized()) {
|
505 | electronWindow.restore();
|
506 | }
|
507 | electronWindow.focus();
|
508 | }
|
509 | }
|
510 | onWindowAllClosed(event) {
|
511 | if (!this.restarting) {
|
512 | this.requestStop();
|
513 | }
|
514 | }
|
515 | async restart(webContents) {
|
516 | this.restarting = true;
|
517 | const wrapper = this.windows.get(webContents.id);
|
518 | if (wrapper) {
|
519 | const listener = wrapper.onDidClose(async () => {
|
520 | listener.dispose();
|
521 | await this.launch({
|
522 | secondInstance: false,
|
523 | argv: this.processArgv.getProcessArgvWithoutBin(process.argv),
|
524 | cwd: process.cwd()
|
525 | });
|
526 | this.restarting = false;
|
527 | });
|
528 |
|
529 | if (!await wrapper.close(frontend_application_state_1.StopReason.Restart)) {
|
530 | listener.dispose();
|
531 | }
|
532 | }
|
533 | }
|
534 | async startContributions() {
|
535 | const promises = [];
|
536 | for (const contribution of this.contributions.getContributions()) {
|
537 | if (contribution.onStart) {
|
538 | promises.push(contribution.onStart(this));
|
539 | }
|
540 | }
|
541 | await Promise.all(promises);
|
542 | }
|
543 | stopContributions() {
|
544 | for (const contribution of this.contributions.getContributions()) {
|
545 | if (contribution.onStop) {
|
546 | contribution.onStop(this);
|
547 | }
|
548 | }
|
549 | }
|
550 | };
|
551 | __decorate([
|
552 | (0, inversify_1.inject)(contribution_provider_1.ContributionProvider),
|
553 | (0, inversify_1.named)(exports.ElectronMainApplicationContribution),
|
554 | __metadata("design:type", Object)
|
555 | ], ElectronMainApplication.prototype, "contributions", void 0);
|
556 | __decorate([
|
557 | (0, inversify_1.inject)(electron_main_constants_1.ElectronMainApplicationGlobals),
|
558 | __metadata("design:type", Object)
|
559 | ], ElectronMainApplication.prototype, "globals", void 0);
|
560 | __decorate([
|
561 | (0, inversify_1.inject)(ElectronMainProcessArgv),
|
562 | __metadata("design:type", ElectronMainProcessArgv)
|
563 | ], ElectronMainApplication.prototype, "processArgv", void 0);
|
564 | __decorate([
|
565 | (0, inversify_1.inject)(electron_security_token_service_1.ElectronSecurityTokenService),
|
566 | __metadata("design:type", electron_security_token_service_1.ElectronSecurityTokenService)
|
567 | ], ElectronMainApplication.prototype, "electronSecurityTokenService", void 0);
|
568 | __decorate([
|
569 | (0, inversify_1.inject)(electron_token_1.ElectronSecurityToken),
|
570 | __metadata("design:type", Object)
|
571 | ], ElectronMainApplication.prototype, "electronSecurityToken", void 0);
|
572 | __decorate([
|
573 | (0, inversify_1.inject)(theia_electron_window_1.TheiaElectronWindowFactory),
|
574 | __metadata("design:type", Function)
|
575 | ], ElectronMainApplication.prototype, "windowFactory", void 0);
|
576 | ElectronMainApplication = __decorate([
|
577 | (0, inversify_1.injectable)()
|
578 | ], ElectronMainApplication);
|
579 | exports.ElectronMainApplication = ElectronMainApplication;
|
580 |
|
\ | No newline at end of file |