diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 1e17015161e..2b62b94920d 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -21,11 +21,11 @@ import { ILifecycleService, UnloadReason } from 'vs/platform/lifecycle/electron- import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { IWindowSettings, OpenContext, IPath, IWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { getLastActiveWindow, findBestWindowOrFolderForFile } from 'vs/code/node/windowsFinder'; +import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace } from 'vs/code/node/windowsFinder'; import CommonEvent, { Emitter } from 'vs/base/common/event'; import product from 'vs/platform/node/product'; import { ITelemetryService, ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; -import { isEqual, isEqualOrParent } from 'vs/base/common/paths'; +import { isEqual } from 'vs/base/common/paths'; import { IWindowsMainService, IOpenConfiguration } from "vs/platform/windows/electron-main/windows"; import { IHistoryMainService } from "vs/platform/history/electron-main/historyMainService"; import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; @@ -356,22 +356,25 @@ export class WindowsManager implements IWindowsMainService { // We found a suitable window to open the files within if (bestWindowOrFolder instanceof CodeWindow) { - bestWindowOrFolder.focus(); const files = { filesToOpen, filesToCreate, filesToDiff }; // copy to object because they get reset shortly after - bestWindowOrFolder.ready().then(readyWindow => { + + const windowToUse = bestWindowOrFolder; + windowToUse.focus(); + windowToUse.ready().then(readyWindow => { readyWindow.send('vscode:openFiles', files); }); - usedWindows.push(bestWindowOrFolder); + usedWindows.push(windowToUse); } // Otherwise open a new window with the best folder to use for the file else { + const folderToOpen = bestWindowOrFolder; const browserWindow = this.openInBrowserWindow({ userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, - workspacePath: bestWindowOrFolder, + workspacePath: folderToOpen, filesToOpen, filesToCreate, filesToDiff, @@ -393,7 +396,7 @@ export class WindowsManager implements IWindowsMainService { if (allFoldersToOpen.length > 0) { // Check for existing instances - const windowsOnWorkspacePath = arrays.coalesce(allFoldersToOpen.map(folderToOpen => this.findWindow(folderToOpen))); + const windowsOnWorkspacePath = arrays.coalesce(allFoldersToOpen.map(folderToOpen => findWindowOnWorkspace(WindowsManager.WINDOWS, folderToOpen))); if (windowsOnWorkspacePath.length > 0) { const browserWindow = windowsOnWorkspacePath[0]; browserWindow.focus(); // just focus one of them @@ -1003,51 +1006,6 @@ export class WindowsManager implements IWindowsMainService { return getLastActiveWindow(WindowsManager.WINDOWS); } - public findWindow(workspacePath: string, filePath?: string, extensionDevelopmentPath?: string): CodeWindow { - if (WindowsManager.WINDOWS.length) { - - // Sort the last active window to the front of the array of windows to test - const windowsToTest = WindowsManager.WINDOWS.slice(0); - const lastActiveWindow = this.getLastActiveWindow(); - if (lastActiveWindow) { - windowsToTest.splice(windowsToTest.indexOf(lastActiveWindow), 1); - windowsToTest.unshift(lastActiveWindow); - } - - // Find it - const res = windowsToTest.filter(w => { - - // match on workspace - if (typeof w.openedWorkspacePath === 'string' && (isEqual(w.openedWorkspacePath, workspacePath, !isLinux /* ignorecase */))) { - return true; - } - - // match on file - if (typeof w.openedFilePath === 'string' && isEqual(w.openedFilePath, filePath, !isLinux /* ignorecase */)) { - return true; - } - - // match on file path - if (typeof w.openedWorkspacePath === 'string' && filePath && isEqualOrParent(filePath, w.openedWorkspacePath, !isLinux /* ignorecase */)) { - return true; - } - - // match on extension development path - if (typeof extensionDevelopmentPath === 'string' && isEqual(w.extensionDevelopmentPath, extensionDevelopmentPath, !isLinux /* ignorecase */)) { - return true; - } - - return false; - }); - - if (res && res.length) { - return res[0]; - } - } - - return null; - } - public openNewWindow(context: OpenContext): void { this.open({ context, cli: this.environmentService.args, forceNewWindow: true, forceEmpty: true }); } diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index 5ccc728fb59..309decbd6e9 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -11,17 +11,13 @@ import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; import { OpenContext } from 'vs/platform/windows/common/windows'; -/** - * Exported subset of CodeWindow for testing. - */ export interface ISimpleWindow { openedWorkspacePath: string; + openedFilePath?: string; + extensionDevelopmentPath?: string; lastFocusTime: number; } -/** - * Exported for testing. - */ export interface IBestWindowOrFolderOptions { windows: W[]; newWindow: boolean; @@ -108,3 +104,53 @@ export function getLastActiveWindow(windows: W[]): W { return null; } + +export function findWindowOnWorkspace(windows: W[], workspacePath: string): W { + if (windows.length) { + + // Sort the last active window to the front of the array of windows to test + const windowsToTest = windows.slice(0); + const lastActiveWindow = getLastActiveWindow(windows); + if (lastActiveWindow) { + windowsToTest.splice(windowsToTest.indexOf(lastActiveWindow), 1); + windowsToTest.unshift(lastActiveWindow); + } + + // Find it + const res = windowsToTest.filter(w => { + + // match on workspace + if (typeof w.openedWorkspacePath === 'string' && (paths.isEqual(w.openedWorkspacePath, workspacePath, !platform.isLinux /* ignorecase */))) { + return true; + } + + return false; + }); + + if (res && res.length) { + return res[0]; + } + } + + return null; +} + +export function findExtensionDevelopmentWindow(windows: W[], extensionDevelopmentPath?: string): W { + if (windows.length) { + const res = windows.filter(w => { + + // match on extension development path + if (typeof extensionDevelopmentPath === 'string' && paths.isEqual(w.extensionDevelopmentPath, extensionDevelopmentPath, !platform.isLinux /* ignorecase */)) { + return true; + } + + return false; + }); + + if (res && res.length) { + return res[0]; + } + } + + return null; +} \ No newline at end of file diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index fc814d30697..7faee2803d9 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -18,6 +18,7 @@ export interface ICodeWindow { win: Electron.BrowserWindow; config: IWindowConfiguration; openedWorkspacePath: string; + lastFocusTime: number; readyState: ReadyState; @@ -56,7 +57,6 @@ export interface IWindowsMainService { focusLastActive(cli: ParsedArgs, context: OpenContext): ICodeWindow; getLastActiveWindow(): ICodeWindow; waitForWindowClose(windowId: number): TPromise; - findWindow(workspacePath: string, filePath?: string, extensionDevelopmentPath?: string): ICodeWindow; openNewWindow(context: OpenContext): void; sendToFocused(channel: string, ...args: any[]): void; sendToAll(channel: string, payload: any, windowIdsToIgnore?: number[]): void; diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 1a70af5ad48..955d0b5fb49 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -19,6 +19,7 @@ import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { ILifecycleService } from "vs/platform/lifecycle/electron-main/lifecycleMain"; import { IWindowsMainService, ISharedProcess } from "vs/platform/windows/electron-main/windows"; import { IHistoryMainService } from "vs/platform/history/electron-main/historyMainService"; +import { findExtensionDevelopmentWindow } from "vs/code/node/windowsFinder"; export class WindowsService implements IWindowsService, IDisposable { @@ -287,9 +288,9 @@ export class WindowsService implements IWindowsService, IDisposable { } closeExtensionHostWindow(extensionDevelopmentPaths: string[]): TPromise { - extensionDevelopmentPaths.map(p => this.windowsMainService.findWindow(null, null, p)).forEach(windowOnExtension => { - if (windowOnExtension) { - windowOnExtension.win.close(); + extensionDevelopmentPaths.map(extensionDevelopmentPath => findExtensionDevelopmentWindow(this.windowsMainService.getWindows(), extensionDevelopmentPath)).forEach(extensionDevelopmentWindow => { + if (extensionDevelopmentWindow) { + extensionDevelopmentWindow.win.close(); } });