mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 27ada910e121e23a6d95ecca9cae595fb98ab568
This commit is contained in:
@@ -498,6 +498,12 @@ export class ResetViewLocationsAction extends Action {
|
||||
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], defaultContainer);
|
||||
}
|
||||
});
|
||||
|
||||
const defaultContainerLocation = this.viewDescriptorService.getDefaultViewContainerLocation(viewContainer);
|
||||
const currentContainerLocation = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
if (defaultContainerLocation !== null && currentContainerLocation !== defaultContainerLocation) {
|
||||
this.viewDescriptorService.moveViewContainerToLocation(viewContainer, defaultContainerLocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorIsReadonlyContext, EditorAreaVisibleContext, DirtyWorkingCopiesContext, ActiveEditorAvailableEditorsContext } from 'vs/workbench/common/editor';
|
||||
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorIsReadonlyContext, EditorAreaVisibleContext, DirtyWorkingCopiesContext, ActiveEditorAvailableEditorIdsContext } from 'vs/workbench/common/editor';
|
||||
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -41,7 +41,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
|
||||
private activeEditorContext: IContextKey<string | null>;
|
||||
private activeEditorIsReadonly: IContextKey<boolean>;
|
||||
private activeEditorAvailableEditors: IContextKey<string>;
|
||||
private activeEditorAvailableEditorIds: IContextKey<string>;
|
||||
|
||||
private activeEditorGroupEmpty: IContextKey<boolean>;
|
||||
private activeEditorGroupIndex: IContextKey<number>;
|
||||
@@ -92,7 +92,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
// Editors
|
||||
this.activeEditorContext = ActiveEditorContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorIsReadonly = ActiveEditorIsReadonlyContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorAvailableEditors = ActiveEditorAvailableEditorsContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorAvailableEditorIds = ActiveEditorAvailableEditorIdsContext.bindTo(this.contextKeyService);
|
||||
this.editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);
|
||||
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
|
||||
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
|
||||
@@ -210,12 +210,12 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
this.activeEditorContext.set(activeEditorPane.getId());
|
||||
this.activeEditorIsReadonly.set(activeEditorPane.input.isReadonly());
|
||||
|
||||
const editors = this.editorService.getEditorOverrides(activeEditorPane.input, undefined, activeGroup);
|
||||
this.activeEditorAvailableEditors.set(editors.map(([_, entry]) => entry.id).join(','));
|
||||
const editors = activeEditorPane.input.resource ? this.editorService.getEditorOverrides(activeEditorPane.input.resource, undefined, activeGroup) : [];
|
||||
this.activeEditorAvailableEditorIds.set(editors.map(([_, entry]) => entry.id).join(','));
|
||||
} else {
|
||||
this.activeEditorContext.reset();
|
||||
this.activeEditorIsReadonly.reset();
|
||||
this.activeEditorAvailableEditors.reset();
|
||||
this.activeEditorAvailableEditorIds.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { LifecyclePhase, StartupKind, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility } from 'vs/platform/windows/common/windows';
|
||||
import { MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility, IPath } from 'vs/platform/windows/common/windows';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IEditor } from 'vs/editor/common/editorCommon';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
@@ -41,6 +41,8 @@ import { INotificationService, NotificationsFilter } from 'vs/platform/notificat
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { WINDOW_ACTIVE_BORDER, WINDOW_INACTIVE_BORDER } from 'vs/workbench/common/theme';
|
||||
import { LineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
enum Settings {
|
||||
ACTIVITYBAR_VISIBLE = 'workbench.activityBar.visible',
|
||||
@@ -82,6 +84,21 @@ enum Classes {
|
||||
WINDOW_BORDER = 'border'
|
||||
}
|
||||
|
||||
interface PanelActivityState {
|
||||
id: string;
|
||||
name?: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface SideBarActivityState {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export abstract class Layout extends Disposable implements IWorkbenchLayoutService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
@@ -450,6 +467,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
private initLayoutState(lifecycleService: ILifecycleService, fileService: IFileService): void {
|
||||
this.applyDefaultLayout(this.environmentService, this.storageService);
|
||||
|
||||
// Fullscreen
|
||||
this.state.fullscreen = isFullscreen();
|
||||
@@ -471,7 +489,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Only restore last viewlet if window was reloaded or we are in development mode
|
||||
let viewletToRestore: string;
|
||||
if (!this.environmentService.isBuilt || lifecycleService.startupKind === StartupKind.ReloadedWindow) {
|
||||
if (!this.environmentService.isBuilt || lifecycleService.startupKind === StartupKind.ReloadedWindow || isWeb) {
|
||||
viewletToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, this.viewletService.getDefaultViewletId());
|
||||
} else {
|
||||
viewletToRestore = this.viewletService.getDefaultViewletId();
|
||||
@@ -527,18 +545,181 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
}
|
||||
|
||||
private applyDefaultLayout(environmentService: IWorkbenchEnvironmentService, storageService: IStorageService) {
|
||||
const defaultLayout = environmentService.options?.defaultLayout;
|
||||
if (!defaultLayout || !defaultLayout.firstRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { sidebar } = defaultLayout;
|
||||
if (sidebar) {
|
||||
if (sidebar.visible !== undefined) {
|
||||
if (sidebar.visible) {
|
||||
storageService.remove(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.store(Storage.SIDEBAR_HIDDEN, true, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebar.containers?.length) {
|
||||
const sidebarState: SideBarActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of sidebar.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let viewletId;
|
||||
switch (container.id) {
|
||||
case 'explorer':
|
||||
viewletId = 'workbench.view.explorer';
|
||||
break;
|
||||
case 'run':
|
||||
viewletId = 'workbench.view.debug';
|
||||
break;
|
||||
case 'scm':
|
||||
viewletId = 'workbench.view.scm';
|
||||
break;
|
||||
case 'search':
|
||||
viewletId = 'workbench.view.search';
|
||||
break;
|
||||
case 'extensions':
|
||||
viewletId = 'workbench.view.extensions';
|
||||
break;
|
||||
case 'remote':
|
||||
viewletId = 'workbench.view.remote';
|
||||
break;
|
||||
default:
|
||||
viewletId = `workbench.view.extension.${container.id}`;
|
||||
}
|
||||
|
||||
if (container.active) {
|
||||
storageService.store(SidebarPart.activeViewletSettingsKey, viewletId, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
if (container.order !== undefined || (container.active === undefined && (<any>container).visible !== undefined)) { // {{SQL CARBON EDIT}} strict-null-checks
|
||||
order = container.order ?? (order + 1);
|
||||
const state: SideBarActivityState = {
|
||||
id: viewletId,
|
||||
order: order,
|
||||
pinned: (container.active || (<any>container).visible) ?? true, // {{SQL CARBON EDIT}} strict-null-checks
|
||||
visible: (container.active || (<any>container).visible) ?? true // {{SQL CARBON EDIT}} strict-null-checks
|
||||
};
|
||||
|
||||
sidebarState.push(state);
|
||||
}
|
||||
|
||||
if (container.views !== undefined) {
|
||||
const viewsState: { id: string, isHidden?: boolean, order?: number }[] = [];
|
||||
const viewsWorkspaceState: { [id: string]: { collapsed: boolean, isHidden?: boolean, size?: number } } = {};
|
||||
|
||||
for (const view of container.views) {
|
||||
if (view.order !== undefined || view.visible !== undefined) {
|
||||
viewsState.push({
|
||||
id: view.id,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
order: view.order === undefined ? undefined : view.order
|
||||
});
|
||||
}
|
||||
|
||||
if (view.collapsed !== undefined) {
|
||||
viewsWorkspaceState[view.id] = {
|
||||
collapsed: view.collapsed,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
storageService.store(`${viewletId}.state.hidden`, JSON.stringify(viewsState), StorageScope.GLOBAL);
|
||||
storageService.store(`${viewletId}.state`, JSON.stringify(viewsWorkspaceState), StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebarState.length) {
|
||||
storageService.store(ActivitybarPart.PINNED_VIEWLETS, JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { panel } = defaultLayout;
|
||||
if (panel) {
|
||||
if (panel.visible !== undefined) {
|
||||
if (panel.visible) {
|
||||
storageService.store(Storage.PANEL_HIDDEN, false, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.remove(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel.containers?.length) {
|
||||
const panelState: PanelActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of panel.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let name;
|
||||
let panelId = container.id;
|
||||
switch (panelId) {
|
||||
case 'terminal':
|
||||
name = 'Terminal';
|
||||
panelId = 'workbench.panel.terminal';
|
||||
break;
|
||||
case 'debug':
|
||||
name = 'Debug Console';
|
||||
panelId = 'workbench.panel.repl';
|
||||
break;
|
||||
case 'problems':
|
||||
name = 'Problems';
|
||||
panelId = 'workbench.panel.markers';
|
||||
break;
|
||||
case 'output':
|
||||
name = 'Output';
|
||||
panelId = 'workbench.panel.output';
|
||||
break;
|
||||
case 'comments':
|
||||
name = 'Comments';
|
||||
panelId = 'workbench.panel.comments';
|
||||
break;
|
||||
case 'refactor':
|
||||
name = 'Refactor Preview';
|
||||
panelId = 'refactorPreview';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (container.active) {
|
||||
storageService.store(PanelPart.activePanelSettingsKey, panelId, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
if (container.order !== undefined || (container.active === undefined && (<any>container).visible !== undefined)) { // {{SQL CARBON EDIT}} strict-null-checks
|
||||
order = container.order ?? (order + 1);
|
||||
const state: PanelActivityState = {
|
||||
id: panelId,
|
||||
name: name,
|
||||
order: order,
|
||||
pinned: (container.active || (<any>container).visible) ?? true, // {{SQL CARBON EDIT}} strict-null-checks
|
||||
visible: (container.active || (<any>container).visible) ?? true // {{SQL CARBON EDIT}} strict-null-checks
|
||||
};
|
||||
|
||||
panelState.push(state);
|
||||
}
|
||||
}
|
||||
|
||||
if (panelState.length) {
|
||||
storageService.store(PanelPart.PINNED_PANELS, JSON.stringify(panelState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private resolveEditorsToOpen(fileService: IFileService): Promise<IResourceEditorInputType[]> | IResourceEditorInputType[] {
|
||||
const configuration = this.environmentService.configuration;
|
||||
const hasInitialFilesToOpen = this.hasInitialFilesToOpen();
|
||||
const initialFilesToOpen = this.getInitialFilesToOpen();
|
||||
|
||||
// Only restore editors if we are not instructed to open files initially
|
||||
this.state.editor.restoreEditors = !hasInitialFilesToOpen;
|
||||
this.state.editor.restoreEditors = initialFilesToOpen === undefined;
|
||||
|
||||
// Files to open, diff or create
|
||||
if (hasInitialFilesToOpen) {
|
||||
if (initialFilesToOpen !== undefined) {
|
||||
|
||||
// Files to diff is exclusive
|
||||
return pathsToEditors(configuration.filesToDiff, fileService).then(filesToDiff => {
|
||||
return pathsToEditors(initialFilesToOpen.filesToDiff, fileService).then(filesToDiff => {
|
||||
if (filesToDiff?.length === 2) {
|
||||
return [{
|
||||
leftResource: filesToDiff[0].resource,
|
||||
@@ -549,7 +730,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
// Otherwise: Open/Create files
|
||||
return pathsToEditors(configuration.filesToOpenOrCreate, fileService);
|
||||
return pathsToEditors(initialFilesToOpen.filesToOpenOrCreate, fileService);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -571,13 +752,26 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
return [];
|
||||
}
|
||||
|
||||
private hasInitialFilesToOpen(): boolean {
|
||||
const configuration = this.environmentService.configuration;
|
||||
private getInitialFilesToOpen(): { filesToOpenOrCreate?: IPath[], filesToDiff?: IPath[] } | undefined {
|
||||
const defaultLayout = this.environmentService.options?.defaultLayout;
|
||||
if (defaultLayout?.firstRun && defaultLayout?.editors?.length) {
|
||||
//
|
||||
return {
|
||||
filesToOpenOrCreate: defaultLayout.editors
|
||||
.sort((a, b) => (a.active ? -1 : 1) - (b.active ? -1 : 1))
|
||||
.map(f => ({ fileUri: URI.file(f.path).with({ scheme: f.scheme }), inactive: !f.active }))
|
||||
};
|
||||
}
|
||||
|
||||
return !!(
|
||||
(configuration.filesToOpenOrCreate && configuration.filesToOpenOrCreate.length > 0) ||
|
||||
(configuration.filesToDiff && configuration.filesToDiff.length > 0)
|
||||
);
|
||||
const configuration = this.environmentService.configuration;
|
||||
if (configuration.filesToOpenOrCreate || configuration.filesToDiff) {
|
||||
return {
|
||||
filesToOpenOrCreate: configuration.filesToOpenOrCreate,
|
||||
filesToDiff: configuration.filesToDiff
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private updatePanelPosition() {
|
||||
|
||||
@@ -59,8 +59,8 @@ export class PaneComposite extends Composite implements IPaneComposite {
|
||||
return this.viewPaneContainer.getOptimalWidth();
|
||||
}
|
||||
|
||||
openView(id: string, focus?: boolean): IView {
|
||||
return this.viewPaneContainer.openView(id, focus);
|
||||
openView<T extends IView>(id: string, focus?: boolean): T | undefined {
|
||||
return this.viewPaneContainer.openView(id, focus) as T;
|
||||
}
|
||||
|
||||
getViewPaneContainer(): ViewPaneContainer {
|
||||
|
||||
@@ -73,7 +73,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets2';
|
||||
static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets2';
|
||||
private static readonly PLACEHOLDER_VIEWLETS = 'workbench.activity.placeholderViewlets';
|
||||
|
||||
//#region IView
|
||||
@@ -87,6 +87,9 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
private content: HTMLElement | undefined;
|
||||
|
||||
private homeBar: ActionBar | undefined;
|
||||
private homeBarContainer: HTMLElement | undefined;
|
||||
|
||||
private menuBar: CustomMenubarControl | undefined;
|
||||
private menuBarContainer: HTMLElement | undefined;
|
||||
|
||||
@@ -155,7 +158,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
(id: string, focus?: boolean) => this.viewletService.openViewlet(id, focus),
|
||||
(from: string, to: string, before?: Before2D) => this.compositeBar.move(from, to, before?.verticallyBefore)
|
||||
),
|
||||
compositeSize: 50,
|
||||
compositeSize: 52,
|
||||
colors: (theme: IColorTheme) => this.getActivitybarItemColors(theme),
|
||||
overflowActionSize: ActivitybarPart.ACTION_HEIGHT
|
||||
}));
|
||||
@@ -353,20 +356,20 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private createHomeBar(command: string, title: string, icon: Codicon): void {
|
||||
const homeBarContainer = document.createElement('div');
|
||||
homeBarContainer.setAttribute('aria-label', nls.localize('homeIndicator', "Home"));
|
||||
homeBarContainer.setAttribute('role', 'toolbar');
|
||||
addClass(homeBarContainer, 'home-bar');
|
||||
this.homeBarContainer = document.createElement('div');
|
||||
this.homeBarContainer.setAttribute('aria-label', nls.localize('homeIndicator', "Home"));
|
||||
this.homeBarContainer.setAttribute('role', 'toolbar');
|
||||
addClass(this.homeBarContainer, 'home-bar');
|
||||
|
||||
const homeActionBar = this._register(new ActionBar(homeBarContainer, {
|
||||
this.homeBar = this._register(new ActionBar(this.homeBarContainer, {
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
animated: false
|
||||
}));
|
||||
|
||||
homeActionBar.push(this._register(this.instantiationService.createInstance(HomeAction, command, title, icon)), { icon: true, label: false });
|
||||
this.homeBar.push(this._register(this.instantiationService.createInstance(HomeAction, command, title, icon)), { icon: true, label: false });
|
||||
|
||||
const content = assertIsDefined(this.content);
|
||||
content.prepend(homeBarContainer);
|
||||
content.prepend(this.homeBarContainer);
|
||||
}
|
||||
|
||||
updateStyles(): void {
|
||||
@@ -582,12 +585,15 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
// Layout composite bar
|
||||
let availableHeight = contentAreaSize.height;
|
||||
if (this.globalActivityActionBar) {
|
||||
availableHeight -= (this.globalActivityActionBar.viewItems.length * ActivitybarPart.ACTION_HEIGHT); // adjust height for global actions showing
|
||||
if (this.homeBarContainer) {
|
||||
availableHeight -= this.homeBarContainer.clientHeight;
|
||||
}
|
||||
if (this.menuBarContainer) {
|
||||
availableHeight -= this.menuBarContainer.clientHeight;
|
||||
}
|
||||
if (this.globalActivityActionBar) {
|
||||
availableHeight -= (this.globalActivityActionBar.viewItems.length * ActivitybarPart.ACTION_HEIGHT); // adjust height for global actions showing
|
||||
}
|
||||
this.compositeBar.layout(new Dimension(width, availableHeight));
|
||||
}
|
||||
|
||||
@@ -640,10 +646,11 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
for (const { when } of viewContainerModel.allViewDescriptors) {
|
||||
views.push({ when: when ? when.serialize() : undefined });
|
||||
}
|
||||
const cacheIcon = URI.isUri(viewContainerModel.icon) ? viewContainerModel.icon.scheme === Schemas.file : true;
|
||||
state.push({
|
||||
id: compositeItem.id,
|
||||
name: viewContainerModel.title,
|
||||
icon: URI.isUri(viewContainerModel.icon) && viewContainerModel.icon.scheme === Schemas.file ? viewContainerModel.icon : viewContainerModel.icon,
|
||||
icon: cacheIcon ? viewContainerModel.icon : undefined,
|
||||
views,
|
||||
pinned: compositeItem.pinned,
|
||||
order: compositeItem.order,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
.monaco-workbench .part.activitybar {
|
||||
width: 48px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content {
|
||||
@@ -17,7 +18,7 @@
|
||||
/*
|
||||
* Fix menu jumping and background inheritance in Safari
|
||||
*/
|
||||
.monaco-workbench .activitybar > .content {
|
||||
.monaco-workbench.safari .activitybar > .content {
|
||||
position: absolute;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
@@ -59,19 +59,10 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation);
|
||||
const newContainer = this.viewDescriptorService.getViewContainerById(viewsToMove[0].id)!;
|
||||
this.moveComposite(newContainer.id, targetCompositeId, before);
|
||||
this.viewDescriptorService.moveViewContainerToLocation(currentContainer, this.targetContainerLocation);
|
||||
this.moveComposite(currentContainer.id, targetCompositeId, before);
|
||||
|
||||
if (viewsToMove.length > 1) {
|
||||
this.viewDescriptorService.moveViewsToContainer(viewsToMove.slice(1), newContainer);
|
||||
}
|
||||
|
||||
this.openComposite(newContainer.id, true).then(composite => {
|
||||
if (composite && viewsToMove.length === 1) {
|
||||
composite.openView(viewsToMove[0].id, true);
|
||||
}
|
||||
});
|
||||
this.openComposite(currentContainer.id, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +231,9 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
onDragLeave: (e: IDraggedCompositeData) => {
|
||||
toggleClass(parent, 'dragged-over', false);
|
||||
},
|
||||
onDragEnd: (e: IDraggedCompositeData) => {
|
||||
toggleClass(parent, 'dragged-over', false);
|
||||
},
|
||||
onDrop: (e: IDraggedCompositeData) => {
|
||||
const pinnedItems = this.getPinnedComposites();
|
||||
this.options.dndHandler.drop(e.dragAndDropData, pinnedItems[pinnedItems.length - 1].id, e.eventData, { horizontallyBefore: false, verticallyBefore: false });
|
||||
|
||||
@@ -17,7 +17,7 @@ import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { DelayedDragHandler } from 'vs/base/browser/dnd';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { CompositeDragAndDropObserver, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
@@ -477,32 +477,34 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
|
||||
CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
|
||||
}
|
||||
|
||||
this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = undefined; this.updateActivity(); }, this));
|
||||
this._register(compositeActivityAction.onDidChangeActivity(() => {
|
||||
this.compositeActivity = undefined;
|
||||
this.updateActivity();
|
||||
}, this));
|
||||
this._register(Event.any(
|
||||
compositeActivityAction.onDidChangeActivity,
|
||||
Event.filter(keybindingService.onDidUpdateKeybindings, () => this.compositeActivity!.name !== this.getActivtyName())
|
||||
)(() => {
|
||||
if (this.compositeActivity && this.compositeActivity.name !== this.getActivtyName()) {
|
||||
this.compositeActivity = undefined;
|
||||
this.updateActivity();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected get activity(): IActivity {
|
||||
if (!this.compositeActivity) {
|
||||
let activityName: string;
|
||||
const keybinding = typeof this.compositeActivityAction.activity.keybindingId === 'string' ? this.getKeybindingLabel(this.compositeActivityAction.activity.keybindingId) : null;
|
||||
if (keybinding) {
|
||||
activityName = nls.localize('titleKeybinding', "{0} ({1})", this.compositeActivityAction.activity.name, keybinding);
|
||||
} else {
|
||||
activityName = this.compositeActivityAction.activity.name;
|
||||
}
|
||||
|
||||
this.compositeActivity = { ...this.compositeActivityAction.activity, ... { name: activityName } };
|
||||
this.compositeActivity = {
|
||||
...this.compositeActivityAction.activity,
|
||||
... { name: this.getActivtyName() }
|
||||
};
|
||||
}
|
||||
|
||||
return this.compositeActivity;
|
||||
}
|
||||
|
||||
private getKeybindingLabel(id: string): string | null {
|
||||
const kb = this.keybindingService.lookupKeybinding(id);
|
||||
if (kb) {
|
||||
return kb.getLabel();
|
||||
}
|
||||
|
||||
return null;
|
||||
private getActivtyName(): string {
|
||||
const keybinding = this.compositeActivityAction.activity.keybindingId ? this.keybindingService.lookupKeybinding(this.compositeActivityAction.activity.keybindingId) : null;
|
||||
return keybinding ? nls.localize('titleKeybinding', "{0} ({1})", this.compositeActivityAction.activity.name, keybinding.getLabel()) : this.compositeActivityAction.activity.name;
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
|
||||
@@ -24,7 +24,6 @@ import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platf
|
||||
import { ResourceLabels, IResourceLabel, DEFAULT_LABELS_CONTAINER } from 'vs/workbench/browser/labels';
|
||||
import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
|
||||
|
||||
import { IAsyncDataSource, ITreeRenderer, ITreeNode, ITreeFilter, TreeVisibility, ITreeSorter } from 'vs/base/browser/ui/tree/tree';
|
||||
import { OutlineVirtualDelegate, OutlineGroupRenderer, OutlineElementRenderer, OutlineItemComparator, OutlineIdentityProvider, OutlineNavigationLabelProvider, OutlineDataSource, OutlineSortOrder, OutlineFilter, OutlineAccessibilityProvider } from 'vs/editor/contrib/documentSymbols/outlineTree';
|
||||
import { IIdentityProvider, IListVirtualDelegate, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list';
|
||||
|
||||
@@ -52,9 +52,7 @@ export function getEditorPartOptions(config: IWorkbenchEditorConfiguration): IEd
|
||||
return options;
|
||||
}
|
||||
|
||||
if (typeof config.workbench.iconTheme === 'string') {
|
||||
options.iconTheme = config.workbench.iconTheme;
|
||||
}
|
||||
options.iconTheme = config.workbench.iconTheme;
|
||||
|
||||
if (config.workbench.editor) {
|
||||
Object.assign(options, config.workbench.editor);
|
||||
|
||||
@@ -21,6 +21,7 @@ import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/wo
|
||||
import { ItemActivation, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { AllEditorsByMostRecentlyUsedQuickAccess, ActiveGroupEditorsByMostRecentlyUsedQuickAccess, AllEditorsByAppearanceQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
|
||||
export class ExecuteCommandAction extends Action {
|
||||
|
||||
@@ -522,7 +523,8 @@ export abstract class BaseCloseAllAction extends Action {
|
||||
private workingCopyService: IWorkingCopyService,
|
||||
private fileDialogService: IFileDialogService,
|
||||
protected editorGroupService: IEditorGroupsService,
|
||||
private editorService: IEditorService
|
||||
private editorService: IEditorService,
|
||||
private filesConfigurationService: IFilesConfigurationService
|
||||
) {
|
||||
super(id, label, clazz);
|
||||
}
|
||||
@@ -562,31 +564,51 @@ export abstract class BaseCloseAllAction extends Action {
|
||||
}));
|
||||
|
||||
const dirtyEditorsToConfirm = new Set<string>();
|
||||
const dirtyEditorsToAutoSave = new Set<IEditorInput>();
|
||||
|
||||
for (const editor of this.editorService.editors) {
|
||||
if (!editor.isDirty() || editor.isSaving()) {
|
||||
continue; // only interested in dirty editors (unless in the process of saving)
|
||||
}
|
||||
|
||||
let name: string;
|
||||
if (editor instanceof SideBySideEditorInput) {
|
||||
name = editor.master.getName(); // prefer shorter names by using master's name in this case
|
||||
} else {
|
||||
name = editor.getName();
|
||||
// Auto-save on focus change: assume to Save unless the editor is untitled
|
||||
// because bringing up a dialog would save in this case anyway.
|
||||
if (this.filesConfigurationService.getAutoSaveMode() === AutoSaveMode.ON_FOCUS_CHANGE && !editor.isUntitled()) {
|
||||
dirtyEditorsToAutoSave.add(editor);
|
||||
}
|
||||
|
||||
dirtyEditorsToConfirm.add(name);
|
||||
// No auto-save on focus change: ask user
|
||||
else {
|
||||
let name: string;
|
||||
if (editor instanceof SideBySideEditorInput) {
|
||||
name = editor.master.getName(); // prefer shorter names by using master's name in this case
|
||||
} else {
|
||||
name = editor.getName();
|
||||
}
|
||||
|
||||
dirtyEditorsToConfirm.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
const confirm = await this.fileDialogService.showSaveConfirm(Array.from(dirtyEditorsToConfirm.values()));
|
||||
if (confirm === ConfirmResult.CANCEL) {
|
||||
let confirmation: ConfirmResult;
|
||||
let saveReason = SaveReason.EXPLICIT;
|
||||
if (dirtyEditorsToConfirm.size > 0) {
|
||||
confirmation = await this.fileDialogService.showSaveConfirm(Array.from(dirtyEditorsToConfirm.values()));
|
||||
} else if (dirtyEditorsToAutoSave.size > 0) {
|
||||
confirmation = ConfirmResult.SAVE;
|
||||
saveReason = SaveReason.FOCUS_CHANGE;
|
||||
} else {
|
||||
confirmation = ConfirmResult.DONT_SAVE;
|
||||
}
|
||||
|
||||
if (confirmation === ConfirmResult.CANCEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm === ConfirmResult.DONT_SAVE) {
|
||||
if (confirmation === ConfirmResult.DONT_SAVE) {
|
||||
await this.editorService.revertAll({ soft: true, includeUntitled: true });
|
||||
} else {
|
||||
await this.editorService.saveAll({ reason: SaveReason.EXPLICIT, includeUntitled: true });
|
||||
await this.editorService.saveAll({ reason: saveReason, includeUntitled: true });
|
||||
}
|
||||
|
||||
if (!this.workingCopyService.hasDirty) {
|
||||
@@ -608,9 +630,10 @@ export class CloseAllEditorsAction extends BaseCloseAllAction {
|
||||
@IWorkingCopyService workingCopyService: IWorkingCopyService,
|
||||
@IFileDialogService fileDialogService: IFileDialogService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@IEditorService editorService: IEditorService
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
|
||||
) {
|
||||
super(id, label, Codicon.closeAll.classNames, workingCopyService, fileDialogService, editorGroupService, editorService);
|
||||
super(id, label, Codicon.closeAll.classNames, workingCopyService, fileDialogService, editorGroupService, editorService, filesConfigurationService);
|
||||
}
|
||||
|
||||
protected async doCloseAll(): Promise<void> {
|
||||
@@ -629,9 +652,10 @@ export class CloseAllEditorGroupsAction extends BaseCloseAllAction {
|
||||
@IWorkingCopyService workingCopyService: IWorkingCopyService,
|
||||
@IFileDialogService fileDialogService: IFileDialogService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@IEditorService editorService: IEditorService
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
|
||||
) {
|
||||
super(id, label, undefined, workingCopyService, fileDialogService, editorGroupService, editorService);
|
||||
super(id, label, undefined, workingCopyService, fileDialogService, editorGroupService, editorService, filesConfigurationService);
|
||||
}
|
||||
|
||||
protected async doCloseAll(): Promise<void> {
|
||||
|
||||
@@ -52,6 +52,7 @@ import { EditorActivation, EditorOpenContext } from 'vs/platform/editor/common/e
|
||||
import { IDialogService, IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
|
||||
export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
@@ -134,7 +135,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IEditorService private readonly editorService: EditorServiceImpl
|
||||
@IEditorService private readonly editorService: EditorServiceImpl,
|
||||
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -1306,30 +1308,43 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return false; // editor is still editable somewhere else
|
||||
}
|
||||
|
||||
// Switch to editor that we want to handle and confirm to save/revert
|
||||
await this.openEditor(editor);
|
||||
|
||||
let name: string;
|
||||
if (editor instanceof SideBySideEditorInput) {
|
||||
name = editor.master.getName(); // prefer shorter names by using master's name in this case
|
||||
} else {
|
||||
name = editor.getName();
|
||||
// Auto-save on focus change: assume to Save unless the editor is untitled
|
||||
// because bringing up a dialog would save in this case anyway.
|
||||
let confirmation: ConfirmResult;
|
||||
let saveReason = SaveReason.EXPLICIT;
|
||||
if (this.filesConfigurationService.getAutoSaveMode() === AutoSaveMode.ON_FOCUS_CHANGE && !editor.isUntitled()) {
|
||||
confirmation = ConfirmResult.SAVE;
|
||||
saveReason = SaveReason.FOCUS_CHANGE;
|
||||
}
|
||||
|
||||
const res = await this.fileDialogService.showSaveConfirm([name]);
|
||||
// No auto-save on focus change: ask user
|
||||
else {
|
||||
|
||||
// Switch to editor that we want to handle and confirm to save/revert
|
||||
await this.openEditor(editor);
|
||||
|
||||
let name: string;
|
||||
if (editor instanceof SideBySideEditorInput) {
|
||||
name = editor.master.getName(); // prefer shorter names by using master's name in this case
|
||||
} else {
|
||||
name = editor.getName();
|
||||
}
|
||||
|
||||
confirmation = await this.fileDialogService.showSaveConfirm([name]);
|
||||
}
|
||||
|
||||
// It could be that the editor saved meanwhile or is saving, so we check
|
||||
// again to see if anything needs to happen before closing for good.
|
||||
// This can happen for example if autoSave: onFocusChange is configured
|
||||
// so that the save happens when the dialog opens.
|
||||
if (!editor.isDirty() || editor.isSaving()) {
|
||||
return res === ConfirmResult.CANCEL ? true : false;
|
||||
return confirmation === ConfirmResult.CANCEL ? true : false;
|
||||
}
|
||||
|
||||
// Otherwise, handle accordingly
|
||||
switch (res) {
|
||||
switch (confirmation) {
|
||||
case ConfirmResult.SAVE:
|
||||
await editor.save(this.id, { reason: SaveReason.EXPLICIT });
|
||||
await editor.save(this.id, { reason: saveReason });
|
||||
|
||||
return editor.isDirty(); // veto if still dirty
|
||||
case ConfirmResult.DONT_SAVE:
|
||||
|
||||
@@ -444,7 +444,6 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
this.screenRedearModeElement.value = this.statusbarService.addEntry({
|
||||
text,
|
||||
ariaLabel: text,
|
||||
tooltip: nls.localize('screenReaderDetectedExtra', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."),
|
||||
command: 'showEditorScreenReaderNotification',
|
||||
backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND),
|
||||
color: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_FOREGROUND)
|
||||
|
||||
@@ -334,23 +334,18 @@ export class TabsTitleControl extends TitleControl {
|
||||
}
|
||||
|
||||
// Shift-key enables or disables this behaviour depending on the setting
|
||||
if (this.accessor.partOptions.scrollToSwitchTabs === 'off') {
|
||||
if (!e.shiftKey) {
|
||||
return; // 'off': only enable this when Shift-key is pressed
|
||||
}
|
||||
} else {
|
||||
if (this.accessor.partOptions.scrollToSwitchTabs === true) {
|
||||
if (e.shiftKey) {
|
||||
return; // 'on': only enable this when Shift-key is not pressed
|
||||
}
|
||||
} else {
|
||||
if (!e.shiftKey) {
|
||||
return; // 'off': only enable this when Shift-key is pressed
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out scrolling direction
|
||||
let scrollingUp = e.deltaX < 0 || e.deltaY < 0;
|
||||
if (this.accessor.partOptions.scrollToSwitchTabs === 'reverse') {
|
||||
scrollingUp = !scrollingUp;
|
||||
}
|
||||
|
||||
const nextEditor = this.group.getEditorByIndex(this.group.getIndexOfEditor(activeEditor) + (scrollingUp ? -1 : 1));
|
||||
const nextEditor = this.group.getEditorByIndex(this.group.getIndexOfEditor(activeEditor) + (e.deltaX < 0 || e.deltaY < 0 /* scrolling up */ ? -1 : 1));
|
||||
if (!nextEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
static readonly activePanelSettingsKey = 'workbench.panelpart.activepanelid';
|
||||
|
||||
private static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
||||
static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
||||
private static readonly MIN_COMPOSITE_BAR_WIDTH = 50;
|
||||
|
||||
_serviceBrand: undefined;
|
||||
@@ -222,14 +222,27 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
}
|
||||
|
||||
private onDidDeregisterPanel(panelId: string): void {
|
||||
private async onDidDeregisterPanel(panelId: string): Promise<void> {
|
||||
const disposable = this.panelDisposables.get(panelId);
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
|
||||
this.panelDisposables.delete(panelId);
|
||||
this.hideComposite(panelId);
|
||||
|
||||
const activeContainers = this.viewDescriptorService.getViewContainersByLocation(ViewContainerLocation.Panel)
|
||||
.filter(container => this.viewDescriptorService.getViewContainerModel(container).activeViewDescriptors.length > 0);
|
||||
|
||||
if (activeContainers.length) {
|
||||
if (this.getActivePanel()?.getId() === panelId) {
|
||||
const defaultPanelId = this.panelRegistry.getDefaultPanelId();
|
||||
const containerToOpen = activeContainers.filter(c => c.id === defaultPanelId)[0] || activeContainers[0];
|
||||
await this.openPanel(containerToOpen.id);
|
||||
}
|
||||
} else {
|
||||
this.layoutService.setPanelHidden(true);
|
||||
}
|
||||
|
||||
this.removeComposite(panelId);
|
||||
}
|
||||
|
||||
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
||||
@@ -287,6 +300,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
this.compositeBar.onDidChange(() => this.saveCachedPanels(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
private onDidRegisterExtensions(): void {
|
||||
@@ -537,6 +551,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
protected removeComposite(compositeId: string): boolean {
|
||||
if (super.removeComposite(compositeId)) {
|
||||
this.compositeBar.removeComposite(compositeId);
|
||||
const compositeActions = this.compositeActions.get(compositeId);
|
||||
if (compositeActions) {
|
||||
compositeActions.activityAction.dispose();
|
||||
|
||||
@@ -34,6 +34,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { LayoutPriority } from 'vs/base/browser/ui/grid/grid';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { CompositeDragAndDropObserver } from 'vs/workbench/browser/dnd';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
||||
export class SidebarPart extends CompositePart<Viewlet> implements IViewletService {
|
||||
|
||||
@@ -93,6 +94,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService
|
||||
) {
|
||||
@@ -134,9 +136,18 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
|
||||
// Viewlet deregister
|
||||
this._register(this.registry.onDidDeregister(async (viewletDescriptor: ViewletDescriptor) => {
|
||||
const activeViewlet = this.getActiveViewlet();
|
||||
if (!activeViewlet || activeViewlet.getId() === viewletDescriptor.id) {
|
||||
await this.openViewlet(this.getDefaultViewletId());
|
||||
|
||||
const activeContainers = this.viewDescriptorService.getViewContainersByLocation(ViewContainerLocation.Sidebar)
|
||||
.filter(container => this.viewDescriptorService.getViewContainerModel(container).activeViewDescriptors.length > 0);
|
||||
|
||||
if (activeContainers.length) {
|
||||
if (this.getActiveComposite()?.getId() === viewletDescriptor.id) {
|
||||
const defaultViewletId = this.getDefaultViewletId();
|
||||
const containerToOpen = activeContainers.filter(c => c.id === defaultViewletId)[0] || activeContainers[0];
|
||||
await this.openViewlet(containerToOpen.id);
|
||||
}
|
||||
} else {
|
||||
this.layoutService.setSideBarHidden(true);
|
||||
}
|
||||
|
||||
this.removeComposite(viewletDescriptor.id);
|
||||
@@ -165,12 +176,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
|
||||
const draggedItemProvider = (): { type: 'view' | 'composite', id: string } => {
|
||||
const activeViewlet = this.getActiveViewlet()!;
|
||||
const visibleViews = activeViewlet.getViewPaneContainer().views.filter(v => v.isVisible());
|
||||
if (visibleViews.length === 1) {
|
||||
return { type: 'view', id: visibleViews[0].id };
|
||||
} else {
|
||||
return { type: 'composite', id: activeViewlet.getId() };
|
||||
}
|
||||
return { type: 'composite', id: activeViewlet.getId() };
|
||||
};
|
||||
|
||||
this._register(CompositeDragAndDropObserver.INSTANCE.registerDraggable(this.titleLabelElement!, draggedItemProvider, {}));
|
||||
|
||||
@@ -695,6 +695,8 @@ class StatusbarEntryItem extends Disposable {
|
||||
}
|
||||
|
||||
if (!this.entry || entry.ariaLabel !== this.entry.ariaLabel) {
|
||||
// Set the aria label on both elements so screen readers would read the correct thing without duplication #96210
|
||||
this.container.setAttribute('aria-label', entry.ariaLabel);
|
||||
this.labelContainer.setAttribute('aria-label', entry.ariaLabel);
|
||||
}
|
||||
|
||||
@@ -703,7 +705,7 @@ class StatusbarEntryItem extends Disposable {
|
||||
if (entry.tooltip) {
|
||||
this.container.title = entry.tooltip;
|
||||
} else {
|
||||
delete this.container.title;
|
||||
this.container.title = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
max-width: 260px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body .welcome-view-content {
|
||||
|
||||
@@ -458,7 +458,7 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
|
||||
if (linkedText.nodes.length === 1 && typeof linkedText.nodes[0] !== 'string') {
|
||||
const node = linkedText.nodes[0];
|
||||
const button = new Button(this.viewWelcomeContainer, { title: node.title });
|
||||
const button = new Button(this.viewWelcomeContainer, { title: node.title, supportCodicons: true });
|
||||
button.label = node.label;
|
||||
button.onDidClick(_ => {
|
||||
this.telemetryService.publicLog2<{ viewId: string, uri: string }, WelcomeActionClassification>('views.welcomeAction', { viewId: this.id, uri: node.href });
|
||||
@@ -878,8 +878,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
}));
|
||||
|
||||
this._register(this.onDidSashChange(() => this.saveViewSizes()));
|
||||
this.viewContainerModel.onDidAddVisibleViewDescriptors(added => this.onDidAddViewDescriptors(added));
|
||||
this.viewContainerModel.onDidRemoveVisibleViewDescriptors(removed => this.onDidRemoveViewDescriptors(removed));
|
||||
this._register(this.viewContainerModel.onDidAddVisibleViewDescriptors(added => this.onDidAddViewDescriptors(added)));
|
||||
this._register(this.viewContainerModel.onDidRemoveVisibleViewDescriptors(removed => this.onDidRemoveViewDescriptors(removed)));
|
||||
const addedViews: IAddedViewDescriptorRef[] = this.viewContainerModel.visibleViewDescriptors.map((viewDescriptor, index) => {
|
||||
const size = this.viewContainerModel.getSize(viewDescriptor.id);
|
||||
const collapsed = this.viewContainerModel.isCollapsed(viewDescriptor.id);
|
||||
@@ -1140,15 +1140,17 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
});
|
||||
}
|
||||
|
||||
openView(id: string, focus?: boolean): IView {
|
||||
openView(id: string, focus?: boolean): IView | undefined {
|
||||
let view = this.getView(id);
|
||||
if (!view) {
|
||||
this.toggleViewVisibility(id);
|
||||
}
|
||||
view = this.getView(id)!;
|
||||
view.setExpanded(true);
|
||||
if (focus) {
|
||||
view.focus();
|
||||
view = this.getView(id);
|
||||
if (view) {
|
||||
view.setExpanded(true);
|
||||
if (focus) {
|
||||
view.focus();
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
@@ -1199,17 +1201,19 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
panesToRemove.push(this.panes[index]);
|
||||
}
|
||||
this.removePanes(panesToRemove);
|
||||
dispose(panesToRemove);
|
||||
}
|
||||
|
||||
protected toggleViewVisibility(viewId: string): void {
|
||||
const visible = !this.viewContainerModel.isVisible(viewId);
|
||||
type ViewsToggleVisibilityClassification = {
|
||||
viewId: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
visible: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
};
|
||||
this.telemetryService.publicLog2<{ viewId: String, visible: boolean }, ViewsToggleVisibilityClassification>('views.toggleVisibility', { viewId, visible });
|
||||
this.viewContainerModel.setVisible(viewId, visible);
|
||||
// Check if view is active
|
||||
if (this.viewContainerModel.activeViewDescriptors.some(viewDescriptor => viewDescriptor.id === viewId)) {
|
||||
const visible = !this.viewContainerModel.isVisible(viewId);
|
||||
type ViewsToggleVisibilityClassification = {
|
||||
viewId: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
visible: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
};
|
||||
this.telemetryService.publicLog2<{ viewId: String, visible: boolean }, ViewsToggleVisibilityClassification>('views.toggleVisibility', { viewId, visible });
|
||||
this.viewContainerModel.setVisible(viewId, visible);
|
||||
}
|
||||
}
|
||||
|
||||
private addPane(pane: ViewPane, size: number, index = this.paneItems.length - 1): void {
|
||||
@@ -1234,8 +1238,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
leftBorder: PANEL_BORDER,
|
||||
dropBackground: SIDE_BAR_DRAG_AND_DROP_BACKGROUND
|
||||
}, pane);
|
||||
const disposable = combinedDisposable(onDidFocus, onDidChangeTitleArea, paneStyler, onDidChange, onDidChangeVisibility);
|
||||
const paneItem: IViewPaneItem = { pane: pane, disposable };
|
||||
const disposable = combinedDisposable(pane, onDidFocus, onDidChangeTitleArea, paneStyler, onDidChange, onDidChangeVisibility);
|
||||
const paneItem: IViewPaneItem = { pane, disposable };
|
||||
|
||||
this.paneItems.splice(index, 0, paneItem);
|
||||
assertIsDefined(this.paneview).addPane(pane, size, index);
|
||||
|
||||
@@ -39,13 +39,13 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
private readonly viewContainersRegistry: IViewContainersRegistry;
|
||||
private readonly viewDisposable: Map<IViewDescriptor, IDisposable>;
|
||||
private readonly viewPaneContainers: Map<string, { viewPaneContainer: ViewPaneContainer, disposable: IDisposable }>;
|
||||
|
||||
private readonly _onDidChangeViewVisibility: Emitter<{ id: string, visible: boolean }> = this._register(new Emitter<{ id: string, visible: boolean }>());
|
||||
readonly onDidChangeViewVisibility: Event<{ id: string, visible: boolean }> = this._onDidChangeViewVisibility.event;
|
||||
|
||||
private readonly visibleViewContextKeys: Map<string, IContextKey<boolean>>;
|
||||
|
||||
private readonly viewPaneContainers: Map<string, ViewPaneContainer>;
|
||||
|
||||
constructor(
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@@ -59,7 +59,7 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry);
|
||||
this.viewDisposable = new Map<IViewDescriptor, IDisposable>();
|
||||
this.visibleViewContextKeys = new Map<string, IContextKey<boolean>>();
|
||||
this.viewPaneContainers = new Map<string, ViewPaneContainer>();
|
||||
this.viewPaneContainers = new Map<string, { viewPaneContainer: ViewPaneContainer, disposable: IDisposable }>();
|
||||
|
||||
this._register(toDisposable(() => {
|
||||
this.viewDisposable.forEach(disposable => disposable.dispose());
|
||||
@@ -67,17 +67,27 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
}));
|
||||
|
||||
this.viewDescriptorService.getViewContainers().forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!));
|
||||
this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer, viewContainerLocation }) => this.onDidRegisterViewContainer(viewContainer, viewContainerLocation)));
|
||||
|
||||
this._register(this.viewContainersRegistry.onDidDeregister(e => this.viewPaneContainers.delete(e.viewContainer.id)));
|
||||
this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer }) => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!)));
|
||||
this._register(this.viewContainersRegistry.onDidDeregister(e => this.deregisterViewPaneContainer(e.viewContainer.id)));
|
||||
this._register(this.viewDescriptorService.onDidChangeContainerLocation(({ viewContainer, from, to }) => this.onDidChangeContainerLocation(viewContainer, from, to)));
|
||||
}
|
||||
|
||||
private registerViewPaneContainer(viewPaneContainer: ViewPaneContainer): void {
|
||||
this._register(viewPaneContainer.onDidAddViews(views => this.onViewsAdded(views)));
|
||||
this._register(viewPaneContainer.onDidChangeViewVisibility(view => this.onViewsVisibilityChanged(view, view.isBodyVisible())));
|
||||
this._register(viewPaneContainer.onDidRemoveViews(views => this.onViewsRemoved(views)));
|
||||
const disposable = new DisposableStore();
|
||||
disposable.add(viewPaneContainer);
|
||||
disposable.add(viewPaneContainer.onDidAddViews(views => this.onViewsAdded(views)));
|
||||
disposable.add(viewPaneContainer.onDidChangeViewVisibility(view => this.onViewsVisibilityChanged(view, view.isBodyVisible())));
|
||||
disposable.add(viewPaneContainer.onDidRemoveViews(views => this.onViewsRemoved(views)));
|
||||
|
||||
this.viewPaneContainers.set(viewPaneContainer.getId(), viewPaneContainer);
|
||||
this.viewPaneContainers.set(viewPaneContainer.getId(), { viewPaneContainer, disposable });
|
||||
}
|
||||
|
||||
private deregisterViewPaneContainer(id: string): void {
|
||||
const viewPaneContainerItem = this.viewPaneContainers.get(id);
|
||||
if (viewPaneContainerItem) {
|
||||
viewPaneContainerItem.disposable.dispose();
|
||||
this.viewPaneContainers.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
private onViewsAdded(added: IView[]): void {
|
||||
@@ -107,6 +117,11 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return contextKey;
|
||||
}
|
||||
|
||||
private onDidChangeContainerLocation(viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation): void {
|
||||
this.deregisterViewletOrPanel(viewContainer, from);
|
||||
this.registerViewletOrPanel(viewContainer, to);
|
||||
}
|
||||
|
||||
private onDidRegisterViewContainer(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void {
|
||||
this.registerViewletOrPanel(viewContainer, viewContainerLocation);
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
@@ -134,6 +149,7 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
category: composite ? composite.name : localize('view category', "View"),
|
||||
menu: [{
|
||||
id: MenuId.CommandPalette,
|
||||
when: viewDescriptor.when,
|
||||
}],
|
||||
keybinding: {
|
||||
when: ContextKeyExpr.has(`${viewDescriptor.id}.active`),
|
||||
@@ -228,16 +244,22 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
async openView<T extends IView>(id: string, focus: boolean): Promise<T | null> {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
|
||||
if (viewContainer) {
|
||||
const location = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
const compositeDescriptor = this.getComposite(viewContainer.id, location!);
|
||||
if (compositeDescriptor) {
|
||||
const paneComposite = await this.openComposite(compositeDescriptor.id, location!) as IPaneComposite | undefined;
|
||||
if (paneComposite && paneComposite.openView) {
|
||||
return paneComposite.openView(id, focus) as T;
|
||||
} else if (focus) {
|
||||
paneComposite?.focus();
|
||||
}
|
||||
if (!viewContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.viewDescriptorService.getViewContainerModel(viewContainer).activeViewDescriptors.some(viewDescriptor => viewDescriptor.id === id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const location = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
const compositeDescriptor = this.getComposite(viewContainer.id, location!);
|
||||
if (compositeDescriptor) {
|
||||
const paneComposite = await this.openComposite(compositeDescriptor.id, location!) as IPaneComposite | undefined;
|
||||
if (paneComposite && paneComposite.openView) {
|
||||
return paneComposite.openView<T>(id, focus) || null;
|
||||
} else if (focus) {
|
||||
paneComposite?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +312,7 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const view = this.viewPaneContainers.get(viewContainer.id)?.getView(id);
|
||||
const view = this.viewPaneContainers.get(viewContainer.id)?.viewPaneContainer?.getView(id);
|
||||
return view?.getProgressIndicator();
|
||||
}
|
||||
|
||||
@@ -307,6 +329,19 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
}
|
||||
}
|
||||
|
||||
private deregisterViewletOrPanel(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void {
|
||||
switch (viewContainerLocation) {
|
||||
case ViewContainerLocation.Panel:
|
||||
this.deregisterPanel(viewContainer);
|
||||
break;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
if (viewContainer.ctorDescriptor) {
|
||||
this.deregisterViewlet(viewContainer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private registerPanel(viewContainer: ViewContainer): void {
|
||||
const that = this;
|
||||
class PaneContainerPanel extends PaneCompositePanel {
|
||||
@@ -329,12 +364,17 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
PaneContainerPanel,
|
||||
viewContainer.id,
|
||||
viewContainer.name,
|
||||
isString(viewContainer.icon) ? viewContainer.icon : undefined,
|
||||
undefined,
|
||||
viewContainer.order,
|
||||
viewContainer.focusCommand?.id,
|
||||
));
|
||||
}
|
||||
|
||||
private deregisterPanel(viewContainer: ViewContainer): void {
|
||||
this.deregisterViewPaneContainer(viewContainer.id);
|
||||
Registry.as<PanelRegistry>(PanelExtensions.Panels).deregisterPanel(viewContainer.id);
|
||||
}
|
||||
|
||||
private registerViewlet(viewContainer: ViewContainer): void {
|
||||
const that = this;
|
||||
class PaneContainerViewlet extends Viewlet {
|
||||
@@ -364,6 +404,11 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
viewContainer.icon instanceof URI ? viewContainer.icon : undefined
|
||||
));
|
||||
}
|
||||
|
||||
private deregisterViewlet(viewContainer: ViewContainer): void {
|
||||
this.deregisterViewPaneContainer(viewContainer.id);
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).deregisterViewlet(viewContainer.id);
|
||||
}
|
||||
}
|
||||
|
||||
export function createFileIconThemableTreeContainerScope(container: HTMLElement, themeService: IThemeService): IDisposable {
|
||||
|
||||
@@ -38,7 +38,7 @@ import { FileUserDataProvider } from 'vs/workbench/services/userData/common/file
|
||||
import { BACKUPS } from 'vs/platform/environment/common/environment';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { BrowserStorageService } from 'vs/platform/storage/browser/storageService';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
|
||||
import { BufferLogService } from 'vs/platform/log/common/bufferLog';
|
||||
@@ -52,23 +52,6 @@ import { coalesce } from 'vs/base/common/arrays';
|
||||
import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider';
|
||||
import { WebResourceIdentityService, IResourceIdentityService } from 'vs/platform/resource/common/resourceIdentityService';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { firstSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
interface PanelActivityState {
|
||||
id: string;
|
||||
name?: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface SideBarActivityState {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
|
||||
class BrowserMain extends Disposable {
|
||||
|
||||
@@ -82,6 +65,11 @@ class BrowserMain extends Disposable {
|
||||
async open(): Promise<IWorkbench> {
|
||||
const services = await this.initServices();
|
||||
|
||||
// const defaultLayout = this.configuration?.defaultLayout;
|
||||
// if (defaultLayout) {
|
||||
// defaultLayout.firstRun = services.storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL) === undefined;
|
||||
// }
|
||||
|
||||
await domContentLoaded();
|
||||
mark('willStartWorkbench');
|
||||
|
||||
@@ -98,8 +86,6 @@ class BrowserMain extends Disposable {
|
||||
// Listeners
|
||||
this.registerListeners(workbench, services.storageService);
|
||||
|
||||
this.applyDefaultLayout(services.storageService);
|
||||
|
||||
// Driver
|
||||
if (this.configuration.driver) {
|
||||
(async () => this._register(await registerWindowDriver()))();
|
||||
@@ -120,176 +106,6 @@ class BrowserMain extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private applyDefaultLayout(storageService: BrowserStorageService) {
|
||||
const { defaultLayout } = this.configuration;
|
||||
if (!defaultLayout) {
|
||||
return;
|
||||
}
|
||||
|
||||
const firstRun = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL);
|
||||
if (firstRun !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { sidebar } = defaultLayout;
|
||||
if (sidebar) {
|
||||
if (sidebar.visible !== undefined) {
|
||||
if (sidebar.visible) {
|
||||
storageService.remove('workbench.sidebar.hidden', StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.store('workbench.sidebar.hidden', true, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebar.containers !== undefined) {
|
||||
const sidebarState: SideBarActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of sidebar.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let viewletId;
|
||||
switch (container.id) {
|
||||
case 'explorer':
|
||||
viewletId = 'workbench.view.explorer';
|
||||
break;
|
||||
case 'run':
|
||||
viewletId = 'workbench.view.debug';
|
||||
break;
|
||||
case 'scm':
|
||||
viewletId = 'workbench.view.scm';
|
||||
break;
|
||||
case 'search':
|
||||
viewletId = 'workbench.view.search';
|
||||
break;
|
||||
case 'extensions':
|
||||
viewletId = 'workbench.view.extensions';
|
||||
break;
|
||||
case 'remote':
|
||||
viewletId = 'workbench.view.remote';
|
||||
break;
|
||||
default:
|
||||
viewletId = `workbench.view.extension.${container.id}`;
|
||||
}
|
||||
|
||||
order = container.order ?? (order + 1);
|
||||
const state: SideBarActivityState = {
|
||||
id: viewletId,
|
||||
order: order,
|
||||
pinned: true,
|
||||
visible: true
|
||||
};
|
||||
|
||||
if (container.active) {
|
||||
storageService.store('workbench.sidebar.activeviewletid', viewletId, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
if ((<any>container).visible !== undefined) { // {{SQL CARBON EDIT}} strict-null-checks
|
||||
state.pinned = (<any>container).visible; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
state.visible = (<any>container).visible; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
}
|
||||
|
||||
sidebarState.push(state);
|
||||
|
||||
if (container.views !== undefined) {
|
||||
const viewsState: { id: string, isHidden?: boolean, order?: number }[] = [];
|
||||
const viewsWorkspaceState: { [id: string]: { collapsed: boolean, isHidden?: boolean, size?: number } } = {};
|
||||
|
||||
for (const view of container.views) {
|
||||
if (view.order !== undefined || view.visible !== undefined) {
|
||||
viewsState.push({
|
||||
id: view.id,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
order: view.order === undefined ? undefined : view.order
|
||||
});
|
||||
}
|
||||
|
||||
if (view.collapsed !== undefined) {
|
||||
viewsWorkspaceState[view.id] = {
|
||||
collapsed: view.collapsed,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
storageService.store(`${viewletId}.state.hidden`, JSON.stringify(viewsState), StorageScope.GLOBAL);
|
||||
storageService.store(`${viewletId}.state`, JSON.stringify(viewsWorkspaceState), StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
storageService.store('workbench.activity.pinnedViewlets2', JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
const { panel } = defaultLayout;
|
||||
if (panel) {
|
||||
if (panel.visible !== undefined) {
|
||||
if (panel.visible) {
|
||||
storageService.store('workbench.panel.hidden', false, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.remove('workbench.panel.hidden', StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel.containers !== undefined) {
|
||||
const panelState: PanelActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of panel.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let name;
|
||||
let panelId = container.id;
|
||||
switch (panelId) {
|
||||
case 'terminal':
|
||||
name = 'Terminal';
|
||||
panelId = 'workbench.panel.terminal';
|
||||
break;
|
||||
case 'debug':
|
||||
name = 'Debug Console';
|
||||
panelId = 'workbench.panel.repl';
|
||||
break;
|
||||
case 'problems':
|
||||
name = 'Problems';
|
||||
panelId = 'workbench.panel.markers';
|
||||
break;
|
||||
case 'output':
|
||||
name = 'Output';
|
||||
panelId = 'workbench.panel.output';
|
||||
break;
|
||||
case 'comments':
|
||||
name = 'Comments';
|
||||
panelId = 'workbench.panel.comments';
|
||||
break;
|
||||
case 'refactor':
|
||||
name = 'Refactor Preview';
|
||||
panelId = 'refactorPreview';
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
order = container.order ?? (order + 1);
|
||||
const state: PanelActivityState = {
|
||||
id: panelId,
|
||||
name: name,
|
||||
order: order,
|
||||
pinned: true,
|
||||
visible: true
|
||||
};
|
||||
|
||||
if (container.active) {
|
||||
storageService.store('workbench.panelpart.activepanelid', panelId, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
if ((<any>container).visible !== undefined) { // {{SQL CARBON EDIT}} strict-null-checks
|
||||
state.pinned = (<any>container).visible; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
state.visible = (<any>container).visible; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
}
|
||||
|
||||
panelState.push(state);
|
||||
}
|
||||
|
||||
storageService.store('workbench.panel.pinnedPanels', JSON.stringify(panelState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private registerListeners(workbench: Workbench, storageService: BrowserStorageService): void {
|
||||
|
||||
// Layout
|
||||
|
||||
@@ -33,15 +33,9 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
|
||||
'default': true
|
||||
},
|
||||
'workbench.editor.scrollToSwitchTabs': {
|
||||
'type': 'string',
|
||||
'enum': ['off', 'natural', 'reverse'],
|
||||
'enumDescriptions': [
|
||||
nls.localize('workbench.editor.scrollToSwitchTabs.off', "Tabs will reveal when scrolling with the mouse but not open. You can press and hold the Shift-key to switch tabs while scrolling."),
|
||||
nls.localize('workbench.editor.scrollToSwitchTabs.natural', "Tabs will open when scrolling with the mouse in natural scrolling direction (scroll up to switch to the tab on the left and down for the tab on the right). You can press and hold the Shift-key to disable this behaviour for that duration."),
|
||||
nls.localize('workbench.editor.scrollToSwitchTabs.reverse', "Tabs will open when scrolling with the mouse in reverse scrolling direction (scroll down to switch to the tab on the left and up for the tab on the right). You can press and hold the Shift-key to disable this behaviour for that duration."),
|
||||
],
|
||||
'default': 'off',
|
||||
'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'scrollToSwitchTabs' }, "Controls wether scrolling over tabs will open them or not. By default tabs will only reveal upon scrolling, but not open. You can press and hold the Shift-key while scrolling to change this behaviour for that duration.")
|
||||
'type': 'boolean',
|
||||
'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'scrollToSwitchTabs' }, "Controls wether scrolling over tabs will open them or not. By default tabs will only reveal upon scrolling, but not open. You can press and hold the Shift-key while scrolling to change this behaviour for that duration."),
|
||||
'default': false
|
||||
},
|
||||
'workbench.editor.highlightModifiedTabs': {
|
||||
'type': 'boolean',
|
||||
|
||||
Reference in New Issue
Block a user