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 | var __param = (this && this.__param) || function (paramIndex, decorator) {
|
27 | return function (target, key) { decorator(target, key, paramIndex); }
|
28 | };
|
29 | Object.defineProperty(exports, "__esModule", { value: true });
|
30 | exports.CustomTitleWidget = exports.ElectronMenuContribution = exports.CustomTitleWidgetFactory = exports.ElectronMenus = exports.ElectronCommands = void 0;
|
31 | const inversify_1 = require("inversify");
|
32 | const common_1 = require("../../common");
|
33 | const browser_1 = require("../../browser");
|
34 | const electron_main_menu_factory_1 = require("./electron-main-menu-factory");
|
35 | const frontend_application_state_1 = require("../../browser/frontend-application-state");
|
36 | const frontend_application_config_provider_1 = require("../../browser/frontend-application-config-provider");
|
37 | const electron_window_preferences_1 = require("../window/electron-window-preferences");
|
38 | const browser_menu_plugin_1 = require("../../browser/menu/browser-menu-plugin");
|
39 | const window_service_1 = require("../../browser/window/window-service");
|
40 | const window_title_service_1 = require("../../browser/window/window-title-service");
|
41 | require("../../../src/electron-browser/menu/electron-menu-style.css");
|
42 | const theming_1 = require("../../browser/theming");
|
43 | var ElectronCommands;
|
44 | (function (ElectronCommands) {
|
45 | ElectronCommands.TOGGLE_DEVELOPER_TOOLS = common_1.Command.toDefaultLocalizedCommand({
|
46 | id: 'theia.toggleDevTools',
|
47 | label: 'Toggle Developer Tools'
|
48 | });
|
49 | ElectronCommands.RELOAD = common_1.Command.toDefaultLocalizedCommand({
|
50 | id: 'view.reload',
|
51 | label: 'Reload Window'
|
52 | });
|
53 | ElectronCommands.ZOOM_IN = common_1.Command.toDefaultLocalizedCommand({
|
54 | id: 'view.zoomIn',
|
55 | label: 'Zoom In'
|
56 | });
|
57 | ElectronCommands.ZOOM_OUT = common_1.Command.toDefaultLocalizedCommand({
|
58 | id: 'view.zoomOut',
|
59 | label: 'Zoom Out'
|
60 | });
|
61 | ElectronCommands.RESET_ZOOM = common_1.Command.toDefaultLocalizedCommand({
|
62 | id: 'view.resetZoom',
|
63 | label: 'Reset Zoom'
|
64 | });
|
65 | ElectronCommands.CLOSE_WINDOW = common_1.Command.toDefaultLocalizedCommand({
|
66 | id: 'close.window',
|
67 | label: 'Close Window'
|
68 | });
|
69 | ElectronCommands.TOGGLE_FULL_SCREEN = common_1.Command.toDefaultLocalizedCommand({
|
70 | id: 'workbench.action.toggleFullScreen',
|
71 | category: browser_1.CommonCommands.VIEW_CATEGORY,
|
72 | label: 'Toggle Full Screen'
|
73 | });
|
74 | })(ElectronCommands = exports.ElectronCommands || (exports.ElectronCommands = {}));
|
75 | var ElectronMenus;
|
76 | (function (ElectronMenus) {
|
77 | ElectronMenus.VIEW_WINDOW = [...browser_1.CommonMenus.VIEW, 'window'];
|
78 | ElectronMenus.VIEW_ZOOM = [...browser_1.CommonMenus.VIEW_APPEARANCE_SUBMENU, '4_appearance_submenu_zoom'];
|
79 | })(ElectronMenus = exports.ElectronMenus || (exports.ElectronMenus = {}));
|
80 | (function (ElectronMenus) {
|
81 | ElectronMenus.HELP_TOGGLE = [...browser_1.CommonMenus.HELP, 'z_toggle'];
|
82 | })(ElectronMenus = exports.ElectronMenus || (exports.ElectronMenus = {}));
|
83 | (function (ElectronMenus) {
|
84 | ElectronMenus.FILE_CLOSE = [...browser_1.CommonMenus.FILE_CLOSE, 'window-close'];
|
85 | })(ElectronMenus = exports.ElectronMenus || (exports.ElectronMenus = {}));
|
86 | exports.CustomTitleWidgetFactory = Symbol('CustomTitleWidgetFactory');
|
87 | let ElectronMenuContribution = class ElectronMenuContribution extends browser_menu_plugin_1.BrowserMenuBarContribution {
|
88 | constructor(factory) {
|
89 | super(factory);
|
90 | this.factory = factory;
|
91 | this.titleBarStyleChangeFlag = false;
|
92 | }
|
93 | onStart(app) {
|
94 | this.handleTitleBarStyling(app);
|
95 | if (common_1.isOSX) {
|
96 | this.attachWindowFocusListener(app);
|
97 | }
|
98 |
|
99 |
|
100 | let onStateChange = undefined;
|
101 | const stateServiceListener = (state) => {
|
102 | if (state === 'closing_window') {
|
103 | if (!!onStateChange) {
|
104 | onStateChange.dispose();
|
105 | }
|
106 | }
|
107 | };
|
108 | onStateChange = this.stateService.onStateChanged(stateServiceListener);
|
109 | this.shell.mainPanel.onDidToggleMaximized(() => {
|
110 | this.handleToggleMaximized();
|
111 | });
|
112 | this.shell.bottomPanel.onDidToggleMaximized(() => {
|
113 | this.handleToggleMaximized();
|
114 | });
|
115 | this.attachMenuBarVisibilityListener();
|
116 | this.themeService.onDidColorThemeChange(e => {
|
117 | this.handleThemeChange(e);
|
118 | });
|
119 | }
|
120 | attachWindowFocusListener(app) {
|
121 |
|
122 |
|
123 |
|
124 | const disposeHandler = window.electronTheiaCore.onWindowEvent('focus', () => {
|
125 | this.setMenu(app);
|
126 | });
|
127 | window.addEventListener('unload', () => disposeHandler.dispose());
|
128 | }
|
129 | attachMenuBarVisibilityListener() {
|
130 | this.preferenceService.onPreferenceChanged(e => {
|
131 | if (e.preferenceName === 'window.menuBarVisibility') {
|
132 | this.handleFullScreen(e.newValue);
|
133 | }
|
134 | });
|
135 | }
|
136 | handleTitleBarStyling(app) {
|
137 | this.hideTopPanel(app);
|
138 | window.electronTheiaCore.getTitleBarStyleAtStartup().then(style => {
|
139 | this.titleBarStyle = style;
|
140 | this.setMenu(app);
|
141 | this.preferenceService.ready.then(() => {
|
142 | this.preferenceService.set('window.titleBarStyle', this.titleBarStyle, browser_1.PreferenceScope.User);
|
143 | });
|
144 | });
|
145 | this.preferenceService.ready.then(() => {
|
146 | window.electronTheiaCore.setMenuBarVisible(['classic', 'visible'].includes(this.preferenceService.get('window.menuBarVisibility', 'classic')));
|
147 | });
|
148 | this.preferenceService.onPreferenceChanged(change => {
|
149 | if (change.preferenceName === 'window.titleBarStyle') {
|
150 | if (this.titleBarStyleChangeFlag && this.titleBarStyle !== change.newValue) {
|
151 | window.electronTheiaCore.setTitleBarStyle(change.newValue);
|
152 | this.handleRequiredRestart();
|
153 | }
|
154 | this.titleBarStyleChangeFlag = true;
|
155 | }
|
156 | });
|
157 | }
|
158 | handleToggleMaximized() {
|
159 | const preference = this.preferenceService.get('window.menuBarVisibility');
|
160 | if (preference === 'classic') {
|
161 | this.factory.setMenuBar();
|
162 | }
|
163 | }
|
164 | |
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | hideTopPanel(app) {
|
171 | const itr = app.shell.children();
|
172 | let child = itr.next();
|
173 | while (child) {
|
174 |
|
175 | if (child.id === 'theia-top-panel') {
|
176 | child.setHidden(this.titleBarStyle !== 'custom');
|
177 | break;
|
178 | }
|
179 | else {
|
180 | child = itr.next();
|
181 | }
|
182 | }
|
183 | }
|
184 | setMenu(app, electronMenu = this.factory.createElectronMenuBar()) {
|
185 | if (!common_1.isOSX) {
|
186 | this.hideTopPanel(app);
|
187 | if (this.titleBarStyle === 'custom' && !this.menuBar) {
|
188 | this.createCustomTitleBar(app);
|
189 | return;
|
190 | }
|
191 | }
|
192 | window.electronTheiaCore.setMenu(electronMenu);
|
193 | }
|
194 | createCustomTitleBar(app) {
|
195 | const dragPanel = new browser_1.Widget();
|
196 | dragPanel.id = 'theia-drag-panel';
|
197 | app.shell.addWidget(dragPanel, { area: 'top' });
|
198 | this.appendMenu(app.shell);
|
199 | this.createCustomTitleWidget(app);
|
200 | const controls = document.createElement('div');
|
201 | controls.id = 'window-controls';
|
202 | controls.append(this.createControlButton('minimize', () => window.electronTheiaCore.minimize()), this.createControlButton('maximize', () => window.electronTheiaCore.maximize()), this.createControlButton('restore', () => window.electronTheiaCore.unMaximize()), this.createControlButton('close', () => window.electronTheiaCore.close()));
|
203 | app.shell.topPanel.node.append(controls);
|
204 | this.handleWindowControls();
|
205 | }
|
206 | createCustomTitleWidget(app) {
|
207 | const titleWidget = this.customTitleWidgetFactory();
|
208 | if (titleWidget) {
|
209 | app.shell.addWidget(titleWidget, { area: 'top' });
|
210 | }
|
211 | }
|
212 | handleWindowControls() {
|
213 | toggleControlButtons();
|
214 | window.electronTheiaCore.onWindowEvent('maximize', toggleControlButtons);
|
215 | window.electronTheiaCore.onWindowEvent('unmaximize', toggleControlButtons);
|
216 | function toggleControlButtons() {
|
217 | if (window.electronTheiaCore.isMaximized()) {
|
218 | document.body.classList.add('maximized');
|
219 | }
|
220 | else {
|
221 | document.body.classList.remove('maximized');
|
222 | }
|
223 | }
|
224 | }
|
225 | createControlButton(id, handler) {
|
226 | const button = document.createElement('div');
|
227 | button.id = `${id}-button`;
|
228 | button.className = `control-button ${(0, browser_1.codicon)(`chrome-${id}`)}`;
|
229 | button.addEventListener('click', handler);
|
230 | return button;
|
231 | }
|
232 | async handleRequiredRestart() {
|
233 | const msgNode = document.createElement('div');
|
234 | const message = document.createElement('p');
|
235 | message.textContent = common_1.nls.localizeByDefault('A setting has changed that requires a restart to take effect.');
|
236 | const detail = document.createElement('p');
|
237 | detail.textContent = common_1.nls.localizeByDefault('Press the restart button to restart {0} and enable the setting.', frontend_application_config_provider_1.FrontendApplicationConfigProvider.get().applicationName);
|
238 | msgNode.append(message, detail);
|
239 | const restart = common_1.nls.localizeByDefault('Restart');
|
240 | const dialog = new browser_1.ConfirmDialog({
|
241 | title: restart,
|
242 | msg: msgNode,
|
243 | ok: restart,
|
244 | cancel: browser_1.Dialog.CANCEL
|
245 | });
|
246 | if (await dialog.open()) {
|
247 | this.windowService.setSafeToShutDown();
|
248 | window.electronTheiaCore.restart();
|
249 | }
|
250 | }
|
251 | registerCommands(registry) {
|
252 | registry.registerCommand(ElectronCommands.TOGGLE_DEVELOPER_TOOLS, {
|
253 | execute: () => {
|
254 | window.electronTheiaCore.toggleDevTools();
|
255 | }
|
256 | });
|
257 | registry.registerCommand(ElectronCommands.RELOAD, {
|
258 | execute: () => this.windowService.reload()
|
259 | });
|
260 | registry.registerCommand(ElectronCommands.CLOSE_WINDOW, {
|
261 | execute: () => window.electronTheiaCore.close()
|
262 | });
|
263 | registry.registerCommand(ElectronCommands.ZOOM_IN, {
|
264 | execute: async () => {
|
265 | const currentLevel = await window.electronTheiaCore.getZoomLevel();
|
266 |
|
267 | let zoomLevel = (Math.floor(currentLevel / electron_window_preferences_1.ZoomLevel.VARIATION) * electron_window_preferences_1.ZoomLevel.VARIATION) + electron_window_preferences_1.ZoomLevel.VARIATION;
|
268 | if (zoomLevel > electron_window_preferences_1.ZoomLevel.MAX) {
|
269 | zoomLevel = electron_window_preferences_1.ZoomLevel.MAX;
|
270 | return;
|
271 | }
|
272 | ;
|
273 | this.preferenceService.set('window.zoomLevel', zoomLevel, browser_1.PreferenceScope.User);
|
274 | }
|
275 | });
|
276 | registry.registerCommand(ElectronCommands.ZOOM_OUT, {
|
277 | execute: async () => {
|
278 | const currentLevel = await window.electronTheiaCore.getZoomLevel();
|
279 |
|
280 | let zoomLevel = (Math.ceil(currentLevel / electron_window_preferences_1.ZoomLevel.VARIATION) * electron_window_preferences_1.ZoomLevel.VARIATION) - electron_window_preferences_1.ZoomLevel.VARIATION;
|
281 | if (zoomLevel < electron_window_preferences_1.ZoomLevel.MIN) {
|
282 | zoomLevel = electron_window_preferences_1.ZoomLevel.MIN;
|
283 | return;
|
284 | }
|
285 | ;
|
286 | this.preferenceService.set('window.zoomLevel', zoomLevel, browser_1.PreferenceScope.User);
|
287 | }
|
288 | });
|
289 | registry.registerCommand(ElectronCommands.RESET_ZOOM, {
|
290 | execute: () => this.preferenceService.set('window.zoomLevel', electron_window_preferences_1.ZoomLevel.DEFAULT, browser_1.PreferenceScope.User)
|
291 | });
|
292 | registry.registerCommand(ElectronCommands.TOGGLE_FULL_SCREEN, {
|
293 | isEnabled: () => window.electronTheiaCore.isFullScreenable(),
|
294 | isVisible: () => window.electronTheiaCore.isFullScreenable(),
|
295 | execute: () => this.toggleFullScreen()
|
296 | });
|
297 | }
|
298 | registerKeybindings(registry) {
|
299 | registry.registerKeybindings({
|
300 | command: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id,
|
301 | keybinding: 'ctrlcmd+alt+i'
|
302 | }, {
|
303 | command: ElectronCommands.RELOAD.id,
|
304 | keybinding: 'ctrlcmd+r'
|
305 | }, {
|
306 | command: ElectronCommands.ZOOM_IN.id,
|
307 | keybinding: 'ctrlcmd+='
|
308 | }, {
|
309 | command: ElectronCommands.ZOOM_IN.id,
|
310 | keybinding: 'ctrlcmd+add'
|
311 | }, {
|
312 | command: ElectronCommands.ZOOM_OUT.id,
|
313 | keybinding: 'ctrlcmd+subtract'
|
314 | }, {
|
315 | command: ElectronCommands.ZOOM_OUT.id,
|
316 | keybinding: 'ctrlcmd+-'
|
317 | }, {
|
318 | command: ElectronCommands.RESET_ZOOM.id,
|
319 | keybinding: 'ctrlcmd+0'
|
320 | }, {
|
321 | command: ElectronCommands.CLOSE_WINDOW.id,
|
322 | keybinding: (common_1.isOSX ? 'cmd+shift+w' : (common_1.isWindows ? 'ctrl+w' : 'ctrl+q'))
|
323 | }, {
|
324 | command: ElectronCommands.TOGGLE_FULL_SCREEN.id,
|
325 | keybinding: common_1.isOSX ? 'ctrl+ctrlcmd+f' : 'f11'
|
326 | });
|
327 | }
|
328 | registerMenus(registry) {
|
329 | registry.registerMenuAction(ElectronMenus.HELP_TOGGLE, {
|
330 | commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id
|
331 | });
|
332 | registry.registerMenuAction(ElectronMenus.VIEW_WINDOW, {
|
333 | commandId: ElectronCommands.RELOAD.id,
|
334 | order: 'z0'
|
335 | });
|
336 | registry.registerMenuAction(ElectronMenus.VIEW_ZOOM, {
|
337 | commandId: ElectronCommands.ZOOM_IN.id,
|
338 | order: 'z1'
|
339 | });
|
340 | registry.registerMenuAction(ElectronMenus.VIEW_ZOOM, {
|
341 | commandId: ElectronCommands.ZOOM_OUT.id,
|
342 | order: 'z2'
|
343 | });
|
344 | registry.registerMenuAction(ElectronMenus.VIEW_ZOOM, {
|
345 | commandId: ElectronCommands.RESET_ZOOM.id,
|
346 | order: 'z3'
|
347 | });
|
348 | registry.registerMenuAction(ElectronMenus.FILE_CLOSE, {
|
349 | commandId: ElectronCommands.CLOSE_WINDOW.id,
|
350 | });
|
351 | registry.registerMenuAction(browser_1.CommonMenus.VIEW_APPEARANCE_SUBMENU_SCREEN, {
|
352 | commandId: ElectronCommands.TOGGLE_FULL_SCREEN.id,
|
353 | label: common_1.nls.localizeByDefault('Full Screen'),
|
354 | order: '0'
|
355 | });
|
356 | }
|
357 | toggleFullScreen() {
|
358 | window.electronTheiaCore.toggleFullScreen();
|
359 | const menuBarVisibility = this.preferenceService.get('window.menuBarVisibility', 'classic');
|
360 | this.handleFullScreen(menuBarVisibility);
|
361 | }
|
362 | handleFullScreen(menuBarVisibility) {
|
363 | const shouldShowTop = !window.electronTheiaCore.isFullScreen() || menuBarVisibility === 'visible';
|
364 | if (this.titleBarStyle === 'native') {
|
365 | window.electronTheiaCore.setMenuBarVisible(shouldShowTop);
|
366 | }
|
367 | else if (shouldShowTop) {
|
368 | this.shell.topPanel.show();
|
369 | }
|
370 | else {
|
371 | this.shell.topPanel.hide();
|
372 | }
|
373 | }
|
374 | handleThemeChange(e) {
|
375 | const backgroundColor = window.getComputedStyle(document.body).backgroundColor;
|
376 | window.electronTheiaCore.setBackgroundColor(backgroundColor);
|
377 | }
|
378 | };
|
379 | __decorate([
|
380 | (0, inversify_1.inject)(frontend_application_state_1.FrontendApplicationStateService),
|
381 | __metadata("design:type", frontend_application_state_1.FrontendApplicationStateService)
|
382 | ], ElectronMenuContribution.prototype, "stateService", void 0);
|
383 | __decorate([
|
384 | (0, inversify_1.inject)(window_service_1.WindowService),
|
385 | __metadata("design:type", Object)
|
386 | ], ElectronMenuContribution.prototype, "windowService", void 0);
|
387 | __decorate([
|
388 | (0, inversify_1.inject)(theming_1.ThemeService),
|
389 | __metadata("design:type", theming_1.ThemeService)
|
390 | ], ElectronMenuContribution.prototype, "themeService", void 0);
|
391 | __decorate([
|
392 | (0, inversify_1.inject)(exports.CustomTitleWidgetFactory),
|
393 | __metadata("design:type", Function)
|
394 | ], ElectronMenuContribution.prototype, "customTitleWidgetFactory", void 0);
|
395 | ElectronMenuContribution = __decorate([
|
396 | (0, inversify_1.injectable)(),
|
397 | __param(0, (0, inversify_1.inject)(electron_main_menu_factory_1.ElectronMainMenuFactory)),
|
398 | __metadata("design:paramtypes", [electron_main_menu_factory_1.ElectronMainMenuFactory])
|
399 | ], ElectronMenuContribution);
|
400 | exports.ElectronMenuContribution = ElectronMenuContribution;
|
401 | let CustomTitleWidget = class CustomTitleWidget extends browser_1.Widget {
|
402 | constructor() {
|
403 | super();
|
404 | this.id = 'theia-custom-title';
|
405 | }
|
406 | init() {
|
407 | this.updateTitle(this.windowTitleService.title);
|
408 | this.windowTitleService.onDidChangeTitle(title => {
|
409 | this.updateTitle(title);
|
410 | });
|
411 | }
|
412 | onResize(msg) {
|
413 | this.adjustTitleToCenter();
|
414 | super.onResize(msg);
|
415 | }
|
416 | onAfterShow(msg) {
|
417 | this.adjustTitleToCenter();
|
418 | super.onAfterShow(msg);
|
419 | }
|
420 | updateTitle(title) {
|
421 | this.node.textContent = title;
|
422 | this.adjustTitleToCenter();
|
423 | }
|
424 | adjustTitleToCenter() {
|
425 | const menubar = this.electronMenuContribution.menuBar;
|
426 | if (menubar) {
|
427 | const titleWidth = this.node.clientWidth;
|
428 | const margin = 16;
|
429 | const leftMarker = menubar.node.offsetLeft + menubar.node.clientWidth + margin;
|
430 | const panelWidth = this.applicationShell.topPanel.node.clientWidth;
|
431 | const controlsWidth = 48 * 3;
|
432 | const rightMarker = panelWidth - controlsWidth - margin;
|
433 | let hidden = false;
|
434 | let relative = false;
|
435 | this.node.style.left = '50%';
|
436 |
|
437 |
|
438 | if (rightMarker - leftMarker < titleWidth) {
|
439 | hidden = true;
|
440 | }
|
441 | else if ((panelWidth - titleWidth) / 2 < leftMarker || (panelWidth + titleWidth) / 2 > rightMarker) {
|
442 |
|
443 | relative = true;
|
444 | this.node.style.left = `${leftMarker + (rightMarker - leftMarker - titleWidth) / 2}px`;
|
445 | }
|
446 | this.node.classList.toggle('hidden', hidden);
|
447 | this.node.classList.toggle('relative', relative);
|
448 | }
|
449 | }
|
450 | };
|
451 | __decorate([
|
452 | (0, inversify_1.inject)(ElectronMenuContribution),
|
453 | __metadata("design:type", ElectronMenuContribution)
|
454 | ], CustomTitleWidget.prototype, "electronMenuContribution", void 0);
|
455 | __decorate([
|
456 | (0, inversify_1.inject)(window_title_service_1.WindowTitleService),
|
457 | __metadata("design:type", window_title_service_1.WindowTitleService)
|
458 | ], CustomTitleWidget.prototype, "windowTitleService", void 0);
|
459 | __decorate([
|
460 | (0, inversify_1.inject)(browser_1.ApplicationShell),
|
461 | __metadata("design:type", browser_1.ApplicationShell)
|
462 | ], CustomTitleWidget.prototype, "applicationShell", void 0);
|
463 | __decorate([
|
464 | (0, inversify_1.postConstruct)(),
|
465 | __metadata("design:type", Function),
|
466 | __metadata("design:paramtypes", []),
|
467 | __metadata("design:returntype", void 0)
|
468 | ], CustomTitleWidget.prototype, "init", null);
|
469 | CustomTitleWidget = __decorate([
|
470 | (0, inversify_1.injectable)(),
|
471 | __metadata("design:paramtypes", [])
|
472 | ], CustomTitleWidget);
|
473 | exports.CustomTitleWidget = CustomTitleWidget;
|
474 |
|
\ | No newline at end of file |