diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 53d3d3f82d6f52c6d5494f1d1ee4240852e8f964..f522a239c7b00559fbf479c60ca734fca4f2f740 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -167,4 +167,20 @@ declare module 'vscode' { */ export function deleteSecret(service: string, account: string): Thenable; } + + export namespace window { + + /** + * Whether the current window is focused. + * + * @readonly + */ + export let isFocused: boolean; + + /** + * An [event](#Event) which fires when the focus state of the current window + * changes. The value of the event represents whether the window is focused. + */ + export const onDidChangeWindowFocus: Event; + } } diff --git a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts index d13fa311d989e8aef8fdc0afcc8e084a578fdd91..aff0d322bc84f2eba09943d5a8f49f3e94bf0af8 100644 --- a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts @@ -37,6 +37,7 @@ import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventSer import { MainThreadTask } from './mainThreadTask'; import { MainThreadSCM } from './mainThreadSCM'; import { MainThreadCredentials } from './mainThreadCredentials'; +import { MainThreadWindow } from './mainThreadWindow'; // --- other interested parties import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors'; @@ -92,6 +93,7 @@ export class ExtHostContribution implements IWorkbenchContribution { col.define(MainContext.MainThreadSCM).set(create(MainThreadSCM)); col.define(MainContext.MainThreadTask).set(create(MainThreadTask)); col.define(MainContext.MainThreadCredentials).set(create(MainThreadCredentials)); + col.define(MainContext.MainThreadWindow).set(create(MainThreadWindow)); if (this.extensionService instanceof MainProcessExtensionService) { col.define(MainContext.MainProcessExtensionService).set(this.extensionService); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadWindow.ts b/src/vs/workbench/api/electron-browser/mainThreadWindow.ts new file mode 100644 index 0000000000000000000000000000000000000000..3973148ce5d7122e8de0fdce465b76e068b6885e --- /dev/null +++ b/src/vs/workbench/api/electron-browser/mainThreadWindow.ts @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { TPromise } from 'vs/base/common/winjs.base'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { MainThreadWindowShape, ExtHostWindowShape, ExtHostContext } from '../node/extHost.protocol'; +import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; + +export class MainThreadWindow extends MainThreadWindowShape { + + private readonly proxy: ExtHostWindowShape; + private disposables: IDisposable[] = []; + + constructor( + @IThreadService threadService: IThreadService, + @IWindowService private windowService: IWindowService + ) { + super(); + this.proxy = threadService.get(ExtHostContext.ExtHostWindow); + + windowService.onDidChangeFocus(this.proxy.$onDidChangeWindowFocus, this.proxy, this.disposables); + } + + $getWindowVisibility(): TPromise { + return this.windowService.isFocused(); + } + + dispose(): void { + this.disposables = dispose(this.disposables); + } +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 0afe8a0fb65dc11f0d554b2a52d05bcc141fc50e..b49272536ed4fae98eaf6f2c8127401b353146a0 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -36,6 +36,7 @@ import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands'; import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostCredentials } from 'vs/workbench/api/node/extHostCredentials'; +import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow'; import * as extHostTypes from 'vs/workbench/api/node/extHostTypes'; import URI from 'vs/base/common/uri'; import Severity from 'vs/base/common/severity'; @@ -96,6 +97,7 @@ export function createApiFactory( const extHostSCM = col.define(ExtHostContext.ExtHostSCM).set(new ExtHostSCM(threadService, extHostCommands)); const extHostTask = col.define(ExtHostContext.ExtHostTask).set(new ExtHostTask(threadService)); const extHostCredentials = col.define(ExtHostContext.ExtHostCredentials).set(new ExtHostCredentials(threadService)); + const extHostWindow = col.define(ExtHostContext.ExtHostWindow).set(new ExtHostWindow(threadService)); col.define(ExtHostContext.ExtHostExtensionService).set(extensionService); col.finish(false, threadService); @@ -308,6 +310,12 @@ export function createApiFactory( onDidCloseTerminal(listener, thisArg?, disposables?) { return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables); }, + get isFocused() { + return extHostWindow.isFocused; + }, + onDidChangeWindowFocus: proposedApiFunction(extension, (listener, thisArg?, disposables?) => { + return extHostWindow.onDidChangeWindowFocus(listener, thisArg, disposables); + }), showInformationMessage(message, first, ...rest) { return extHostMessageService.showMessage(Severity.Info, message, first, rest); }, diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 33fa36a74d607a57d09548bde157852bfd71906c..f0b8af1b611b498278d0d20bfa2df23e2fc5dc37 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -356,6 +356,10 @@ export abstract class MainThreadCredentialsShape { $deleteSecret(service: string, account: string): Thenable { throw ni(); } } +export abstract class MainThreadWindowShape { + $getWindowVisibility(): TPromise { throw ni(); } +} + // -- extension host export abstract class ExtHostCommandsShape { @@ -515,6 +519,10 @@ export abstract class ExtHostDebugServiceShape { export abstract class ExtHostCredentialsShape { } +export abstract class ExtHostWindowShape { + $onDidChangeWindowFocus(value: boolean): void { throw ni(); } +} + // --- proxy identifiers export const MainContext = { @@ -541,6 +549,7 @@ export const MainContext = { MainThreadSCM: createMainId('MainThreadSCM', MainThreadSCMShape), MainThreadTask: createMainId('MainThreadTask', MainThreadTaskShape), MainThreadCredentials: createMainId('MainThreadCredentials', MainThreadCredentialsShape), + MainThreadWindow: createMainId('MainThreadWindow', MainThreadWindowShape), }; export const ExtHostContext = { @@ -563,4 +572,5 @@ export const ExtHostContext = { ExtHostTask: createExtId('ExtHostTask', ExtHostTaskShape), ExtHostWorkspace: createExtId('ExtHostWorkspace', ExtHostWorkspaceShape), ExtHostCredentials: createExtId('ExtHostCredentials', ExtHostCredentialsShape), + ExtHostWindow: createExtId('ExtHostWindow', ExtHostWindowShape), }; diff --git a/src/vs/workbench/api/node/extHostWindow.ts b/src/vs/workbench/api/node/extHostWindow.ts new file mode 100644 index 0000000000000000000000000000000000000000..26da6a6c19022ecb60e2043934357062fa2158ac --- /dev/null +++ b/src/vs/workbench/api/node/extHostWindow.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import Event, { Emitter } from 'vs/base/common/event'; +import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; +import { ExtHostWindowShape, MainContext, MainThreadWindowShape } from './extHost.protocol'; + +export class ExtHostWindow implements ExtHostWindowShape { + + private _proxy: MainThreadWindowShape; + + private _onDidChangeWindowFocus = new Emitter(); + get onDidChangeWindowFocus(): Event { return this._onDidChangeWindowFocus.event; } + + private _isFocused = false; + get isFocused(): boolean { return this._isFocused; } + + constructor(threadService: IThreadService) { + this._proxy = threadService.get(MainContext.MainThreadWindow); + this._proxy.$getWindowVisibility().then(isFocused => this.$onDidChangeWindowFocus(isFocused)); + } + + $onDidChangeWindowFocus(isFocused: boolean): void { + if (isFocused === this._isFocused) { + return; + } + + this._isFocused = isFocused; + this._onDidChangeWindowFocus.fire(isFocused); + } +} \ No newline at end of file