From fbd2c51122c2f7178b6b20f65b9c003cb5a0a262 Mon Sep 17 00:00:00 2001 From: chrmarti Date: Tue, 7 Feb 2017 08:35:19 -0800 Subject: [PATCH] Open containing window (fixes #15654) --- src/vs/code/electron-main/launch.ts | 2 +- src/vs/code/electron-main/main.ts | 2 +- src/vs/code/electron-main/windows.ts | 32 +++++++++++++++---- .../windows/electron-main/windowsService.ts | 8 ++--- .../electron-browser/main.contribution.ts | 10 +++--- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index 77a863d1bb6..0f35a39f929 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -83,7 +83,7 @@ export class LaunchService implements ILaunchService { const openUrlArg = args['open-url'] || []; const openUrl = typeof openUrlArg === 'string' ? [openUrlArg] : openUrlArg; - const context = !!userEnv['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.OTHER; + const context = !!userEnv['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; if (openUrl.length > 0) { openUrl.forEach(url => this.urlService.open(url)); diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index de09965d895..97545ce2d90 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -252,7 +252,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo windowsMainService.ready(userEnv); // Open our first window - const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.OTHER; + const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; if (environmentService.args['new-window'] && environmentService.args._.length === 0) { windowsMainService.open({ context, cli: environmentService.args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths } else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) { diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index af876f6f7fb..a50e2993692 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -48,8 +48,11 @@ export enum OpenContext { // opening from a file or folder dialog DIALOG, - // any other way of opening - OTHER + // opening from the OS's UI + DESKTOP, + + // opening through the API + API } export interface IOpenConfiguration { @@ -406,15 +409,15 @@ export class WindowsManager implements IWindowsMainService { } // Open Files in last instance if any and flag tells us so - const lastActiveWindow = this.getLastActiveWindow(); - if (!openFilesInNewWindow && lastActiveWindow) { - lastActiveWindow.focus(); + let bestWindow; + if (!openFilesInNewWindow && (bestWindow = this.findBestWindow(openConfig.context, [...filesToOpen, ...filesToCreate, ...filesToDiff]))) { + bestWindow.focus(); const files = { filesToOpen, filesToCreate, filesToDiff }; // copy to object because they get reset shortly after - lastActiveWindow.ready().then(readyWindow => { + bestWindow.ready().then(readyWindow => { readyWindow.send('vscode:openFiles', files); }); - usedWindows.push(lastActiveWindow); + usedWindows.push(bestWindow); } // Otherwise open instance with files @@ -1023,6 +1026,21 @@ export class WindowsManager implements IWindowsMainService { return res && res[0]; } + private findBestWindow(context: OpenContext, filePaths: IPath[]): VSCodeWindow { + const findContainer = context === OpenContext.DESKTOP || context === OpenContext.CLI; + return (findContainer && this.findContainingWindow(filePaths)) || this.getLastActiveWindow(); + } + + private findContainingWindow(filePaths: IPath[]): VSCodeWindow { + for (const filePath of filePaths) { + const windows = WindowsManager.WINDOWS.filter(window => typeof window.openedWorkspacePath === 'string' && paths.isEqualOrParent(filePath.filePath, window.openedWorkspacePath)); + if (windows.length) { + return windows.sort((a, b) => -(a.openedWorkspacePath.length - b.openedWorkspacePath.length))[0]; + } + } + return null; + } + public getLastActiveWindow(): VSCodeWindow { if (WindowsManager.WINDOWS.length) { const lastFocussedDate = Math.max.apply(Math, WindowsManager.WINDOWS.map(w => w.lastFocusTime)); diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 313f8856a41..2528cf989f7 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -94,7 +94,7 @@ export class WindowsService implements IWindowsService, IDisposable { const vscodeWindow = this.windowsMainService.getWindowById(windowId); if (vscodeWindow) { - this.windowsMainService.open({ context: OpenContext.OTHER, cli: this.environmentService.args, forceEmpty: true, windowToUse: vscodeWindow, forceReuseWindow: true }); + this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentService.args, forceEmpty: true, windowToUse: vscodeWindow, forceReuseWindow: true }); } return TPromise.as(null); @@ -198,12 +198,12 @@ export class WindowsService implements IWindowsService, IDisposable { return TPromise.as(null); } - this.windowsMainService.open({ context: OpenContext.OTHER, cli: this.environmentService.args, pathsToOpen: paths, forceNewWindow: options && options.forceNewWindow, forceReuseWindow: options && options.forceReuseWindow }); + this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentService.args, pathsToOpen: paths, forceNewWindow: options && options.forceNewWindow, forceReuseWindow: options && options.forceReuseWindow }); return TPromise.as(null); } openNewWindow(): TPromise { - this.windowsMainService.openNewWindow(OpenContext.OTHER); + this.windowsMainService.openNewWindow(OpenContext.API); return TPromise.as(null); } @@ -266,7 +266,7 @@ export class WindowsService implements IWindowsService, IDisposable { const cli = assign(Object.create(null), this.environmentService.args, { goto: true }); const pathsToOpen = [filePath]; - this.windowsMainService.open({ context: OpenContext.OTHER, cli, pathsToOpen }); + this.windowsMainService.open({ context: OpenContext.API, cli, pathsToOpen }); return TPromise.as(null); } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 5cc0693ba5b..3b365b76547 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -183,16 +183,16 @@ let properties: { [path: string]: IJSONSchema; } = { 'enum': ['on', 'off', 'default'], 'enumDescriptions': [ nls.localize('window.openFilesInNewWindow.on', "\"on\": files will open in a new window"), - nls.localize('window.openFilesInNewWindow.off', "\"off\": files will open in the last active window"), - nls.localize('window.openFilesInNewWindow.default', "\"default\": files will open in the last active window unless opened via the dock or from finder (macOS only)") + nls.localize('window.openFilesInNewWindow.off', "\"off\": files will open in the window with the files' folder open or the last active window"), + nls.localize('window.openFilesInNewWindow.default', "\"default\": files will open in the window with the files' folder open or the last active window unless opened via the dock or from finder (macOS only)") ], 'default': 'default', 'description': nls.localize('openFilesInNewWindow', - `Controls if files should open in a new window or the last active window. -- default: files will open in the last active window unless opened via the dock or from finder (macOS only) + `Controls if files should open in a new window. +- default: files will open in the window with the files' folder open or the last active window unless opened via the dock or from finder (macOS only) - on: files will open in a new window -- off: files will open in the last active window +- off: files will open in the window with the files' folder open or the last active window Note that there can still be cases where this setting is ignored (e.g. when using the -new-window or -reuse-window command line option).` ) }, -- GitLab