Merge from vscode 313ede61cbad8f9dc748907b3384e059ddddb79a (#7436)

* Merge from vscode 313ede61cbad8f9dc748907b3384e059ddddb79a

* fix strict null checks
This commit is contained in:
Anthony Dresser
2019-09-30 23:35:45 -07:00
committed by GitHub
parent 6ab03053a0
commit 084524cd2d
196 changed files with 2927 additions and 2547 deletions

View File

@@ -75,9 +75,10 @@ class DecorationRule {
}
// bubble badge
// TODO @misolori update bubble badge to use class name instead of unicode
createCSSRule(
`.${this.bubbleBadgeClassName}::after`,
`content: "\uf052"; color: ${getColor(theme, color)}; font-family: octicons; font-size: 14px; padding-right: 14px; opacity: 0.4;`,
`content: "\uf052"; color: ${getColor(theme, color)}; font-family: octicons; font-size: 14px; padding-right: 10px; opacity: 0.4;`,
element
);
}

View File

@@ -91,7 +91,7 @@ export abstract class AbstractFileDialogService {
const toOpen: IWindowOpenable = stat.isDirectory ? { folderUri: uri } : { fileUri: uri };
if (stat.isDirectory || options.forceNewWindow || preferNewWindow) {
return this.hostService.openInWindow([toOpen], { forceNewWindow: options.forceNewWindow });
return this.hostService.openWindow([toOpen], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
@@ -105,7 +105,7 @@ export abstract class AbstractFileDialogService {
const uri = await this.pickResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
if (options.forceNewWindow || preferNewWindow) {
return this.hostService.openInWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow });
return this.hostService.openWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
@@ -118,7 +118,7 @@ export abstract class AbstractFileDialogService {
const uri = await this.pickResource({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
return this.hostService.openInWindow([{ folderUri: uri }], { forceNewWindow: options.forceNewWindow });
return this.hostService.openWindow([{ folderUri: uri }], { forceNewWindow: options.forceNewWindow });
}
}
@@ -129,7 +129,7 @@ export abstract class AbstractFileDialogService {
const uri = await this.pickResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, filters, availableFileSystems });
if (uri) {
return this.hostService.openInWindow([{ workspaceUri: uri }], { forceNewWindow: options.forceNewWindow });
return this.hostService.openWindow([{ workspaceUri: uri }], { forceNewWindow: options.forceNewWindow });
}
}

View File

@@ -110,7 +110,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
return this.pickFileToSaveSimplified(schema, options);
} else {
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
if (result && result.filePath) {
return URI.file(result.filePath);
}
}
@@ -134,7 +134,7 @@ export class FileDialogService extends AbstractFileDialogService implements IFil
}
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
if (result && result.filePath) {
return URI.file(result.filePath);
}

View File

@@ -364,12 +364,16 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
const pendingReply = this._pendingRPCReplies[callId];
delete this._pendingRPCReplies[callId];
let err: Error | null = null;
if (value && value.$isError) {
err = new Error();
err.name = value.name;
err.message = value.message;
err.stack = value.stack;
let err: any = undefined;
if (value) {
if (value.$isError) {
err = new Error();
err.name = value.name;
err.message = value.message;
err.stack = value.stack;
} else {
err = value;
}
}
pendingReply.resolveErr(err);
}
@@ -725,7 +729,7 @@ class MessageIO {
}
public static serializeReplyErr(req: number, err: any): VSBuffer {
if (err instanceof Error) {
if (err) {
return this._serializeReplyErrEror(req, err);
}
return this._serializeReplyErrEmpty(req);

View File

@@ -187,4 +187,17 @@ suite('RPCProtocol', () => {
done(null);
});
});
test('issue #72798: null errors are hard to digest', function (done) {
delegate = (a1: number, a2: number) => {
throw { 'what': 'what' };
};
bProxy.$m(4, 1).then((res) => {
assert.fail('unexpected');
done(null);
}, (err) => {
assert.equal(err.what, 'what');
done(null);
});
});
});

View File

@@ -9,7 +9,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, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { IWindowSettings, IWindowOpenable, IOpenWindowOptions, 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';
@@ -46,13 +46,6 @@ export class BrowserHostService extends Disposable implements IHostService {
_serviceBrand: undefined;
//#region Events
get onDidChangeFocus(): Event<boolean> { return this._onDidChangeFocus; }
private _onDidChangeFocus: Event<boolean>;
//#endregion
private workspaceProvider: IWorkspaceProvider;
constructor(
@@ -87,11 +80,28 @@ export class BrowserHostService extends Disposable implements IHostService {
);
}
//#region Window
get onDidChangeFocus(): Event<boolean> { return this._onDidChangeFocus; }
private _onDidChangeFocus: Event<boolean>;
readonly windowCount = Promise.resolve(1);
get hasFocus(): boolean {
return document.hasFocus();
}
async openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void> {
async focus(): Promise<void> {
window.focus();
}
openWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
openWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void>;
openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise<void> {
if (Array.isArray(arg1)) {
return this.doOpenWindow(arg1, arg2);
}
return this.doOpenEmptyWindow(arg1);
}
private async doOpenWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void> {
for (let i = 0; i < toOpen.length; i++) {
const openable = toOpen[i];
openable.label = openable.label || this.getRecentLabel(openable);
@@ -126,7 +136,7 @@ export class BrowserHostService extends Disposable implements IHostService {
return this.labelService.getUriLabel(openable.fileUri);
}
private shouldReuse(options: IOpenInWindowOptions = {}): boolean {
private shouldReuse(options: IOpenWindowOptions = {}): boolean {
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
const openFolderInNewWindowConfig = (windowConfig && windowConfig.openFoldersInNewWindow) || 'default' /* default */;
@@ -138,8 +148,8 @@ export class BrowserHostService extends Disposable implements IHostService {
return !openFolderInNewWindow;
}
async openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
this.workspaceProvider.open(undefined, { reuse: options && options.reuse });
private async doOpenEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
this.workspaceProvider.open(undefined, { reuse: options && options.forceReuseWindow });
}
async toggleFullScreen(): Promise<void> {
@@ -176,16 +186,6 @@ export class BrowserHostService extends Disposable implements IHostService {
}
}
get hasFocus(): boolean {
return document.hasFocus();
}
async focus(): Promise<void> {
window.focus();
}
//#endregion
async restart(): Promise<void> {
this.reload();
}
@@ -195,7 +195,7 @@ export class BrowserHostService extends Disposable implements IHostService {
}
async closeWorkspace(): Promise<void> {
return this.openEmptyWindow({ reuse: true });
return this.doOpenEmptyWindow({ forceReuseWindow: true });
}
}

View File

@@ -5,7 +5,7 @@
import { Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IWindowOpenable, IOpenInWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { IWindowOpenable, IOpenWindowOptions, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
export const IHostService = createDecorator<IHostService>('hostService');
@@ -13,38 +13,13 @@ export interface IHostService {
_serviceBrand: undefined;
//#region Events
//#region Focus
/**
* Emitted when the window focus changes.
*/
readonly onDidChangeFocus: Event<boolean>;
//#endregion
//#region Window
/**
* The number of windows that belong to the current client session.
*/
readonly windowCount: Promise<number>;
/**
* Opens the provided array of openables in a window with the provided options.
*/
openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void>;
/**
* 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?: IOpenEmptyWindowOptions): Promise<void>;
/**
* Switch between fullscreen and normal window.
*/
toggleFullScreen(): Promise<void>;
/**
* Find out if the window has focus or not.
*/
@@ -57,6 +32,28 @@ export interface IHostService {
//#endregion
//#region Window
/**
* Opens an empty window. The optional parameter allows to define if
* a new window should open or the existing one change to an empty.
*/
openWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
/**
* Opens the provided array of openables in a window with the provided options.
*/
openWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void>;
/**
* Switch between fullscreen and normal window.
*/
toggleFullScreen(): Promise<void>;
//#endregion
//#region Lifecycle
/**

View File

@@ -9,7 +9,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, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { IWindowOpenable, IOpenWindowOptions, isFolderToOpen, isWorkspaceToOpen, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { Disposable } from 'vs/base/common/lifecycle';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
@@ -17,16 +17,6 @@ export class DesktopHostService extends Disposable implements IHostService {
_serviceBrand: undefined;
//#region Events
get onDidChangeFocus(): Event<boolean> { return this._onDidChangeFocus; }
private _onDidChangeFocus: Event<boolean> = Event.any(
Event.map(Event.filter(this.electronService.onWindowFocus, id => id === this.electronEnvironmentService.windowId), _ => true),
Event.map(Event.filter(this.electronService.onWindowBlur, id => id === this.electronEnvironmentService.windowId), _ => false)
);
//#endregion
constructor(
@IElectronService private readonly electronService: IElectronService,
@ILabelService private readonly labelService: ILabelService,
@@ -46,19 +36,31 @@ export class DesktopHostService extends Disposable implements IHostService {
this._register(this.onDidChangeFocus(focus => this._hasFocus = focus));
}
//#region Window
get onDidChangeFocus(): Event<boolean> { return this._onDidChangeFocus; }
private _onDidChangeFocus: Event<boolean> = Event.any(
Event.map(Event.filter(this.electronService.onWindowFocus, id => id === this.electronEnvironmentService.windowId), _ => true),
Event.map(Event.filter(this.electronService.onWindowBlur, id => id === this.electronEnvironmentService.windowId), _ => false)
);
private _hasFocus: boolean;
get hasFocus(): boolean { return this._hasFocus; }
get windowCount(): Promise<number> { return this.electronService.getWindowCount(); }
openWindow(options?: IOpenEmptyWindowOptions): Promise<void>;
openWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void>;
openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise<void> {
if (Array.isArray(arg1)) {
return this.doOpenWindow(arg1, arg2);
}
openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void> {
return this.doOpenEmptyWindow(arg1);
}
private doOpenWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise<void> {
if (!!this.environmentService.configuration.remoteAuthority) {
toOpen.forEach(openable => openable.label = openable.label || this.getRecentLabel(openable));
}
return this.electronService.openInWindow(toOpen, options);
return this.electronService.openWindow(toOpen, options);
}
private getRecentLabel(openable: IWindowOpenable): string {
@@ -73,8 +75,8 @@ export class DesktopHostService extends Disposable implements IHostService {
return this.labelService.getUriLabel(openable.fileUri);
}
openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
return this.electronService.openEmptyWindow(options);
private doOpenEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
return this.electronService.openWindow(options);
}
toggleFullScreen(): Promise<void> {
@@ -85,8 +87,6 @@ export class DesktopHostService extends Disposable implements IHostService {
return this.electronService.focusWindow();
}
//#endregion
restart(): Promise<void> {
return this.electronService.relaunch();
}
@@ -96,7 +96,7 @@ export class DesktopHostService extends Disposable implements IHostService {
}
closeWorkspace(): Promise<void> {
return this.electronService.closeWorkpsace();
return this.electronService.closeWorkspace();
}
}

View File

@@ -16,6 +16,7 @@ import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
import { ISignService } from 'vs/platform/sign/common/sign';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import { findFreePort } from 'vs/base/node/ports';
export async function createRemoteTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise<RemoteTunnel> {
const tunnel = new NodeRemoteTunnel(options, tunnelRemotePort);
@@ -25,7 +26,7 @@ export async function createRemoteTunnel(options: IConnectionOptions, tunnelRemo
class NodeRemoteTunnel extends Disposable implements RemoteTunnel {
public readonly tunnelRemotePort: number;
public readonly tunnelLocalPort: number;
public tunnelLocalPort: number;
private readonly _options: IConnectionOptions;
private readonly _server: net.Server;
@@ -47,7 +48,7 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel {
this._server.on('connection', this._connectionListener);
this.tunnelRemotePort = tunnelRemotePort;
this.tunnelLocalPort = (<net.AddressInfo>this._server.listen(0).address()).port;
}
public dispose(): void {
@@ -58,6 +59,13 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel {
}
public async waitForReady(): Promise<this> {
// try to get the same port number as the remote port number...
const localPort = await findFreePort(this.tunnelRemotePort, 1, 1000);
// if that fails, the method above returns 0, which works out fine below...
this.tunnelLocalPort = (<net.AddressInfo>this._server.listen(localPort).address()).port;
await this._barrier.wait();
return this;
}

View File

@@ -57,6 +57,10 @@ export class BrowserTextFileService extends AbstractTextFileService {
return false; // dirty with backups: no veto
}
protected async getWindowCount(): Promise<number> {
return 1; // Browser only ever is 1 window
}
}
registerSingleton(ITextFileService, BrowserTextFileService);

View File

@@ -39,7 +39,6 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { ITextSnapshot } from 'vs/editor/common/model';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { IHostService } from 'vs/workbench/services/host/browser/host';
/**
* The workbench file service implementation implements the raw file service spec and adds additional methods on top.
@@ -74,14 +73,13 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
@IFileService protected readonly fileService: IFileService,
@IUntitledEditorService protected readonly untitledEditorService: IUntitledEditorService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IInstantiationService protected instantiationService: IInstantiationService,
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IModeService private readonly modeService: IModeService,
@IModelService private readonly modelService: IModelService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
@INotificationService private readonly notificationService: INotificationService,
@IBackupFileService private readonly backupFileService: IBackupFileService,
@IHostService private readonly hostService: IHostService,
@IHistoryService private readonly historyService: IHistoryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IDialogService private readonly dialogService: IDialogService,
@@ -180,7 +178,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
case ShutdownReason.CLOSE:
if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY && this.configuredHotExit === HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE) {
doBackup = true; // backup if a folder is open and onExitAndWindowClose is configured
} else if (await this.hostService.windowCount > 1 || platform.isMacintosh) {
} else if (await this.getWindowCount() > 1 || platform.isMacintosh) {
doBackup = false; // do not backup if a window is closed that does not cause quitting of the application
} else {
doBackup = true; // backup if last window is closed on win/linux where the application quits right after
@@ -213,6 +211,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
return true;
}
protected abstract getWindowCount(): Promise<number>;
private backupAll(dirtyToBackup: URI[]): Promise<void> {
// split up between files and untitled

View File

@@ -77,10 +77,10 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private resource: URI;
private contentEncoding: string; // encoding as reported from disk
private preferredEncoding: string; // encoding as chosen by the user
private contentEncoding: string; // encoding as reported from disk
private preferredEncoding: string | undefined; // encoding as chosen by the user
private preferredMode: string | undefined; // mode as chosen by the user
private preferredMode: string | undefined; // mode as chosen by the user
private versionId: number;
private bufferSavedVersionId: number;
@@ -107,7 +107,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
constructor(
resource: URI,
preferredEncoding: string,
preferredEncoding: string | undefined,
preferredMode: string | undefined,
@INotificationService private readonly notificationService: INotificationService,
@IModeService modeService: IModeService,

View File

@@ -27,9 +27,46 @@ import { Readable } from 'stream';
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
import { ITextSnapshot } from 'vs/editor/common/model';
import { nodeReadableToString, streamToNodeReadable, nodeStreamToVSBufferReadable } from 'vs/base/node/stream';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export class NativeTextFileService extends AbstractTextFileService {
constructor(
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IFileService fileService: IFileService,
@IUntitledEditorService untitledEditorService: IUntitledEditorService,
@ILifecycleService lifecycleService: ILifecycleService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@INotificationService notificationService: INotificationService,
@IBackupFileService backupFileService: IBackupFileService,
@IHistoryService historyService: IHistoryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IDialogService dialogService: IDialogService,
@IFileDialogService fileDialogService: IFileDialogService,
@IEditorService editorService: IEditorService,
@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService,
@IElectronService private readonly electronService: IElectronService
) {
super(contextService, fileService, untitledEditorService, lifecycleService, instantiationService, configurationService, modeService, modelService, environmentService, notificationService, backupFileService, historyService, contextKeyService, dialogService, fileDialogService, editorService, textResourceConfigurationService);
}
private _encoding!: EncodingOracle;
get encoding(): EncodingOracle {
if (!this._encoding) {
@@ -255,6 +292,10 @@ export class NativeTextFileService extends AbstractTextFileService {
});
});
}
protected getWindowCount(): Promise<number> {
return this.electronService.getWindowCount();
}
}
export interface IEncodingOverride {

View File

@@ -7,7 +7,7 @@ import * as sinon from 'sinon';
import * as platform from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { workbenchInstantiationService, TestLifecycleService, TestTextFileService, TestContextService, TestFileService, TestHostService } from 'vs/workbench/test/workbenchTestServices';
import { workbenchInstantiationService, TestLifecycleService, TestTextFileService, TestContextService, TestFileService, TestElectronService } from 'vs/workbench/test/workbenchTestServices';
import { toResource } from 'vs/base/test/common/utils';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
@@ -20,7 +20,7 @@ import { IWorkspaceContextService, Workspace } from 'vs/platform/workspace/commo
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { Schemas } from 'vs/base/common/network';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IElectronService } from 'vs/platform/electron/node/electron';
class ServiceAccessor {
constructor(
@@ -30,7 +30,7 @@ class ServiceAccessor {
@IWorkspaceContextService public contextService: TestContextService,
@IModelService public modelService: ModelServiceImpl,
@IFileService public fileService: TestFileService,
@IHostService public hostService: TestHostService
@IElectronService public electronService: TestElectronService
) {
}
}
@@ -424,7 +424,7 @@ suite('Files - TextFileService', () => {
}
// Set multiple windows if required
if (multipleWindows) {
accessor.hostService.windowCount = Promise.resolve(2);
accessor.electronService.windowCount = Promise.resolve(2);
}
// Set cancel to force a veto if hot exit does not trigger
service.setConfirmResult(ConfirmResult.CANCEL);

View File

@@ -7,7 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { virtualMachineHint } from 'vs/base/node/id';
import * as perf from 'vs/base/common/performance';
import * as os from 'os';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
@@ -308,7 +308,7 @@ class TimerService implements ITimerService {
private _startupMetrics?: Promise<IStartupMetrics>;
constructor(
@IHostService private readonly _hostService: IHostService,
@IElectronService private readonly _electronService: IElectronService,
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService,
@@ -380,7 +380,7 @@ class TimerService implements ITimerService {
isLatestVersion: Boolean(await this._updateService.isLatestVersion()),
didUseCachedData: didUseCachedData(),
windowKind: this._lifecycleService.startupKind,
windowCount: await this._hostService.windowCount,
windowCount: await this._electronService.getWindowCount(),
viewletId: activeViewlet ? activeViewlet.getId() : undefined,
editorIds: this._editorService.visibleEditors.map(input => input.getTypeId()),
panelId: activePanel ? activePanel.getId() : undefined,

View File

@@ -13,6 +13,7 @@ import product from 'vs/platform/product/common/product';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
import { IElectronService } from 'vs/platform/electron/node/electron';
export class RelayURLService extends URLService implements IURLHandler {
@@ -21,7 +22,8 @@ export class RelayURLService extends URLService implements IURLHandler {
constructor(
@IMainProcessService mainProcessService: IMainProcessService,
@IOpenerService openerService: IOpenerService,
@IElectronEnvironmentService private electronEnvironmentService: IElectronEnvironmentService
@IElectronEnvironmentService private electronEnvironmentService: IElectronEnvironmentService,
@IElectronService private electronService: IElectronService
) {
super();
@@ -52,8 +54,14 @@ export class RelayURLService extends URLService implements IURLHandler {
return await this.urlService.open(resource);
}
handleURL(uri: URI): Promise<boolean> {
return super.open(uri);
async handleURL(uri: URI): Promise<boolean> {
const result = await super.open(uri);
if (result) {
await this.electronService.focusWindow();
}
return result;
}
}

View File

@@ -113,7 +113,7 @@ export class BrowserWorkspacesService extends Disposable implements IWorkspacesS
//#region Workspace Management
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | undefined> {
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}

View File

@@ -78,8 +78,7 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi
return false; // only care about untitled workspaces to ask for saving
}
const windowCount = await this.hostService.windowCount;
const windowCount = await this.electronService.getWindowCount();
if (reason === ShutdownReason.CLOSE && !isMacintosh && windowCount === 1) {
return false; // Windows/Linux: quits when last window is closed, so do not ask then
}