提交 3a7b5fe6 编写于 作者: S Sandeep Somavarapu

Fix #32947

上级 6f000804
......@@ -55,7 +55,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { ILifecycleService, LifecyclePhase, ShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IMessageService, IChoiceService, Severity } from 'vs/platform/message/common/message';
......@@ -91,10 +91,6 @@ import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollba
import { TextMateService } from 'vs/workbench/services/textMate/electron-browser/TMSyntax';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService';
import { isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { StorageService } from 'vs/platform/storage/common/storageService';
import { migrateStorageToMultiRootWorkspace } from 'vs/platform/storage/common/migration';
import { once } from 'vs/base/common/event';
/**
* Services that we require for the Shell
......@@ -135,7 +131,6 @@ export class WorkbenchShell {
private previousErrorTime: number;
private content: HTMLElement;
private contentsContainer: Builder;
private shutdownListener: IDisposable;
private configuration: IWindowConfiguration;
private workbench: Workbench;
......@@ -319,7 +314,6 @@ export class WorkbenchShell {
const lifecycleService = instantiationService.createInstance(LifecycleService);
this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
this.toUnbind.push(lifecycleService.onWillShutdown(event => this.onWillShutdown(event)));
serviceCollection.set(ILifecycleService, lifecycleService);
disposables.push(lifecycleTelemetry(this.telemetryService, lifecycleService));
this.lifecycleService = lifecycleService;
......@@ -444,33 +438,6 @@ export class WorkbenchShell {
return this.workbench.joinCreation();
}
private onWillShutdown(event: ShutdownEvent): void {
// The shutdown sequence could have been stopped due to a veto. Make sure to
// always dispose the shutdown listener if we are called again in the same session.
if (this.shutdownListener) {
this.shutdownListener.dispose();
this.shutdownListener = void 0;
}
if (event.reason === ShutdownReason.RELOAD) {
const workspace = event.payload;
// We are transitioning into a workspace from an empty workspace or folder workspace
// As such we want to migrate UI state from the current workspace to the new one. Since
// many components write to storage only on shutdown, we register a shutdown listener
// very late to be called as the last one.
if (isWorkspaceIdentifier(workspace) && !this.contextService.hasMultiFolderWorkspace()) {
this.shutdownListener = once(this.lifecycleService.onShutdown)(() => {
// TODO@Ben revisit this when we move away from local storage to a file based approach
const storageImpl = this.storageService as StorageService;
migrateStorageToMultiRootWorkspace(storageImpl.storageId, workspace, storageImpl.workspaceStorage);
});
}
}
}
public dispose(): void {
// Workbench
......@@ -483,11 +450,6 @@ export class WorkbenchShell {
// Listeners
this.toUnbind = dispose(this.toUnbind);
if (this.shutdownListener) {
this.shutdownListener.dispose();
this.shutdownListener = void 0;
}
// Container
$(this.container).empty();
}
......
......@@ -84,7 +84,7 @@ import { ProgressService2 } from 'vs/workbench/services/progress/browser/progres
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ILifecycleService, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
import { ILifecycleService, ShutdownReason, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
import { IWindowService, IWindowConfiguration as IWindowSettings, IWindowConfiguration, IPath } from 'vs/platform/windows/common/windows';
import { IMessageService } from 'vs/platform/message/common/message';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
......@@ -98,9 +98,11 @@ import { OpenRecentAction, ToggleDevToolsAction, ReloadWindowAction, inRecentFil
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { getQuickNavigateHandler, inQuickOpenContext } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IWorkspaceEditingService, IWorkspaceMigrationService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { WorkspaceEditingService } from 'vs/workbench/services/workspace/node/workspaceEditingService';
import URI from 'vs/base/common/uri';
import { isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceMigrationService } from 'vs/workbench/services/workspace/node/workspaceMigrationService';
export const MessagesVisibleContext = new RawContextKey<boolean>('globalMessageVisible', false);
export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen', false);
......@@ -180,6 +182,7 @@ export class Workbench implements IPartService {
private keybindingService: IKeybindingService;
private backupFileService: IBackupFileService;
private configurationEditingService: IConfigurationEditingService;
private workspaceMigrationService: WorkspaceMigrationService;
private titlebarPart: TitlebarPart;
private activitybarPart: ActivitybarPart;
private sidebarPart: SidebarPart;
......@@ -520,6 +523,7 @@ export class Workbench implements IPartService {
private initServices(): void {
const { serviceCollection } = this.workbenchParams;
this.toDispose.push(this.lifecycleService.onWillShutdown(event => this.onWillShutdown(event)));
this.toDispose.push(this.lifecycleService.onShutdown(this.shutdownComponents, this));
// Services we contribute
......@@ -626,6 +630,10 @@ export class Workbench implements IPartService {
// Configuration Resolver
serviceCollection.set(IConfigurationResolverService, new SyncDescriptor(ConfigurationResolverService, process.env));
// Workspace Migrating
this.workspaceMigrationService = this.instantiationService.createInstance(WorkspaceMigrationService);
serviceCollection.set(IWorkspaceMigrationService, this.workspaceMigrationService);
// Quick open service (quick open controller)
this.quickOpen = this.instantiationService.createInstance(QuickOpenController);
this.toDispose.push(this.quickOpen);
......@@ -962,6 +970,21 @@ export class Workbench implements IPartService {
}
}
private onWillShutdown(event: ShutdownEvent): void {
if (event.reason === ShutdownReason.RELOAD) {
const workspace = event.payload;
// We are transitioning into a workspace from an empty workspace or folder workspace
// As such we want to migrate UI state from the current workspace to the new one. Since
// many components write to storage only on shutdown, we register a shutdown listener
// very late to be called as the last one.
if (isWorkspaceIdentifier(workspace) && !this.contextService.hasMultiFolderWorkspace()) {
event.veto(this.instantiationService.createInstance(WorkspaceMigrationService).migrate(workspace).then(() => false, () => false));
}
}
}
private shutdownComponents(reason = ShutdownReason.QUIT): void {
// Restore sidebar if we are being shutdown as a matter of a reload
......
......@@ -5,8 +5,9 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import URI from 'vs/base/common/uri';
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
export const IWorkspaceEditingService = createDecorator<IWorkspaceEditingService>('workspaceEditingService');
......@@ -23,4 +24,15 @@ export interface IWorkspaceEditingService {
* remove roots from the existing workspace
*/
removeRoots(roots: URI[]): TPromise<void>;
}
export const IWorkspaceMigrationService = createDecorator<IWorkspaceMigrationService>('workspaceMigrationService');
export interface IWorkspaceMigrationService {
/**
* Migrate current workspace to given workspace
*/
migrate(toWokspaceId: IWorkspaceIdentifier): TPromise<void>;
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* 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 URI from 'vs/base/common/uri';
import { once } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { StorageService } from 'vs/platform/storage/common/storageService';
import { migrateStorageToMultiRootWorkspace } from 'vs/platform/storage/common/migration';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
import { IWorkspaceMigrationService } from 'vs/workbench/services/workspace/common/workspaceEditing';
export class WorkspaceMigrationService implements IWorkspaceMigrationService {
public _serviceBrand: any;
private shutdownListener: IDisposable;
constructor(
@IStorageService private storageService: IStorageService,
@IJSONEditingService private jsonEditingService: IJSONEditingService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IConfigurationService private configurationService: IConfigurationService,
@ILifecycleService private lifecycleService: ILifecycleService
) {
}
migrate(toWorkspaceId: IWorkspaceIdentifier): TPromise<void> {
this.migrateStorage(toWorkspaceId);
return this.migrateConfiguration(toWorkspaceId);
}
migrateStorage(toWorkspaceId: IWorkspaceIdentifier): void {
// The shutdown sequence could have been stopped due to a veto. Make sure to
// always dispose the shutdown listener if we are called again in the same session.
if (this.shutdownListener) {
this.shutdownListener.dispose();
this.shutdownListener = void 0;
}
this.shutdownListener = once(this.lifecycleService.onShutdown)(() => {
// TODO@Ben revisit this when we move away from local storage to a file based approach
const storageImpl = this.storageService as StorageService;
migrateStorageToMultiRootWorkspace(storageImpl.storageId, toWorkspaceId, storageImpl.workspaceStorage);
});
}
private migrateConfiguration(toWorkspaceId: IWorkspaceIdentifier): TPromise<void> {
const configurationProperties = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
const targetWorkspaceConfiguration = {};
for (const key of this.configurationService.keys().workspace) {
if (configurationProperties[key] && configurationProperties[key].scope === ConfigurationScope.WINDOW) {
targetWorkspaceConfiguration[key] = this.configurationService.lookup(key).workspace;
}
}
return this.jsonEditingService.write(URI.file(toWorkspaceId.configPath), { key: 'settings', value: targetWorkspaceConfiguration }, true);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册