diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 8dff8703ef9ac3829adaae23422d725b666f39eb..d7f67feaf82997c6ecbc12e198519dd7e9509813 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -108,6 +108,10 @@ export class QuickOpenWidget implements IModelProvider { this.model = null; } + public getElement(): Builder { + return $(this.builder); + } + public getModel(): IModel { return this.model; } diff --git a/src/vs/test/utils/servicesTestUtils.ts b/src/vs/test/utils/servicesTestUtils.ts index e626349cc1deda3e38af1f78748792b97a6866d1..4965a8996a21d8a20579796563cb63812c5984c9 100644 --- a/src/vs/test/utils/servicesTestUtils.ts +++ b/src/vs/test/utils/servicesTestUtils.ts @@ -217,6 +217,12 @@ export class TestMessageService implements IMessageService { export class TestPartService implements IPartService { public _serviceBrand: any; + private _onTitleBarVisibilityChange = new Emitter(); + + public get onTitleBarVisibilityChange(): Event { + return this._onTitleBarVisibilityChange.event; + } + public layout(): void { } public isCreated(): boolean { @@ -243,6 +249,10 @@ export class TestPartService implements IPartService { return false; } + public getTitleBarOffset(): number { + return 0; + } + public isStatusBarHidden(): boolean { return false; } diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index b35417330c7f678542a7c3add603e1087869f662..adf5d093ce7b8fc220225045c877f051a729367d 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -8,6 +8,7 @@ import 'vs/css!./media/quickopen'; import { TPromise, ValueCallback } from 'vs/base/common/winjs.base'; import nls = require('vs/nls'); +import * as browser from 'vs/base/browser/browser'; import { Dimension, withElementById } from 'vs/base/browser/builder'; import strings = require('vs/base/common/strings'); import filters = require('vs/base/common/filters'); @@ -126,7 +127,9 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe } private registerListeners(): void { - this.configurationService.onDidUpdateConfiguration(e => this.updateConfiguration(e.config)); + this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.updateConfiguration(e.config))); + this.toUnbind.push(this.partService.onTitleBarVisibilityChange(() => this.positionQuickOpenWidget())); + this.toUnbind.push(browser.onDidChangeZoomLevel(() => this.positionQuickOpenWidget())); } private updateConfiguration(settings: IWorkbenchQuickOpenConfiguration): void { @@ -279,6 +282,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe const pickOpenContainer = this.pickOpenWidget.create(); DOM.addClass(pickOpenContainer, 'show-file-icons'); + this.positionQuickOpenWidget(); } // Update otherwise @@ -512,6 +516,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe const quickOpenContainer = this.quickOpenWidget.create(); DOM.addClass(quickOpenContainer, 'show-file-icons'); + this.positionQuickOpenWidget(); } // Layout @@ -549,6 +554,18 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe return promiseCompletedOnHide; } + private positionQuickOpenWidget(): void { + let titlebarOffset = this.partService.getTitleBarOffset(); + + if (this.quickOpenWidget) { + this.quickOpenWidget.getElement().style('top', `${titlebarOffset}px`); + } + + if (this.pickOpenWidget) { + this.pickOpenWidget.getElement().style('top', `${titlebarOffset}px`); + } + } + private handleOnShow(isPicker: boolean): void { if (isPicker && this.quickOpenWidget) { this.quickOpenWidget.hide(HideReason.FOCUS_LOST); diff --git a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css index 5cb8cff834a90941f9f3437a87f108216281a5aa..0d23ccc11c573ed560bca998bc1204c5cca24a76 100644 --- a/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css +++ b/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css @@ -31,14 +31,6 @@ zoom: 1; /* prevent zooming */ } -.titlebar-style-custom .monaco-workbench.fullscreen .quick-open-widget { - top: 0; -} - -.titlebar-style-custom .monaco-workbench .quick-open-widget { - top: 22px; /* push down quick open when we have a custom title bar */ -} - /* Theming */ .vs .monaco-workbench > .part.titlebar { diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 6e2c5a27e0ad33a30f7e72c6e3bee3e4c6cae26e..270f552bc2023daa06eef3f317d52b119d074364 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -10,6 +10,7 @@ import 'vs/css!./media/workbench'; import { TPromise, ValueCallback } from 'vs/base/common/winjs.base'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import strings = require('vs/base/common/strings'); +import Event, { Emitter } from 'vs/base/common/event'; import DOM = require('vs/base/browser/dom'); import { Builder, $ } from 'vs/base/browser/builder'; import { Delayer } from 'vs/base/common/async'; @@ -120,6 +121,8 @@ export class Workbench implements IPartService { private static sidebarPositionConfigurationKey = 'workbench.sideBar.location'; private static statusbarVisibleConfigurationKey = 'workbench.statusBar.visible'; + private _onTitleBarVisibilityChange: Emitter; + public _serviceBrand: any; private parent: HTMLElement; @@ -187,11 +190,17 @@ export class Workbench implements IPartService { this.toShutdown = []; this.editorBackgroundDelayer = new Delayer(50); + this._onTitleBarVisibilityChange = new Emitter(); + this.creationPromise = new TPromise(c => { this.creationPromiseComplete = c; }); } + public get onTitleBarVisibilityChange(): Event { + return this._onTitleBarVisibilityChange.event; + } + /** * Starts the workbench and creates the HTML elements on the container. A workbench can only be started * once. Use the shutdown function to free up resources created by the workbench on startup. @@ -546,6 +555,15 @@ export class Workbench implements IPartService { return !this.getCustomTitleBarStyle() || browser.isFullscreen(); } + public getTitleBarOffset(): number { + let offset = 0; + if (!this.isTitleBarHidden()) { + offset = 22 / browser.getZoomFactor(); // adjust the position based on title bar size and zoom factor + } + + return offset; + } + private getCustomTitleBarStyle(): string { if (!isMacintosh) { return null; // custom title bar is only supported on Mac currently @@ -752,12 +770,14 @@ export class Workbench implements IPartService { this.addClass('fullscreen'); if (hasCustomTitle) { + this._onTitleBarVisibilityChange.fire(); this.layout({ forceStyleRecompute: true }); // handle title bar when fullscreen changes } } else { this.removeClass('fullscreen'); if (hasCustomTitle) { + this._onTitleBarVisibilityChange.fire(); this.layout({ forceStyleRecompute: true }); // handle title bar when fullscreen changes } } diff --git a/src/vs/workbench/services/message/browser/messageList.ts b/src/vs/workbench/services/message/browser/messageList.ts index e251d6bb4e1b2f3d0d132f9da8e5569a298269e7..cae18f520a3947a6219cc48193451cdf976163b7 100644 --- a/src/vs/workbench/services/message/browser/messageList.ts +++ b/src/vs/workbench/services/message/browser/messageList.ts @@ -211,6 +211,10 @@ export class MessageList { } private positionMessageList(animate?: boolean): void { + if (!this.messageListContainer) { + return; // not yet created + } + $(this.messageListContainer).removeClass('transition'); // disable any animations let position = 0; diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index db2be49eebe06936470511aea354954a6dd715ea..50ebcacb9aeb4de4ee702f643993cdbd4fc83bef 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -6,6 +6,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import Event from 'vs/base/common/event'; export enum Parts { ACTIVITYBAR_PART, @@ -31,6 +32,11 @@ export const IPartService = createDecorator('partService'); export interface IPartService { _serviceBrand: ServiceIdentifier; + /** + * Emits when the visibility of the title bar changes. + */ + onTitleBarVisibilityChange: Event; + /** * Asks the part service to layout all parts. */ @@ -66,6 +72,11 @@ export interface IPartService { */ isTitleBarHidden(): boolean; + /** + * Number of pixels (adjusted for zooming) that the title bar (if visible) pushes down the workbench contents. + */ + getTitleBarOffset(): number; + /** * Checks if the statusbar is currently hidden or not */