From 11c186f18462da9f879907dbea29ff6facba391e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 17 Jun 2018 12:14:35 +0200 Subject: [PATCH] some cleanup and :lipstick: --- src/vs/code/electron-main/window.ts | 14 ++++-- src/vs/platform/windows/common/windowsIpc.ts | 1 - .../windows/electron-main/windowsService.ts | 1 + src/vs/workbench/browser/layout.ts | 2 +- .../browser/parts/menubar/menubarPart.ts | 4 +- .../parts/titlebar/media/titlebarpart.css | 5 +- .../browser/parts/titlebar/titlebarPart.ts | 49 +++++++++++-------- .../electron-browser/media/shell.css | 18 +++---- .../workbench/electron-browser/workbench.ts | 19 ++++--- .../fileActions.contribution.ts | 3 +- .../electron-browser/files.contribution.ts | 4 -- 11 files changed, 65 insertions(+), 55 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 2c991fb949a..85abd41d972 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -385,12 +385,18 @@ export class CodeWindow implements ICodeWindow { // Window (Un)Maximize this._win.on('maximize', (e) => { - this.currentConfig.maximized = true; + if (this.currentConfig) { + this.currentConfig.maximized = true; + } + app.emit('browser-window-maximize', e, this._win); }); this._win.on('unmaximize', (e) => { - this.currentConfig.maximized = false; + if (this.currentConfig) { + this.currentConfig.maximized = false; + } + app.emit('browser-window-unmaximize', e, this._win); }); @@ -596,7 +602,6 @@ export class CodeWindow implements ICodeWindow { // Set fullscreen state windowConfiguration.fullscreen = this._win.isFullScreen(); - windowConfiguration.maximized = this._win.isMaximized(); // Set Accessibility Config let autoDetectHighContrast = true; @@ -609,6 +614,9 @@ export class CodeWindow implements ICodeWindow { // Theme windowConfiguration.baseTheme = this.getBaseTheme(); windowConfiguration.backgroundColor = this.getBackgroundColor(); + + // Title style related + windowConfiguration.maximized = this._win.isMaximized(); windowConfiguration.frameless = this.hasHiddenTitleBarStyle() && !isMacintosh; // Perf Counters diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 05dcf11fea9..04deb592138 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -179,7 +179,6 @@ export class WindowsChannelClient implements IWindowsService { private _onWindowUnmaximize: Event = eventFromCall(this.channel, 'event:onWindowUnmaximize'); get onWindowUnmaximize(): Event { return this._onWindowUnmaximize; } - pickFileFolderAndOpen(options: INativeOpenDialogOptions): TPromise { return this.channel.call('pickFileFolderAndOpen', options); } diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index ac6540e2981..47441d7e6f9 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -341,6 +341,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable } minimizeWindow(windowId: number): TPromise { + this.logService.trace('windowsService#minimizeWindow', windowId); const codeWindow = this.windowsMainService.getWindowById(windowId); if (codeWindow) { diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index fffba4de832..325b14f8506 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -434,7 +434,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr this.statusbarHeight = isStatusbarHidden ? 0 : this.partLayoutInfo.statusbar.height; this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / getZoomFactor(); // adjust for zoom prevention - this.menubarHeight = isMenubarHidden ? 0 : this.partLayoutInfo.menubar.height / getZoomFactor(); + this.menubarHeight = isMenubarHidden ? 0 : this.partLayoutInfo.menubar.height / getZoomFactor(); // adjust for zoom prevention this.headingHeight = Math.max(this.menubarHeight, this.titlebarHeight); this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.headingHeight; diff --git a/src/vs/workbench/browser/parts/menubar/menubarPart.ts b/src/vs/workbench/browser/parts/menubar/menubarPart.ts index a64265cc5a3..8cbceb2a0d7 100644 --- a/src/vs/workbench/browser/parts/menubar/menubarPart.ts +++ b/src/vs/workbench/browser/parts/menubar/menubarPart.ts @@ -18,7 +18,7 @@ import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/commo import { ActionRunner, IActionRunner, IAction } from 'vs/base/common/actions'; import { Builder, $ } from 'vs/base/browser/builder'; import { Separator, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { EventType, Dimension } from 'vs/base/browser/dom'; +import { EventType, Dimension, toggleClass } from 'vs/base/browser/dom'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { isWindows, isMacintosh } from 'vs/base/common/platform'; @@ -630,7 +630,7 @@ export class MenubarPart extends Part { this.container.style('background-color', null); } - this.container.getHTMLElement().classList.toggle('light', Color.fromHex(bgColor).isLighter()); + toggleClass(this.container.getHTMLElement(), 'light', Color.fromHex(bgColor).isLighter()); } } diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 0ecaa4cbc91..fc61158b914 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -29,9 +29,8 @@ zoom: 1; /* prevent zooming */ } -/***********************\ -| Windows and Linux CSS | -\***********************/ +/* Windows/Linux: Rules for custom title (icon, window controls) */ + .monaco-workbench.windows > .part.titlebar, .monaco-workbench.linux > .part.titlebar { padding: 0; diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 27b5346de92..229ef8bfe91 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -27,7 +27,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme'; -import { isMacintosh, isWindows } from 'vs/base/common/platform'; +import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; import { Color } from 'vs/base/common/color'; import { trim } from 'vs/base/common/strings'; @@ -48,6 +48,7 @@ export class TitlebarPart extends Part implements ITitleService { private title: Builder; private windowControls: Builder; private appIcon: Builder; + private pendingTitle: string; private representedFileName: string; private menubarWidth: number; @@ -58,7 +59,7 @@ export class TitlebarPart extends Part implements ITitleService { controlsWidth?: number; appIconWidth?: number; appIconLeftPadding?: number; - } = {}; + } = Object.create(null); private isInactive: boolean; @@ -248,13 +249,14 @@ export class TitlebarPart extends Part implements ITitleService { public createContentArea(parent: HTMLElement): HTMLElement { this.titleContainer = $(parent); + // App Icon (Windows/Linux) if (!isMacintosh) { - // App Icon this.appIcon = $(this.titleContainer).img({ class: 'window-appicon', src: paths.join(this.environmentService.appRoot, isWindows ? 'resources/win32/code.ico' : 'resources/linux/code.png') - }).on(EventType.DBLCLICK, (e) => { + }).on(EventType.DBLCLICK, e => { EventHelper.stop(e, true); + this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); @@ -284,29 +286,32 @@ export class TitlebarPart extends Part implements ITitleService { } }); + // Window Controls (Windows/Linux) if (!isMacintosh) { this.windowControls = $(this.titleContainer).div({ class: 'window-controls-container' }); + // Minimize $(this.windowControls).div({ class: 'window-icon window-minimize' }).on(EventType.CLICK, () => { this.windowService.minimizeWindow().then(null, errors.onUnexpectedError); }); - let maxRestore = $(this.windowControls).div({ class: 'window-icon window-max-restore' }); - maxRestore.on(EventType.CLICK, (e, builder) => { + // Restore + $(this.windowControls).div({ class: 'window-icon window-max-restore' }).on(EventType.CLICK, () => { this.windowService.isMaximized().then((maximized) => { if (maximized) { return this.windowService.unmaximizeWindow(); - } else { - return this.windowService.maximizeWindow(); } + + return this.windowService.maximizeWindow(); }).then(null, errors.onUnexpectedError); }); + // Close $(this.windowControls).div({ class: 'window-icon window-close' }).on(EventType.CLICK, () => { this.windowService.closeWindow().then(null, errors.onUnexpectedError); }); - let isMaximized = this.windowService.getConfiguration().maximized ? true : false; + const isMaximized = this.windowService.getConfiguration().maximized ? true : false; this.onDidChangeMaximized(isMaximized); this.windowService.onDidChangeMaximize(this.onDidChangeMaximized, this); } @@ -326,17 +331,17 @@ export class TitlebarPart extends Part implements ITitleService { } private onDidChangeMaximized(maximized: boolean) { - let element = $(this.titleContainer).getHTMLElement().querySelector('.window-max-restore'); + const element = $(this.titleContainer).getHTMLElement().querySelector('.window-max-restore') as HTMLElement; if (!element) { return; } if (maximized) { - removeClass(element, 'window-maximize'); - addClass(element, 'window-unmaximize'); + removeClass(element, 'window-maximize'); + addClass(element, 'window-unmaximize'); } else { - removeClass(element, 'window-unmaximize'); - addClass(element, 'window-maximize'); + removeClass(element, 'window-unmaximize'); + addClass(element, 'window-maximize'); } } @@ -345,15 +350,17 @@ export class TitlebarPart extends Part implements ITitleService { // Part container if (this.titleContainer) { - const bgColor = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); - this.titleContainer.style('color', this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_FOREGROUND : TITLE_BAR_ACTIVE_FOREGROUND)); - this.titleContainer.style('background-color', bgColor); - if (Color.fromHex(bgColor).isLighter()) { + const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); + this.titleContainer.style('background-color', titleBackground); + if (Color.fromHex(titleBackground).isLighter()) { this.titleContainer.addClass('light'); } else { this.titleContainer.removeClass('light'); } + const titleForeground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_FOREGROUND : TITLE_BAR_ACTIVE_FOREGROUND); + this.titleContainer.style('color', titleForeground); + const titleBorder = this.getColor(TITLE_BAR_BORDER); this.titleContainer.style('border-bottom', titleBorder ? `1px solid ${titleBorder}` : null); } @@ -423,6 +430,7 @@ export class TitlebarPart extends Part implements ITitleService { } private updateLayout() { + // To prevent zooming we need to adjust the font size with the zoom factor if (typeof this.initialSizing.titleFontSize !== 'number') { this.initialSizing.titleFontSize = parseInt(this.titleContainer.getComputedStyle().fontSize, 10); @@ -439,7 +447,8 @@ export class TitlebarPart extends Part implements ITitleService { 'line-height': `${newHeight}px` }); - if (!isMacintosh) { + // Windows/Linux specific layout + if (isWindows || isLinux) { if (typeof this.initialSizing.controlsWidth !== 'number') { this.initialSizing.controlsWidth = parseInt(this.windowControls.getComputedStyle().width, 10); } @@ -472,8 +481,6 @@ export class TitlebarPart extends Part implements ITitleService { bufferWidth = 0; } - - // Adjust app icon mimic menubar this.appIcon.style({ width: `${newAppIconWidth}px`, diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index b904c6121a1..6748e7384c3 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -65,6 +65,15 @@ cursor: pointer; } +.monaco-shell .monaco-menu .monaco-action-bar.vertical { + padding: .5em 0; +} + +.monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label, +.monaco-shell .monaco-menu .monaco-action-bar.vertical .keybinding { + padding: 0.5em 2em; +} + /* START Keyboard Focus Indication Styles */ .monaco-shell [tabindex="0"]:focus, @@ -131,13 +140,4 @@ .monaco-shell .monaco-tree.focused:focus, .monaco-shell .monaco-list:focus { outline: 0 !important; /* tree indicates focus not via outline but through the focused item */ -} - -.monaco-shell .monaco-menu .monaco-action-bar.vertical .action-label, -.monaco-shell .monaco-menu .monaco-action-bar.vertical .keybinding { - padding: 0.5em 2em; -} - -.monaco-shell .monaco-menu .monaco-action-bar.vertical { - padding: .5em 0; } \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index f673a17f2fc..397fde34ad5 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -356,11 +356,8 @@ export class Workbench extends Disposable implements IPartService { // List serviceCollection.set(IListService, this.instantiationService.createInstance(ListService)); - // Context Menu - const hasCustomTitle = this.getCustomTitleBarStyle() === 'custom'; - // Use themable context menus when custom titlebar is enabled to match custom menubar - if (!isMacintosh && hasCustomTitle) { + if (!isMacintosh && this.getCustomTitleBarStyle() === 'custom') { serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService, null, this.telemetryService, this.notificationService, this.contextViewService)); } else { serviceCollection.set(IContextMenuService, new SyncDescriptor(NativeContextMenuService)); @@ -411,6 +408,7 @@ export class Workbench extends Disposable implements IPartService { this.titlebarPart = this.instantiationService.createInstance(TitlebarPart, Identifiers.TITLEBAR_PART); this._register(toDisposable(() => this.titlebarPart.shutdown())); serviceCollection.set(ITitleService, this.titlebarPart); + // History serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService)); @@ -1017,9 +1015,10 @@ export class Workbench extends Disposable implements IPartService { }); this.menubarPart.create(menubarContainer.getHTMLElement()); - this.menubarPart.onVisibilityChange((dimension => { + + this._register(this.menubarPart.onVisibilityChange((dimension => { this._onMenubarVisibilityChange.fire(dimension); - })); + }))); } private createActivityBarPart(): void { @@ -1133,10 +1132,10 @@ export class Workbench extends Disposable implements IPartService { //#region IPartService - private _onTitleBarVisibilityChange: Emitter = new Emitter(); + private _onTitleBarVisibilityChange: Emitter = this._register(new Emitter()); get onTitleBarVisibilityChange(): Event { return this._onTitleBarVisibilityChange.event; } - private _onMenubarVisibilityChange: Emitter = new Emitter(); + private _onMenubarVisibilityChange: Emitter = this._register(new Emitter()); get onMenubarVisibilityChange(): Event { return this._onMenubarVisibilityChange.event; } get onEditorLayout(): Event { return this.editorPart.onDidLayout; } @@ -1187,9 +1186,9 @@ export class Workbench extends Disposable implements IPartService { isVisible(part: Parts): boolean { switch (part) { case Parts.TITLEBAR_PART: - return this.getCustomTitleBarStyle() && !browser.isFullscreen(); + return this.getCustomTitleBarStyle() === 'custom' && !browser.isFullscreen(); case Parts.MENUBAR_PART: - return this.getCustomTitleBarStyle() && !this.menubarHidden; + return this.getCustomTitleBarStyle() === 'custom' && !this.menubarHidden; case Parts.SIDEBAR_PART: return !this.sideBarHidden; case Parts.PANEL_PART: diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index d445eaa0684..59221606c51 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, CopyPathAction, FocusOpenEditorsView, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler } from 'vs/workbench/parts/files/electron-browser/fileActions'; +import { ToggleAutoSaveAction, GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, CopyPathAction, FocusOpenEditorsView, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler } from 'vs/workbench/parts/files/electron-browser/fileActions'; import { revertLocalChangesCommand, acceptLocalChangesCommand, CONFLICT_RESOLUTION_CONTEXT } from 'vs/workbench/parts/files/electron-browser/saveErrorHandler'; import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; @@ -40,6 +40,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(RefreshExplorerView, R registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalNewUntitledFileAction, GlobalNewUntitledFileAction.ID, GlobalNewUntitledFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_N }), 'File: New Untitled File', category); registry.registerWorkbenchAction(new SyncActionDescriptor(ShowOpenedFileInNewWindow, ShowOpenedFileInNewWindow.ID, ShowOpenedFileInNewWindow.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_O) }), 'File: Open Active File in New Window', category); registry.registerWorkbenchAction(new SyncActionDescriptor(CompareWithClipboardAction, CompareWithClipboardAction.ID, CompareWithClipboardAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_C) }), 'File: Compare Active File with Clipboard', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleAutoSaveAction, ToggleAutoSaveAction.ID, ToggleAutoSaveAction.LABEL), 'File: Toggle Auto Save', category); // Commands CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand); diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 9739c0c06f3..71c741536a2 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -34,7 +34,6 @@ import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInpu import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { ToggleAutoSaveAction } from 'vs/workbench/parts/files/electron-browser/fileActions'; // Viewlet Action export class OpenExplorerViewletAction extends ToggleViewletAction { @@ -74,9 +73,6 @@ registry.registerWorkbenchAction( nls.localize('view', "View") ); -// Register Action to Toggle Auto Save -registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleAutoSaveAction, ToggleAutoSaveAction.ID, ToggleAutoSaveAction.LABEL), 'Toggle Auto Save', nls.localize('file', "File")); - // Register file editors Registry.as(EditorExtensions.Editors).registerEditor( new EditorDescriptor( -- GitLab