提交 d0b67392 编写于 作者: B Benjamin Pasero

debt - getWindows is electron only

上级 cc036f3f
......@@ -12,7 +12,7 @@ export function stringify(obj: any): string {
export function parse(text: string): any {
let data = JSON.parse(text);
data = revive(data, 0);
data = revive(data);
return data;
}
......@@ -32,8 +32,7 @@ function replacer(key: string, value: any): any {
return value;
}
export function revive(obj: any, depth: number): any {
export function revive(obj: any, depth = 0): any {
if (!obj || depth > 200) {
return obj;
}
......
......@@ -18,7 +18,7 @@ import { parseLineAndColumnAware } from 'vs/code/node/paths';
import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILogService } from 'vs/platform/log/common/log';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, isFileToOpen, isWorkspaceToOpen, isFolderToOpen, IWindowOpenable } from 'vs/platform/windows/common/windows';
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, isFileToOpen, isWorkspaceToOpen, isFolderToOpen, IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri } from 'vs/code/node/windowsFinder';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import product from 'vs/platform/product/common/product';
......@@ -1617,7 +1617,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return getLastActiveWindow(WindowsManager.WINDOWS.filter(window => window.remoteAuthority === remoteAuthority));
}
openEmptyWindow(context: OpenContext, options?: { reuse?: boolean, remoteAuthority?: string }): ICodeWindow[] {
openEmptyWindow(context: OpenContext, options?: IOpenEmptyWindowOptions): ICodeWindow[] {
let cli = this.environmentService.args;
const remote = options && options.remoteAuthority;
if (cli && (cli.remote !== remote)) {
......
......@@ -6,13 +6,12 @@
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { MessageBoxOptions, MessageBoxReturnValue, shell, OpenDevToolsOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, CrashReporterStartOptions, crashReporter, Menu } from 'electron';
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { OpenContext, INativeOpenDialogOptions, IWindowOpenable, IOpenInWindowOptions, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
import { OpenContext, INativeOpenDialogOptions, IWindowOpenable, IOpenInWindowOptions, IOpenedWindow, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { isMacintosh } from 'vs/base/common/platform';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { AddContextToFunctions } from 'vs/platform/ipc/node/simpleIpcProxy';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri';
export class ElectronMainService implements AddContextToFunctions<IElectronService, number> {
......@@ -27,31 +26,28 @@ export class ElectronMainService implements AddContextToFunctions<IElectronServi
//#region Window
async windowCount(windowId: number): Promise<number> {
async getWindows(): Promise<IOpenedWindow[]> {
const windows = this.windowsMainService.getWindows();
return windows.map(window => ({
id: window.id,
workspace: window.openedWorkspace,
folderUri: window.openedFolderUri,
title: window.win.getTitle(),
filename: window.getRepresentedFilename()
}));
}
async getWindowCount(windowId: number): Promise<number> {
return this.windowsMainService.getWindowCount();
}
async openEmptyWindow(windowId: number, options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void> {
async openEmptyWindow(windowId: number, options?: IOpenEmptyWindowOptions): Promise<void> {
this.windowsMainService.openEmptyWindow(OpenContext.API, options);
}
async openInWindow(windowId: number, toOpen: IWindowOpenable[], options: IOpenInWindowOptions = Object.create(null)): Promise<void> {
if (toOpen.length > 0) {
// Revive URIs
toOpen.forEach(openable => {
if (isWorkspaceToOpen(openable)) {
openable.workspaceUri = URI.revive(openable.workspaceUri);
} else if (isFolderToOpen(openable)) {
openable.folderUri = URI.revive(openable.folderUri);
} else {
openable.fileUri = URI.revive(openable.fileUri);
}
});
options.waitMarkerFileURI = options.waitMarkerFileURI && URI.revive(options.waitMarkerFileURI);
// Open via Windows Service
this.windowsMainService.open({
context: OpenContext.API,
contextWindowId: windowId,
......@@ -112,7 +108,11 @@ export class ElectronMainService implements AddContextToFunctions<IElectronServi
}
}
async focusWindow(windowId: number): Promise<void> {
async focusWindow(windowId: number, options?: { windowId?: number; }): Promise<void> {
if (options && typeof options.windowId === 'number') {
windowId = options.windowId;
}
const window = this.windowsMainService.getWindowById(windowId);
if (window) {
if (isMacintosh) {
......
......@@ -5,7 +5,7 @@
import { MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, SaveDialogOptions, OpenDialogOptions, OpenDialogReturnValue, SaveDialogReturnValue, CrashReporterStartOptions } from 'electron';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { INativeOpenDialogOptions, IWindowOpenable, IOpenInWindowOptions } from 'vs/platform/windows/common/windows';
import { INativeOpenDialogOptions, IWindowOpenable, IOpenInWindowOptions, IOpenedWindow, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
export const IElectronService = createDecorator<IElectronService>('electronService');
......@@ -15,9 +15,10 @@ export interface IElectronService {
_serviceBrand: undefined;
// Window
windowCount(): Promise<number>;
getWindows(): Promise<IOpenedWindow[]>;
getWindowCount(): Promise<number>;
openEmptyWindow(options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void>;
openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void>;
toggleFullScreen(): Promise<void>;
......@@ -29,7 +30,7 @@ export interface IElectronService {
unmaximizeWindow(): Promise<void>;
minimizeWindow(): Promise<void>;
focusWindow(): Promise<void>;
focusWindow(options?: { windowId?: number }): Promise<void>;
// Dialogs
showMessageBox(options: MessageBoxOptions): Promise<MessageBoxReturnValue>;
......
......@@ -5,6 +5,7 @@
import { Event } from 'vs/base/common/event';
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { revive } from 'vs/base/common/marshalling';
//
// Use both `SimpleServiceProxyChannel` and `createSimpleChannelProxy`
......@@ -53,10 +54,17 @@ export class SimpleServiceProxyChannel implements IServerChannel {
const target = this.service[command];
if (typeof target === 'function') {
if (Array.isArray(args)) {
// Deserialize context if any
const context = deserializeContext(args[0]);
if (context) {
args[0] = context;
}
// Revive: handles URIs and RegExp
for (let i = 0; i < args.length; i++) {
args[i] = revive(args[i]);
}
}
return target.apply(this.service, args);
......@@ -72,7 +80,9 @@ export function createSimpleChannelProxy<T>(channel: IChannel, context?: unknown
return new Proxy({}, {
get(_target, propKey, _receiver) {
if (typeof propKey === 'string') {
return function (...args: any[]) {
return async function (...args: any[]) {
// Serialize context if any
let methodArgs: any[];
if (serializedContext) {
methodArgs = [context, ...args];
......@@ -80,7 +90,8 @@ export function createSimpleChannelProxy<T>(channel: IChannel, context?: unknown
methodArgs = args;
}
return channel.call(propKey, methodArgs);
// Revive: handles URIs and RegExp
return revive(await channel.call(propKey, methodArgs));
};
}
......
......@@ -45,13 +45,19 @@ export interface IWindowsService {
getRecentlyOpened(windowId: number): Promise<IRecentlyOpened>;
isFocused(windowId: number): Promise<boolean>;
// Global methods
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>;
getActiveWindowId(): Promise<number | undefined>;
}
export const IWindowService = createDecorator<IWindowService>('windowService');
export interface IOpenedWindow {
id: number;
workspace?: IWorkspaceIdentifier;
folderUri?: ISingleFolderWorkspaceIdentifier;
title: string;
filename?: string;
}
export interface IOpenInWindowOptions {
forceNewWindow?: boolean;
forceReuseWindow?: boolean;
......@@ -62,6 +68,11 @@ export interface IOpenInWindowOptions {
waitMarkerFileURI?: URI;
}
export interface IOpenEmptyWindowOptions {
reuse?: boolean;
remoteAuthority?: string;
}
export type IWindowOpenable = IWorkspaceToOpen | IFolderToOpen | IFileToOpen;
export interface IBaseWindowOpenable {
......
......@@ -58,7 +58,6 @@ export class WindowsChannel implements IServerChannel {
case 'getRecentlyOpened': return this.service.getRecentlyOpened(arg);
case 'isFocused': return this.service.isFocused(arg);
case 'openExtensionDevelopmentHostWindow': return (this.service as any).openExtensionDevelopmentHostWindow(arg[0], arg[1]); // TODO@Isidor move
case 'getWindows': return this.service.getWindows();
case 'getActiveWindowId': return this.service.getActiveWindowId();
}
......
......@@ -6,7 +6,7 @@
import { Event } from 'vs/base/common/event';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWindowsService } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IRecentlyOpened, IRecent, isRecentWorkspace } from 'vs/platform/history/common/history';
import { URI } from 'vs/base/common/uri';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
......@@ -58,28 +58,6 @@ export class WindowsService implements IWindowsService {
return this.channel.call('openExtensionDevelopmentHostWindow', [args, env]);
}
async getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
const result = await this.channel.call<{
id: number;
workspace?: IWorkspaceIdentifier;
folderUri?: ISingleFolderWorkspaceIdentifier;
title: string;
filename?: string;
}[]>('getWindows');
for (const win of result) {
if (win.folderUri) {
win.folderUri = URI.revive(win.folderUri);
}
if (win.workspace) {
win.workspace = reviveWorkspaceIdentifier(win.workspace);
}
}
return result;
}
getActiveWindowId(): Promise<number | undefined> {
return this.channel.call('getActiveWindowId');
}
......
......@@ -14,7 +14,6 @@ import { IURLService, IURLHandler } from 'vs/platform/url/common/url';
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
import { IRecentlyOpened, IRecent } from 'vs/platform/history/common/history';
import { IHistoryMainService } from 'vs/platform/history/electron-main/historyMainService';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { Schemas } from 'vs/base/common/network';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
......@@ -97,20 +96,6 @@ export class LegacyWindowsMainService extends Disposable implements IWindowsServ
}
}
async getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
this.logService.trace('windowsService#getWindows');
const windows = this.windowsMainService.getWindows();
return windows.map(window => ({
id: window.id,
workspace: window.openedWorkspace,
folderUri: window.openedFolderUri,
title: window.win.getTitle(),
filename: window.getRepresentedFilename()
}));
}
async getActiveWindowId(): Promise<number | undefined> {
return this._activeWindowId;
}
......
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OpenContext, IWindowConfiguration, INativeOpenDialogOptions, IWindowOpenable } from 'vs/platform/windows/common/windows';
import { OpenContext, IWindowConfiguration, INativeOpenDialogOptions, IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
......@@ -108,7 +108,7 @@ export interface IWindowsMainService {
focusLastActive(cli: ParsedArgs, context: OpenContext): ICodeWindow;
getLastActiveWindow(): ICodeWindow | undefined;
waitForWindowCloseOrLoad(windowId: number): Promise<void>;
openEmptyWindow(context: OpenContext, options?: { reuse?: boolean, remoteAuthority?: string }): ICodeWindow[];
openEmptyWindow(context: OpenContext, options?: IOpenEmptyWindowOptions): ICodeWindow[];
openNewTabbedWindow(context: OpenContext): ICodeWindow[];
openExternal(url: string): Promise<boolean>;
sendToFocused(channel: string, ...args: any[]): void;
......
......@@ -58,7 +58,7 @@ export class MainThreadCommands implements MainThreadCommandsShape {
id,
CommandsRegistry.registerCommand(id, (accessor, ...args) => {
return this._proxy.$executeContributedCommand(id, ...args).then(result => {
return revive(result, 0);
return revive(result);
});
})
);
......@@ -74,7 +74,7 @@ export class MainThreadCommands implements MainThreadCommandsShape {
async $executeCommand<T>(id: string, args: any[], retry: boolean): Promise<T | undefined> {
for (let i = 0; i < args.length; i++) {
args[i] = revive(args[i], 0);
args[i] = revive(args[i]);
}
if (retry && args.length > 0 && !CommandsRegistry.getCommand(id)) {
await this._extensionService.activateByEvent(`onCommand:${id}`);
......
......@@ -52,7 +52,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
{
processArgument(a) {
// URI, Regex
return revive(a, 0);
return revive(a);
}
},
{
......@@ -141,7 +141,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
try {
const result = await this._proxy.$executeCommand<T>(id, toArgs, retry);
return revive(result, 0);
return revive(result);
} catch (e) {
// Rerun the command when it wasn't known, had arguments, and when retry
// is enabled. We do this because the command might be registered inside
......
......@@ -11,7 +11,6 @@ import { ILogService } from 'vs/platform/log/common/log';
import { Disposable } from 'vs/base/common/lifecycle';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IRecentlyOpened, IRecent, isRecentFile, isRecentFolder } from 'vs/platform/history/common/history';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { addDisposableListener, EventType } from 'vs/base/browser/dom';
......@@ -167,11 +166,6 @@ export class SimpleWindowsService implements IWindowsService {
});
}
// Global methods
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
return Promise.resolve([]);
}
getActiveWindowId(): Promise<number | undefined> {
return Promise.resolve(0);
}
......
......@@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { toResource, IEditorCommandsContext, SideBySideEditor } from 'vs/workbench/common/editor';
import { IWindowOpenable, IOpenInWindowOptions, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
import { IWindowOpenable, IOpenInWindowOptions, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
......@@ -98,7 +98,7 @@ export const openWindowCommand = (accessor: ServicesAccessor, toOpen: IWindowOpe
}
};
export const newWindowCommand = (accessor: ServicesAccessor, options?: { reuse?: boolean, remoteAuthority?: string }) => {
export const newWindowCommand = (accessor: ServicesAccessor, options?: IOpenEmptyWindowOptions) => {
const hostService = accessor.get(IHostService);
hostService.openEmptyWindow(options);
};
......
......@@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
import { Action } from 'vs/base/common/actions';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { IWindowService } from 'vs/platform/windows/common/windows';
import * as nls from 'vs/nls';
import * as browser from 'vs/base/browser/browser';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
......@@ -19,7 +19,6 @@ import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { IHostService } from 'vs/workbench/services/host/browser/host';
export class CloseCurrentWindowAction extends Action {
......@@ -168,14 +167,12 @@ export abstract class BaseSwitchWindow extends Action {
constructor(
id: string,
label: string,
private windowsService: IWindowsService,
private windowService: IWindowService,
private quickInputService: IQuickInputService,
private keybindingService: IKeybindingService,
private modelService: IModelService,
private modeService: IModeService,
private electronService: IElectronService,
private hostService: IHostService
private electronService: IElectronService
) {
super(id, label);
}
......@@ -185,7 +182,7 @@ export abstract class BaseSwitchWindow extends Action {
async run(): Promise<void> {
const currentWindowId = this.windowService.windowId;
const windows = await this.windowsService.getWindows();
const windows = await this.electronService.getWindows();
const placeHolder = nls.localize('switchWindowPlaceHolder', "Select a window to switch to");
const picks = windows.map(win => {
const resource = win.filename ? URI.file(win.filename) : win.folderUri ? win.folderUri : win.workspace ? win.workspace.configPath : undefined;
......@@ -212,7 +209,7 @@ export abstract class BaseSwitchWindow extends Action {
});
if (pick) {
this.hostService.focus();
this.electronService.focusWindow({ windowId: pick.payload });
}
}
}
......@@ -225,16 +222,14 @@ export class SwitchWindow extends BaseSwitchWindow {
constructor(
id: string,
label: string,
@IWindowsService windowsService: IWindowsService,
@IWindowService windowService: IWindowService,
@IQuickInputService quickInputService: IQuickInputService,
@IKeybindingService keybindingService: IKeybindingService,
@IModelService modelService: IModelService,
@IModeService modeService: IModeService,
@IElectronService electronService: IElectronService,
@IHostService hostService: IHostService
@IElectronService electronService: IElectronService
) {
super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService, electronService, hostService);
super(id, label, windowService, quickInputService, keybindingService, modelService, modeService, electronService);
}
protected isQuickNavigate(): boolean {
......@@ -250,16 +245,14 @@ export class QuickSwitchWindow extends BaseSwitchWindow {
constructor(
id: string,
label: string,
@IWindowsService windowsService: IWindowsService,
@IWindowService windowService: IWindowService,
@IQuickInputService quickInputService: IQuickInputService,
@IKeybindingService keybindingService: IKeybindingService,
@IModelService modelService: IModelService,
@IModeService modeService: IModeService,
@IElectronService electronService: IElectronService,
@IHostService hostService: IHostService
@IElectronService electronService: IElectronService
) {
super(id, label, windowsService, windowService, quickInputService, keybindingService, modelService, modeService, electronService, hostService);
super(id, label, windowService, quickInputService, keybindingService, modelService, modeService, electronService);
}
protected isQuickNavigate(): boolean {
......
......@@ -8,7 +8,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IResourceEditor, IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWindowSettings, IWindowOpenable, IOpenInWindowOptions, isFolderToOpen, isWorkspaceToOpen, isFileToOpen } from 'vs/platform/windows/common/windows';
import { IWindowSettings, IWindowOpenable, IOpenInWindowOptions, isFolderToOpen, isWorkspaceToOpen, isFileToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { pathsToEditors } from 'vs/workbench/common/editor';
import { IFileService } from 'vs/platform/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
......@@ -88,7 +88,7 @@ export class BrowserHostService implements IHostService {
return { openFolderInNewWindow };
}
async openEmptyWindow(options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void> {
async openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
// TODO@Ben delegate to embedder
const targetHref = `${document.location.origin}${document.location.pathname}?ew=true`;
if (options && options.reuse) {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IWindowOpenable, IOpenInWindowOptions } from 'vs/platform/windows/common/windows';
import { IWindowOpenable, IOpenInWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
export const IHostService = createDecorator<IHostService>('hostService');
......@@ -28,7 +28,7 @@ export interface IHostService {
* Opens an empty window. The optional parameter allows to define if
* a new window should open or the existing one change to an empty.
*/
openEmptyWindow(options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void>;
openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
/**
* Switch between fullscreen and normal window.
......
......@@ -8,7 +8,7 @@ import { IElectronService } from 'vs/platform/electron/node/electron';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILabelService } from 'vs/platform/label/common/label';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWindowOpenable, IOpenInWindowOptions, isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
import { IWindowOpenable, IOpenInWindowOptions, isFolderToOpen, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
export class DesktopHostService implements IHostService {
......@@ -22,7 +22,7 @@ export class DesktopHostService implements IHostService {
//#region Window
get windowCount(): Promise<number> { return this.electronService.windowCount(); }
get windowCount(): Promise<number> { return this.electronService.getWindowCount(); }
openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void> {
if (!!this.environmentService.configuration.remoteAuthority) {
......@@ -44,7 +44,7 @@ export class DesktopHostService implements IHostService {
return this.labelService.getUriLabel(openable.fileUri);
}
openEmptyWindow(options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void> {
openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
return this.electronService.openEmptyWindow(options);
}
......
......@@ -7,7 +7,7 @@ import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common
import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IJSONEditingService, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesService, rewriteWorkspaceFileForNewLocation, WORKSPACE_FILTER } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
......@@ -20,7 +20,7 @@ import { BackupFileService } from 'vs/workbench/services/backup/common/backupFil
import { ICommandService } from 'vs/platform/commands/common/commands';
import { distinct } from 'vs/base/common/arrays';
import { isLinux, isWindows, isMacintosh, isWeb } from 'vs/base/common/platform';
import { isEqual, basename, isEqualOrParent, getComparisonKey } from 'vs/base/common/resources';
import { isEqual, isEqualOrParent, getComparisonKey } from 'vs/base/common/resources';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
......@@ -28,7 +28,6 @@ import { ILifecycleService, ShutdownReason } from 'vs/platform/lifecycle/common/
import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IHostService } from 'vs/workbench/services/host/browser/host';
......@@ -49,13 +48,12 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
@ICommandService private readonly commandService: ICommandService,
@IFileService private readonly fileService: IFileService,
@ITextFileService private readonly textFileService: ITextFileService,
@IWindowsService private readonly windowsService: IWindowsService,
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IFileDialogService private readonly fileDialogService: IFileDialogService,
@IDialogService private readonly dialogService: IDialogService,
@ILifecycleService readonly lifecycleService: ILifecycleService,
@ILabelService readonly labelService: ILabelService,
@IDialogService protected readonly dialogService: IDialogService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@ILabelService private readonly labelService: ILabelService,
@IHostService private readonly hostService: IHostService
) {
this.registerListeners();
......@@ -319,22 +317,6 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
}
async isValidTargetWorkspacePath(path: URI): Promise<boolean> {
const windows = await this.windowsService.getWindows();
// Prevent overwriting a workspace that is currently opened in another window
if (windows.some(window => !!window.workspace && isEqual(window.workspace.configPath, path))) {
await this.dialogService.show(
Severity.Info,
nls.localize('workspaceOpenedMessage', "Unable to save workspace '{0}'", basename(path)),
[nls.localize('ok', "OK")],
{
detail: nls.localize('workspaceOpenedDetail', "The workspace is already opened in another window. Please close that window first and then try again.")
}
);
return false;
}
return true; // OK
}
......@@ -461,5 +443,3 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
return undefined;
}
}
registerSingleton(IWorkspaceEditingService, WorkspaceEditingService, true);
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { isEqual, basename } from 'vs/base/common/resources';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { WorkspaceEditingService } from 'vs/workbench/services/workspace/browser/workspaceEditingService';
import { IElectronService } from 'vs/platform/electron/node/electron';
export class NativeWorkspaceEditingService extends WorkspaceEditingService {
_serviceBrand: undefined;
constructor(
@IJSONEditingService jsonEditingService: IJSONEditingService,
@IWorkspaceContextService contextService: WorkspaceService,
@IElectronService private electronService: IElectronService,
@IConfigurationService configurationService: IConfigurationService,
@IStorageService storageService: IStorageService,
@IExtensionService extensionService: IExtensionService,
@IBackupFileService backupFileService: IBackupFileService,
@INotificationService notificationService: INotificationService,
@ICommandService commandService: ICommandService,
@IFileService fileService: IFileService,
@ITextFileService textFileService: ITextFileService,
@IWindowService windowService: IWindowService,
@IWorkspacesService workspacesService: IWorkspacesService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IFileDialogService fileDialogService: IFileDialogService,
@IDialogService protected dialogService: IDialogService,
@ILifecycleService lifecycleService: ILifecycleService,
@ILabelService labelService: ILabelService,
@IHostService hostService: IHostService
) {
super(jsonEditingService, contextService, windowService, configurationService, storageService, extensionService, backupFileService, notificationService, commandService, fileService, textFileService, workspacesService, environmentService, fileDialogService, dialogService, lifecycleService, labelService, hostService);
}
async isValidTargetWorkspacePath(path: URI): Promise<boolean> {
const windows = await this.electronService.getWindows();
// Prevent overwriting a workspace that is currently opened in another window
if (windows.some(window => !!window.workspace && isEqual(window.workspace.configPath, path))) {
await this.dialogService.show(
Severity.Info,
nls.localize('workspaceOpenedMessage', "Unable to save workspace '{0}'", basename(path)),
[nls.localize('ok', "OK")],
{
detail: nls.localize('workspaceOpenedDetail', "The workspace is already opened in another window. Please close that window first and then try again.")
}
);
return false;
}
return true; // OK
}
}
registerSingleton(IWorkspaceEditingService, NativeWorkspaceEditingService, true);
......@@ -35,7 +35,7 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IWindowsService, IWindowService, MenuBarVisibility, IWindowConfiguration, IWindowOpenable, IOpenInWindowOptions } from 'vs/platform/windows/common/windows';
import { IWindowsService, IWindowService, MenuBarVisibility, IWindowConfiguration, IWindowOpenable, IOpenInWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -1281,10 +1281,6 @@ export class TestWindowsService implements IWindowsService {
});
}
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
throw new Error('not implemented');
}
getActiveWindowId(): Promise<number | undefined> {
return Promise.resolve(undefined);
}
......@@ -1386,7 +1382,7 @@ export class TestHostService implements IHostService {
async focus(): Promise<void> { }
async openEmptyWindow(options?: { reuse?: boolean, remoteAuthority?: string }): Promise<void> { }
async openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> { }
async openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void> { }
async toggleFullScreen(): Promise<void> { }
......
......@@ -72,6 +72,8 @@ import { IMenubarService } from 'vs/platform/menubar/node/menubar';
import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { ElectronService } from 'vs/platform/electron/electron-browser/electronService';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { NativeWorkspaceEditingService } from 'vs/workbench/services/workspace/electron-browser/workspaceEditingService';
registerSingleton(IClipboardService, ClipboardService, true);
registerSingleton(ILifecycleService, LifecycleService);
......@@ -82,6 +84,7 @@ registerSingleton(IUpdateService, UpdateService);
registerSingleton(IIssueService, IssueService);
registerSingleton(IMenubarService, MenubarService);
registerSingleton(IElectronService, ElectronService, true);
registerSingleton(IWorkspaceEditingService, NativeWorkspaceEditingService, true);
//#endregion
......
......@@ -65,6 +65,8 @@ import { NoOpTunnelService } from 'vs/platform/remote/common/tunnelService';
import { IUserDataSyncStoreService, IUserDataSyncService } from 'vs/platform/userDataSync/common/userDataSync';
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { WorkspaceEditingService } from 'vs/workbench/services/workspace/browser/workspaceEditingService';
registerSingleton(IExtensionManagementService, ExtensionManagementService);
registerSingleton(IBackupFileService, BackupFileService);
......@@ -75,6 +77,7 @@ registerSingleton(IContextMenuService, ContextMenuService);
registerSingleton(ITunnelService, NoOpTunnelService, true);
registerSingleton(IUserDataSyncStoreService, UserDataSyncStoreService);
registerSingleton(IUserDataSyncService, UserDataSyncService);
registerSingleton(IWorkspaceEditingService, WorkspaceEditingService, true);
//#endregion
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册