Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2

This commit is contained in:
ADS Merger
2020-04-23 02:50:35 +00:00
committed by Anthony Dresser
parent 3603f55d97
commit 7f1d8fc32f
659 changed files with 22709 additions and 12497 deletions

View File

@@ -241,10 +241,10 @@ class LogWorkingCopiesAction extends Action {
const developerCategory = nls.localize('developer', "Developer");
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(LogWorkingCopiesAction, LogWorkingCopiesAction.ID, LogWorkingCopiesAction.LABEL), 'Developer: Log Working Copies', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(InspectContextKeysAction), 'Developer: Inspect Context Keys', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleScreencastModeAction), 'Developer: Toggle Screencast Mode', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(LogStorageAction), 'Developer: Log Storage Database Contents', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(LogWorkingCopiesAction), 'Developer: Log Working Copies', developerCategory);
// Screencast Mode
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);

View File

@@ -232,39 +232,39 @@ const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActio
const helpCategory = nls.localize('help', "Help");
if (KeybindingsReferenceAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(KeybindingsReferenceAction, KeybindingsReferenceAction.ID, KeybindingsReferenceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_R) }), 'Help: Keyboard Shortcuts Reference', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(KeybindingsReferenceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_R) }), 'Help: Keyboard Shortcuts Reference', helpCategory);
}
if (OpenDocumentationUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenDocumentationUrlAction, OpenDocumentationUrlAction.ID, OpenDocumentationUrlAction.LABEL), 'Help: Documentation', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenDocumentationUrlAction), 'Help: Documentation', helpCategory);
}
if (OpenIntroductoryVideosUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenIntroductoryVideosUrlAction, OpenIntroductoryVideosUrlAction.ID, OpenIntroductoryVideosUrlAction.LABEL), 'Help: Introductory Videos', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenIntroductoryVideosUrlAction), 'Help: Introductory Videos', helpCategory);
}
if (OpenTipsAndTricksUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenTipsAndTricksUrlAction, OpenTipsAndTricksUrlAction.ID, OpenTipsAndTricksUrlAction.LABEL), 'Help: Tips and Tricks', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenTipsAndTricksUrlAction), 'Help: Tips and Tricks', helpCategory);
}
if (OpenNewsletterSignupUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNewsletterSignupUrlAction, OpenNewsletterSignupUrlAction.ID, OpenNewsletterSignupUrlAction.LABEL), 'Help: Tips and Tricks', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenNewsletterSignupUrlAction), 'Help: Tips and Tricks', helpCategory);
}
if (OpenTwitterUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenTwitterUrlAction, OpenTwitterUrlAction.ID, OpenTwitterUrlAction.LABEL), 'Help: Join Us on Twitter', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenTwitterUrlAction), 'Help: Join Us on Twitter', helpCategory);
}
if (OpenRequestFeatureUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenRequestFeatureUrlAction, OpenRequestFeatureUrlAction.ID, OpenRequestFeatureUrlAction.LABEL), 'Help: Search Feature Requests', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenRequestFeatureUrlAction), 'Help: Search Feature Requests', helpCategory);
}
if (OpenLicenseUrlAction.AVAILABLE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenLicenseUrlAction, OpenLicenseUrlAction.ID, OpenLicenseUrlAction.LABEL), 'Help: View License', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenLicenseUrlAction), 'Help: View License', helpCategory);
}
if (OpenPrivacyStatementUrlAction.AVAILABE) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenPrivacyStatementUrlAction, OpenPrivacyStatementUrlAction.ID, OpenPrivacyStatementUrlAction.LABEL), 'Help: Privacy Statement', helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenPrivacyStatementUrlAction), 'Help: Privacy Statement', helpCategory);
}
// --- Menu Registration

View File

@@ -22,11 +22,12 @@ import { InEditorZenModeContext, IsCenteredLayoutContext, EditorAreaVisibleConte
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { SideBarVisibleContext } from 'vs/workbench/common/viewlet';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IViewDescriptorService, IViewContainersRegistry, Extensions as ViewContainerExtensions, IViewsService, FocusedViewContext, ViewContainerLocation, IViewDescriptor } from 'vs/workbench/common/views';
import { IViewDescriptorService, IViewsService, FocusedViewContext, ViewContainerLocation, IViewDescriptor } from 'vs/workbench/common/views';
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { Codicon } from 'vs/base/common/codicons';
const registry = Registry.as<IWorkbenchActionRegistry>(WorkbenchExtensions.WorkbenchActions);
const viewCategory = nls.localize('view', "View");
@@ -53,7 +54,7 @@ export class CloseSidebarAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseSidebarAction, CloseSidebarAction.ID, CloseSidebarAction.LABEL), 'View: Close Side Bar', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseSidebarAction), 'View: Close Side Bar', viewCategory);
// --- Toggle Activity Bar
@@ -83,7 +84,7 @@ export class ToggleActivityBarVisibilityAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, ToggleActivityBarVisibilityAction.LABEL), 'View: Toggle Activity Bar Visibility', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleActivityBarVisibilityAction), 'View: Toggle Activity Bar Visibility', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '2_workbench_layout',
@@ -116,7 +117,7 @@ class ToggleCenteredLayout extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleCenteredLayout, ToggleCenteredLayout.ID, ToggleCenteredLayout.LABEL), 'View: Toggle Centered Layout', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleCenteredLayout), 'View: Toggle Centered Layout', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '1_toggle_view',
@@ -144,7 +145,7 @@ export class ToggleEditorLayoutAction extends Action {
) {
super(id, label);
this.class = 'codicon-editor-layout';
this.class = Codicon.editorLayout.classNames;
this.updateEnablement();
this.registerListeners();
@@ -166,7 +167,7 @@ export class ToggleEditorLayoutAction extends Action {
}
const group = viewCategory;
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleEditorLayoutAction, ToggleEditorLayoutAction.ID, ToggleEditorLayoutAction.LABEL, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_0, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_0 } }), 'View: Toggle Vertical/Horizontal Editor Layout', group);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleEditorLayoutAction, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_0, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_0 } }), 'View: Toggle Vertical/Horizontal Editor Layout', group);
MenuRegistry.appendMenuItem(MenuId.MenubarLayoutMenu, {
group: 'z_flip',
@@ -209,7 +210,7 @@ export class ToggleSidebarPositionAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleSidebarPositionAction, ToggleSidebarPositionAction.ID, ToggleSidebarPositionAction.LABEL), 'View: Toggle Side Bar Position', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleSidebarPositionAction), 'View: Toggle Side Bar Position', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '3_workbench_layout_move',
@@ -252,7 +253,7 @@ export class ToggleEditorVisibilityAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleEditorVisibilityAction, ToggleEditorVisibilityAction.ID, ToggleEditorVisibilityAction.LABEL), 'View: Toggle Editor Area Visibility', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleEditorVisibilityAction), 'View: Toggle Editor Area Visibility', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '2_workbench_layout',
@@ -285,7 +286,7 @@ export class ToggleSidebarVisibilityAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleSidebarVisibilityAction, ToggleSidebarVisibilityAction.ID, ToggleSidebarVisibilityAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_B }), 'View: Toggle Side Bar Visibility', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleSidebarVisibilityAction, { primary: KeyMod.CtrlCmd | KeyCode.KEY_B }), 'View: Toggle Side Bar Visibility', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
group: '2_appearance',
@@ -332,7 +333,7 @@ export class ToggleStatusbarVisibilityAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleStatusbarVisibilityAction, ToggleStatusbarVisibilityAction.ID, ToggleStatusbarVisibilityAction.LABEL), 'View: Toggle Status Bar Visibility', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleStatusbarVisibilityAction), 'View: Toggle Status Bar Visibility', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '2_workbench_layout',
@@ -369,7 +370,7 @@ class ToggleTabsVisibilityAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleTabsVisibilityAction, ToggleTabsVisibilityAction.ID, ToggleTabsVisibilityAction.LABEL, {
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleTabsVisibilityAction, {
primary: undefined,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_W, },
linux: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_W, }
@@ -396,7 +397,7 @@ class ToggleZenMode extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleZenMode, ToggleZenMode.ID, ToggleZenMode.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_Z) }), 'View: Toggle Zen Mode', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleZenMode, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_Z) }), 'View: Toggle Zen Mode', viewCategory);
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '1_toggle_view',
@@ -457,7 +458,7 @@ export class ToggleMenuBarAction extends Action {
}
if (isWindows || isLinux || isWeb) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleMenuBarAction, ToggleMenuBarAction.ID, ToggleMenuBarAction.LABEL), 'View: Toggle Menu Bar', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleMenuBarAction), 'View: Toggle Menu Bar', viewCategory);
}
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
@@ -486,13 +487,12 @@ export class ResetViewLocationsAction extends Action {
}
async run(): Promise<void> {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
viewContainerRegistry.all.forEach(viewContainer => {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
this.viewDescriptorService.getViewContainers().forEach(viewContainer => {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
viewDescriptors.allViewDescriptors.forEach(viewDescriptor => {
const defaultContainer = this.viewDescriptorService.getDefaultContainer(viewDescriptor.id);
const currentContainer = this.viewDescriptorService.getViewContainer(viewDescriptor.id);
viewContainerModel.allViewDescriptors.forEach(viewDescriptor => {
const defaultContainer = this.viewDescriptorService.getDefaultContainerById(viewDescriptor.id);
const currentContainer = this.viewDescriptorService.getViewContainerByViewId(viewDescriptor.id);
if (defaultContainer && currentContainer !== defaultContainer) {
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], defaultContainer);
@@ -502,7 +502,7 @@ export class ResetViewLocationsAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ResetViewLocationsAction, ResetViewLocationsAction.ID, ResetViewLocationsAction.LABEL), 'View: Reset View Locations', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ResetViewLocationsAction), 'View: Reset View Locations', viewCategory);
// --- Toggle View with Command
export abstract class ToggleViewAction extends Action {
@@ -524,7 +524,7 @@ export abstract class ToggleViewAction extends Action {
const focusedViewId = FocusedViewContext.getValue(this.contextKeyService);
if (focusedViewId === this.viewId) {
if (this.viewDescriptorService.getViewLocation(this.viewId) === ViewContainerLocation.Sidebar) {
if (this.viewDescriptorService.getViewLocationById(this.viewId) === ViewContainerLocation.Sidebar) {
this.layoutService.setSideBarHidden(true);
} else {
this.layoutService.setPanelHidden(true);
@@ -555,8 +555,6 @@ export class MoveFocusedViewAction extends Action {
}
async run(): Promise<void> {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
const focusedViewId = FocusedViewContext.getValue(this.contextKeyService);
if (focusedViewId === undefined || focusedViewId.trim() === '') {
@@ -564,7 +562,7 @@ export class MoveFocusedViewAction extends Action {
return;
}
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(focusedViewId);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(focusedViewId);
if (!viewDescriptor || !viewDescriptor.canMoveView) {
this.notificationService.error(nls.localize('moveFocusedView.error.nonMovableView', "The currently focused view is not movable."));
return;
@@ -581,9 +579,9 @@ export class MoveFocusedViewAction extends Action {
label: nls.localize('sidebar', "Side Bar")
});
const currentContainer = this.viewDescriptorService.getViewContainer(focusedViewId)!;
const currentLocation = this.viewDescriptorService.getViewLocation(focusedViewId)!;
const isViewSolo = this.viewDescriptorService.getViewDescriptors(currentContainer).allViewDescriptors.length === 1;
const currentContainer = this.viewDescriptorService.getViewContainerByViewId(focusedViewId)!;
const currentLocation = this.viewDescriptorService.getViewLocationById(focusedViewId)!;
const isViewSolo = this.viewDescriptorService.getViewContainerModel(currentContainer).allViewDescriptors.length === 1;
if (!(isViewSolo && currentLocation === ViewContainerLocation.Sidebar)) {
items.push({
@@ -595,16 +593,16 @@ export class MoveFocusedViewAction extends Action {
const pinnedViewlets = this.activityBarService.getPinnedViewletIds();
items.push(...pinnedViewlets
.filter(viewletId => {
if (viewletId === this.viewDescriptorService.getViewContainer(focusedViewId)!.id) {
if (viewletId === this.viewDescriptorService.getViewContainerByViewId(focusedViewId)!.id) {
return false;
}
return !viewContainerRegistry.get(viewletId)!.rejectAddedViews;
return !this.viewDescriptorService.getViewContainerById(viewletId)!.rejectAddedViews;
})
.map(viewletId => {
return {
id: viewletId,
label: viewContainerRegistry.get(viewletId)!.name
label: this.viewDescriptorService.getViewContainerById(viewletId)!.name
};
}));
@@ -623,16 +621,16 @@ export class MoveFocusedViewAction extends Action {
const pinnedPanels = this.panelService.getPinnedPanels();
items.push(...pinnedPanels
.filter(panel => {
if (panel.id === this.viewDescriptorService.getViewContainer(focusedViewId)!.id) {
if (panel.id === this.viewDescriptorService.getViewContainerByViewId(focusedViewId)!.id) {
return false;
}
return !viewContainerRegistry.get(panel.id)!.rejectAddedViews;
return !this.viewDescriptorService.getViewContainerById(panel.id)!.rejectAddedViews;
})
.map(panel => {
return {
id: panel.id,
label: viewContainerRegistry.get(panel.id)!.name
label: this.viewDescriptorService.getViewContainerById(panel.id)!.name
};
}));
@@ -648,7 +646,7 @@ export class MoveFocusedViewAction extends Action {
this.viewDescriptorService.moveViewToLocation(viewDescriptor!, ViewContainerLocation.Sidebar);
this.viewsService.openView(focusedViewId, true);
} else if (destination.id) {
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], viewContainerRegistry.get(destination.id)!);
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], this.viewDescriptorService.getViewContainerById(destination.id)!);
this.viewsService.openView(focusedViewId, true);
}
@@ -659,7 +657,7 @@ export class MoveFocusedViewAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveFocusedViewAction, MoveFocusedViewAction.ID, MoveFocusedViewAction.LABEL), 'View: Move Focused View', viewCategory, FocusedViewContext.notEqualsTo(''));
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveFocusedViewAction), 'View: Move Focused View', viewCategory, FocusedViewContext.notEqualsTo(''));
// --- Reset View Location with Command
@@ -683,7 +681,7 @@ export class ResetFocusedViewLocationAction extends Action {
let viewDescriptor: IViewDescriptor | null = null;
if (focusedViewId !== undefined && focusedViewId.trim() !== '') {
viewDescriptor = this.viewDescriptorService.getViewDescriptor(focusedViewId);
viewDescriptor = this.viewDescriptorService.getViewDescriptorById(focusedViewId);
}
if (!viewDescriptor) {
@@ -691,8 +689,8 @@ export class ResetFocusedViewLocationAction extends Action {
return;
}
const defaultContainer = this.viewDescriptorService.getDefaultContainer(viewDescriptor.id);
if (!defaultContainer || defaultContainer === this.viewDescriptorService.getViewContainer(viewDescriptor.id)) {
const defaultContainer = this.viewDescriptorService.getDefaultContainerById(viewDescriptor.id);
if (!defaultContainer || defaultContainer === this.viewDescriptorService.getViewContainerByViewId(viewDescriptor.id)) {
return;
}
@@ -702,7 +700,7 @@ export class ResetFocusedViewLocationAction extends Action {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(ResetFocusedViewLocationAction, ResetFocusedViewLocationAction.ID, ResetFocusedViewLocationAction.LABEL), 'View: Reset Focused View Location', viewCategory, FocusedViewContext.notEqualsTo(''));
registry.registerWorkbenchAction(SyncActionDescriptor.from(ResetFocusedViewLocationAction), 'View: Reset Focused View Location', viewCategory, FocusedViewContext.notEqualsTo(''));
// --- Resize View
@@ -776,5 +774,5 @@ export class DecreaseViewSizeAction extends BaseResizeViewAction {
}
}
registry.registerWorkbenchAction(SyncActionDescriptor.create(IncreaseViewSizeAction, IncreaseViewSizeAction.ID, IncreaseViewSizeAction.LABEL, undefined), 'View: Increase Current View Size', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(DecreaseViewSizeAction, DecreaseViewSizeAction.ID, DecreaseViewSizeAction.LABEL, undefined), 'View: Decrease Current View Size', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(IncreaseViewSizeAction, undefined), 'View: Increase Current View Size', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(DecreaseViewSizeAction, undefined), 'View: Decrease Current View Size', viewCategory);

View File

@@ -15,6 +15,7 @@ import { IPanel } from 'vs/workbench/common/panel';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { Direction } from 'vs/base/browser/ui/grid/grid';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
abstract class BaseNavigationAction extends Action {
@@ -200,10 +201,67 @@ class NavigateDownAction extends BaseNavigationAction {
}
}
function findVisibleNeighbour(layoutService: IWorkbenchLayoutService, part: Parts, next: boolean): Parts {
const neighbour = part === Parts.EDITOR_PART ? (next ? Parts.STATUSBAR_PART : Parts.PANEL_PART) : part === Parts.STATUSBAR_PART ? (next ? Parts.SIDEBAR_PART : Parts.EDITOR_PART) :
part === Parts.SIDEBAR_PART ? (next ? Parts.PANEL_PART : Parts.STATUSBAR_PART) : part === Parts.PANEL_PART ? (next ? Parts.EDITOR_PART : Parts.SIDEBAR_PART) : Parts.EDITOR_PART;
if (layoutService.isVisible(neighbour) || neighbour === Parts.EDITOR_PART) {
return neighbour;
}
return findVisibleNeighbour(layoutService, neighbour, next);
}
function focusNextOrPreviousPart(layoutService: IWorkbenchLayoutService, next: boolean): void {
const currentlyFocusedPart = layoutService.hasFocus(Parts.EDITOR_PART) ? Parts.EDITOR_PART : layoutService.hasFocus(Parts.STATUSBAR_PART) ? Parts.STATUSBAR_PART :
layoutService.hasFocus(Parts.SIDEBAR_PART) ? Parts.SIDEBAR_PART : layoutService.hasFocus(Parts.PANEL_PART) ? Parts.PANEL_PART : undefined;
let partToFocus = Parts.EDITOR_PART;
if (currentlyFocusedPart) {
partToFocus = findVisibleNeighbour(layoutService, currentlyFocusedPart, next);
}
layoutService.focusPart(partToFocus);
}
export class FocusNextPart extends Action {
static readonly ID = 'workbench.action.focusNextPart';
static readonly LABEL = nls.localize('focusNextPart', "Focus Next Part");
constructor(
id: string,
label: string,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
) {
super(id, label);
}
async run(): Promise<void> {
focusNextOrPreviousPart(this.layoutService, true);
}
}
export class FocusPreviousPart extends Action {
static readonly ID = 'workbench.action.focusPreviousPart';
static readonly LABEL = nls.localize('focusPreviousPart', "Focus Previous Part");
constructor(
id: string,
label: string,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
) {
super(id, label);
}
async run(): Promise<void> {
focusNextOrPreviousPart(this.layoutService, false);
}
}
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
const viewCategory = nls.localize('view', "View");
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateUpAction, NavigateUpAction.ID, NavigateUpAction.LABEL, undefined), 'View: Navigate to the View Above', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateDownAction, NavigateDownAction.ID, NavigateDownAction.LABEL, undefined), 'View: Navigate to the View Below', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateLeftAction, NavigateLeftAction.ID, NavigateLeftAction.LABEL, undefined), 'View: Navigate to the View on the Left', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateRightAction, NavigateRightAction.ID, NavigateRightAction.LABEL, undefined), 'View: Navigate to the View on the Right', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateUpAction, undefined), 'View: Navigate to the View Above', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateDownAction, undefined), 'View: Navigate to the View Below', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateLeftAction, undefined), 'View: Navigate to the View on the Left', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateRightAction, undefined), 'View: Navigate to the View on the Right', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusNextPart, { primary: KeyCode.F6 }), 'View: Focus Next Part', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusPreviousPart, { primary: KeyMod.Shift | KeyCode.F6 }), 'View: Focus Previous Part', viewCategory);

View File

@@ -243,9 +243,9 @@ class QuickAccessSelectPreviousAction extends BaseQuickAccessNavigateAction {
}
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessSelectNextAction, QuickAccessSelectNextAction.ID, QuickAccessSelectNextAction.LABEL, { primary: 0, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_N } }, inQuickPickContext, KeybindingWeight.WorkbenchContrib + 50), 'Select Next in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessSelectPreviousAction, QuickAccessSelectPreviousAction.ID, QuickAccessSelectPreviousAction.LABEL, { primary: 0, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_P } }, inQuickPickContext, KeybindingWeight.WorkbenchContrib + 50), 'Select Previous in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessNavigateNextAction, QuickAccessNavigateNextAction.ID, QuickAccessNavigateNextAction.LABEL), 'Navigate Next in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessNavigatePreviousAction, QuickAccessNavigatePreviousAction.ID, QuickAccessNavigatePreviousAction.LABEL), 'Navigate Previous in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessSelectNextAction, { primary: 0, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_N } }, inQuickPickContext, KeybindingWeight.WorkbenchContrib + 50), 'Select Next in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessSelectPreviousAction, { primary: 0, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_P } }, inQuickPickContext, KeybindingWeight.WorkbenchContrib + 50), 'Select Previous in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessNavigateNextAction), 'Navigate Next in Quick Open');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessNavigatePreviousAction), 'Navigate Previous in Quick Open');
//#endregion

View File

@@ -30,6 +30,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { inQuickPickContext, getQuickNavigateHandler } from 'vs/workbench/browser/quickaccess';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { ResourceMap } from 'vs/base/common/map';
import { Codicon } from 'vs/base/common/codicons';
export const inRecentFilesPickerContextKey = 'inRecentFilesPicker';
@@ -41,12 +42,12 @@ interface IRecentlyOpenedPick extends IQuickPickItem {
abstract class BaseOpenRecentAction extends Action {
private readonly removeFromRecentlyOpened: IQuickInputButton = {
iconClass: 'codicon-close',
iconClass: Codicon.removeClose.classNames,
tooltip: nls.localize('remove', "Remove from Recently Opened")
};
private readonly dirtyRecentlyOpened: IQuickInputButton = {
iconClass: 'dirty-workspace codicon-circle-filled',
iconClass: 'dirty-workspace ' + Codicon.closeDirty.classNames,
tooltip: nls.localize('dirtyRecentlyOpened', "Workspace With Dirty Files"),
alwaysVisible: true
};
@@ -336,18 +337,18 @@ const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActio
// --- Actions Registration
const fileCategory = nls.localize('file', "File");
registry.registerWorkbenchAction(SyncActionDescriptor.create(NewWindowAction, NewWindowAction.ID, NewWindowAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_N }), 'New Window');
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickPickRecentAction, QuickPickRecentAction.ID, QuickPickRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenRecentAction, OpenRecentAction.ID, OpenRecentAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NewWindowAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_N }), 'New Window');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickPickRecentAction), 'File: Quick Open Recent...', fileCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenRecentAction, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory);
const viewCategory = nls.localize('view', "View");
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleFullScreenAction, ToggleFullScreenAction.ID, ToggleFullScreenAction.LABEL, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleFullScreenAction, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory);
const developerCategory = nls.localize('developer', "Developer");
registry.registerWorkbenchAction(SyncActionDescriptor.create(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReloadWindowAction), 'Developer: Reload Window', developerCategory);
const helpCategory = nls.localize('help', "Help");
registry.registerWorkbenchAction(SyncActionDescriptor.create(ShowAboutDialogAction, ShowAboutDialogAction.ID, ShowAboutDialogAction.LABEL), `Help: About`, helpCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowAboutDialogAction), `Help: About`, helpCategory);
// --- Commands/Keybindings Registration

View File

@@ -255,11 +255,11 @@ export class DuplicateWorkspaceInNewWindowAction extends Action {
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
const workspacesCategory = nls.localize('workspaces', "Workspaces");
registry.registerWorkbenchAction(SyncActionDescriptor.create(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.create(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(AddRootFolderAction), 'Workspaces: Add Folder to Workspace...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(GlobalRemoveRootFolderAction), 'Workspaces: Remove Folder from Workspace...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseWorkspaceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SaveWorkspaceAsAction), 'Workspaces: Save Workspace As...', workspacesCategory);
registry.registerWorkbenchAction(SyncActionDescriptor.from(DuplicateWorkspaceInNewWindowAction), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory);
// --- Menu Registration

View File

@@ -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 } from 'vs/workbench/common/editor';
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 { 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,6 +41,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
private activeEditorContext: IContextKey<string | null>;
private activeEditorIsReadonly: IContextKey<boolean>;
private activeEditorAvailableEditors: IContextKey<string>;
private activeEditorGroupEmpty: IContextKey<boolean>;
private activeEditorGroupIndex: IContextKey<number>;
@@ -91,6 +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.editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
@@ -206,15 +208,14 @@ export class WorkbenchContextKeysHandler extends Disposable {
if (activeEditorPane) {
this.activeEditorContext.set(activeEditorPane.getId());
try {
this.activeEditorIsReadonly.set(activeEditorPane.input.isReadonly());
} catch (error) {
// TODO@ben for https://github.com/microsoft/vscode/issues/93224
throw new Error(`${error.message}: editor id ${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(','));
} else {
this.activeEditorContext.reset();
this.activeEditorIsReadonly.reset();
this.activeEditorAvailableEditors.reset();
}
}

View File

@@ -289,11 +289,12 @@ class ResourceLabelWidget extends IconLabel {
}
private handleModelEvent(model: ITextModel): void {
if (!this.label || !this.label.resource) {
return; // only update if label exists
const resource = toResource(this.label);
if (!resource) {
return; // only update if resource exists
}
if (model.uri.toString() === this.label.resource.toString()) {
if (model.uri.toString() === resource.toString()) {
if (this.lastKnownDetectedModeId !== model.getModeId()) {
this.render(true); // update if the language id of the model has changed from our last known state
}
@@ -417,8 +418,8 @@ class ResourceLabelWidget extends IconLabel {
}
private clearIconCache(newLabel: IResourceLabelProps, newOptions?: IResourceLabelOptions): boolean {
const newResource = newLabel ? newLabel.resource : undefined;
const oldResource = this.label ? this.label.resource : undefined;
const newResource = toResource(newLabel);
const oldResource = toResource(this.label);
const newFileKind = newOptions ? newOptions.fileKind : undefined;
const oldFileKind = this.options ? this.options.fileKind : undefined;

View File

@@ -10,7 +10,7 @@ import { onDidChangeFullscreen, isFullscreen } from 'vs/base/browser/browser';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { Registry } from 'vs/platform/registry/common/platform';
import { isWindows, isLinux, isMacintosh, isWeb, isNative } from 'vs/base/common/platform';
import { pathsToEditors } from 'vs/workbench/common/editor';
import { pathsToEditors, SideBySideEditorInput } from 'vs/workbench/common/editor';
import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart';
import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart';
import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
@@ -267,6 +267,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this._register(this.editorService.onDidVisibleEditorsChange(showEditorIfHidden));
this._register(this.editorGroupService.onDidActivateGroup(showEditorIfHidden));
// Revalidate center layout when active editor changes: diff editor quits centered mode.
this._register(this.editorService.onDidActiveEditorChange(() => this.centerEditorLayout(this.state.editor.centered)));
// Configuration changes
this._register(this.configurationService.onDidChangeConfiguration(() => this.doUpdateLayoutConfiguration()));
@@ -612,6 +615,32 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
return !!container && isAncestor(activeElement, container);
}
focusPart(part: Parts): void {
switch (part) {
case Parts.EDITOR_PART:
this.editorGroupService.activeGroup.focus();
break;
case Parts.PANEL_PART:
const activePanel = this.panelService.getActivePanel();
if (activePanel) {
activePanel.focus();
}
break;
case Parts.SIDEBAR_PART:
const activeViewlet = this.viewletService.getActiveViewlet();
if (activeViewlet) {
activeViewlet.focus();
}
break;
default:
// Status Bar, Activity Bar and Title Bar simply pass focus to container
const container = this.getContainer(part);
if (container) {
container.focus();
}
}
}
getContainer(part: Parts): HTMLElement | undefined {
switch (part) {
case Parts.TITLEBAR_PART:
@@ -890,6 +919,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
);
this.container.prepend(workbenchGrid.element);
this.container.setAttribute('role', 'application');
this.workbenchGrid = workbenchGrid;
[titleBar, editorPart, activityBar, panelPart, sideBar, statusBar].forEach((part: Part) => {
@@ -956,7 +986,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE);
let smartActive = active;
if (this.editorGroupService.groups.length > 1 && this.configurationService.getValue('workbench.editor.centeredLayoutAutoResize')) {
const activeEditor = this.editorService.activeEditor;
if (this.configurationService.getValue('workbench.editor.centeredLayoutAutoResize')
&& (this.editorGroupService.groups.length > 1 || (activeEditor && activeEditor instanceof SideBySideEditorInput))) {
smartActive = false; // Respect the auto resize setting - do not go into centered layout if there is more than 1 group.
}

View File

@@ -9,19 +9,21 @@
}
.monaco-workbench .part > .drop-block-overlay.visible {
display: block;
backdrop-filter: brightness(97%) blur(2px);
visibility: visible;
opacity: 1;
z-index: 10;
}
.monaco-workbench .part > .drop-block-overlay {
display: none;
width: 100%;
height: 100%;
position: absolute;
top: 0;
width: 100%;
height: 100%;
backdrop-filter: brightness(97%) blur(2px);
pointer-events: none;
visibility: hidden;
opacity: 0;
transition: opacity .5s, visibility .5s;
z-index: 10;
}
.monaco-workbench .part > .title {

View File

@@ -28,6 +28,9 @@ import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/bro
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { Codicon } from 'vs/base/common/codicons';
import { isString } from 'vs/base/common/types';
export class ViewletActivityAction extends ActivityAction {
@@ -249,13 +252,17 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction {
constructor(
id: string,
name: string,
iconUrl: URI | undefined,
icon: URI | string | undefined,
@IViewletService viewletService: IViewletService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@ITelemetryService telemetryService: ITelemetryService
) {
super({ id, name: id, iconUrl }, viewletService, layoutService, telemetryService);
super({
id,
name: id,
iconUrl: URI.isUri(icon) ? icon : undefined,
cssClass: isString(icon) ? icon : undefined
}, viewletService, layoutService, telemetryService);
}
}
@@ -338,9 +345,21 @@ export class NextSideBarViewAction extends SwitchSideBarViewAction {
}
}
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(PreviousSideBarViewAction, PreviousSideBarViewAction.ID, PreviousSideBarViewAction.LABEL), 'View: Previous Side Bar View', nls.localize('view', "View"));
registry.registerWorkbenchAction(SyncActionDescriptor.create(NextSideBarViewAction, NextSideBarViewAction.ID, NextSideBarViewAction.LABEL), 'View: Next Side Bar View', nls.localize('view', "View"));
export class HomeAction extends Action {
constructor(
private readonly command: string,
name: string,
icon: Codicon,
@ICommandService private readonly commandService: ICommandService
) {
super('workbench.action.home', name, icon.classNames);
}
async run(): Promise<void> {
this.commandService.executeCommand(this.command);
}
}
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
@@ -352,6 +371,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label:not(.codicon) {
background-color: ${activeForegroundColor} !important;
}
.monaco-workbench .activitybar > .content .home-bar > .monaco-action-bar .action-item .action-label.codicon,
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label.codicon,
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label.codicon,
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.codicon {
@@ -443,3 +463,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
}
}
});
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.from(PreviousSideBarViewAction), 'View: Previous Side Bar View', nls.localize('view', "View"));
registry.registerWorkbenchAction(SyncActionDescriptor.from(NextSideBarViewAction), 'View: Next Side Bar View', nls.localize('view', "View"));

View File

@@ -6,10 +6,9 @@
import 'vs/css!./media/activitybarpart';
import * as nls from 'vs/nls';
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { GLOBAL_ACTIVITY_ID } from 'vs/workbench/common/activity';
import { Registry } from 'vs/platform/registry/common/platform';
import { GLOBAL_ACTIVITY_ID, IActivity } from 'vs/workbench/common/activity';
import { Part } from 'vs/workbench/browser/part';
import { GlobalActivityActionViewItem, ViewletActivityAction, ToggleViewletAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewletActivityAction, AccountsActionViewItem } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { GlobalActivityActionViewItem, ViewletActivityAction, ToggleViewletAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewletActivityAction, AccountsActionViewItem, HomeAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IBadge, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { IWorkbenchLayoutService, Parts, Position as SideBarPosition } from 'vs/workbench/services/layout/browser/layoutService';
@@ -26,10 +25,10 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { URI, UriComponents } from 'vs/base/common/uri';
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity } from 'vs/workbench/browser/parts/compositeBarActions';
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { IViewDescriptorService, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewDescriptorCollection, ViewContainerLocation } from 'vs/workbench/common/views';
import { IViewDescriptorService, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewContainerModel, ViewContainerLocation } from 'vs/workbench/common/views';
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types';
import { isUndefinedOrNull, assertIsDefined, isString } from 'vs/base/common/types';
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { Schemas } from 'vs/base/common/network';
@@ -38,16 +37,17 @@ import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menuba
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { getMenuBarVisibility } from 'vs/platform/windows/common/windows';
import { isWeb } from 'vs/base/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { getUserDataSyncStore } from 'vs/platform/userDataSync/common/userDataSync';
import { IProductService } from 'vs/platform/product/common/productService';
import { Before2D } from 'vs/workbench/browser/dnd';
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
interface IPlaceholderViewlet {
id: string;
name?: string;
iconUrl?: UriComponents;
iconCSS?: string;
views?: { when?: string }[];
}
@@ -61,7 +61,7 @@ interface IPinnedViewlet {
interface ICachedViewlet {
id: string;
name?: string;
iconUrl?: UriComponents;
icon?: URI | string;
pinned: boolean;
order?: number;
visible: boolean;
@@ -85,19 +85,19 @@ export class ActivitybarPart extends Part implements IActivityBarService {
//#endregion
private content: HTMLElement | undefined;
private menuBar: CustomMenubarControl | undefined;
private menuBarContainer: HTMLElement | undefined;
private compositeBar: CompositeBar;
private globalActivityAction: ActivityAction | undefined;
private globalActivityActionBar: ActionBar | undefined;
private readonly globalActivity: ICompositeActivity[] = [];
private customMenubar: CustomMenubarControl | undefined;
private menubar: HTMLElement | undefined;
private content: HTMLElement | undefined;
private readonly cachedViewlets: ICachedViewlet[] = [];
private compositeBar: CompositeBar;
private readonly compositeActions = new Map<string, { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction }>();
private readonly viewletDisposables = new Map<string, IDisposable>();
constructor(
@@ -110,8 +110,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IWorkbenchEnvironmentService workbenchEnvironmentService: IWorkbenchEnvironmentService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
@IProductService private readonly productService: IProductService
) {
@@ -122,7 +121,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.cachedViewlets = this.getCachedViewlets();
for (const cachedViewlet of this.cachedViewlets) {
if (workbenchEnvironmentService.configuration.remoteAuthority // In remote window, hide activity bar entries until registered.
if (environmentService.configuration.remoteAuthority // In remote window, hide activity bar entries until registered.
|| this.shouldBeHidden(cachedViewlet.id, cachedViewlet)
) {
cachedViewlet.visible = false;
@@ -200,7 +199,6 @@ export class ActivitybarPart extends Part implements IActivityBarService {
private onDidRegisterExtensions(): void {
this.removeNotExistingComposites();
this.saveCachedViewlets();
}
@@ -218,8 +216,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
if (viewletDescriptor) {
const viewContainer = this.getViewContainer(viewletDescriptor.id);
if (viewContainer?.hideIfEmpty) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
if (viewDescriptors.activeViewDescriptors.length === 0) {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
if (viewContainerModel.activeViewDescriptors.length === 0) {
this.hideComposite(viewletDescriptor.id); // Update the composite bar by hiding
}
}
@@ -297,25 +295,25 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
private uninstallMenubar() {
if (this.customMenubar) {
this.customMenubar.dispose();
if (this.menuBar) {
this.menuBar.dispose();
}
if (this.menubar) {
removeNode(this.menubar);
if (this.menuBarContainer) {
removeNode(this.menuBarContainer);
}
}
private installMenubar() {
this.menubar = document.createElement('div');
addClass(this.menubar, 'menubar');
this.menuBarContainer = document.createElement('div');
addClass(this.menuBarContainer, 'menubar');
const content = assertIsDefined(this.content);
content.prepend(this.menubar);
content.prepend(this.menuBarContainer);
// Menubar: install a custom menu bar depending on configuration
this.customMenubar = this._register(this.instantiationService.createInstance(CustomMenubarControl));
this.customMenubar.create(this.menubar);
this.menuBar = this._register(this.instantiationService.createInstance(CustomMenubarControl));
this.menuBar.create(this.menuBarContainer);
}
createContentArea(parent: HTMLElement): HTMLElement {
@@ -325,6 +323,17 @@ export class ActivitybarPart extends Part implements IActivityBarService {
addClass(this.content, 'content');
parent.appendChild(this.content);
// Home action bar
const homeIndicator = this.environmentService.options?.homeIndicator;
if (homeIndicator) {
let codicon = iconRegistry.get(homeIndicator.icon);
if (!codicon) {
console.warn(`Unknown home indicator icon ${homeIndicator.icon}`);
codicon = Codicon.code;
}
this.createHomeBar(homeIndicator.command, homeIndicator.title, codicon);
}
// Install menubar if compact
if (getMenuBarVisibility(this.configurationService, this.environmentService) === 'compact') {
this.installMenubar();
@@ -343,10 +352,26 @@ export class ActivitybarPart extends Part implements IActivityBarService {
return this.content;
}
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');
const homeActionBar = this._register(new ActionBar(homeBarContainer, {
orientation: ActionsOrientation.VERTICAL,
animated: false
}));
homeActionBar.push(this._register(this.instantiationService.createInstance(HomeAction, command, title, icon)), { icon: true, label: false });
const content = assertIsDefined(this.content);
content.prepend(homeBarContainer);
}
updateStyles(): void {
super.updateStyles();
// Part container
const container = assertIsDefined(this.getContainer());
const background = this.getColor(ACTIVITY_BAR_BACKGROUND) || '';
container.style.backgroundColor = background;
@@ -360,7 +385,6 @@ export class ActivitybarPart extends Part implements IActivityBarService {
container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : '';
container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : '';
container.style.borderLeftColor = !isPositionLeft ? borderColor : '';
// container.style.outlineColor = this.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND) ?? '';
}
private getActivitybarItemColors(theme: IColorTheme): ICompositeBarColors {
@@ -397,14 +421,14 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.globalActivityAction = new ActivityAction({
id: 'workbench.actions.manage',
name: nls.localize('manage', "Manage"),
cssClass: 'codicon-settings-gear'
cssClass: Codicon.gear.classNames
});
if (getUserDataSyncStore(this.productService, this.configurationService)) {
const profileAction = new ActivityAction({
id: 'workbench.actions.accounts',
name: nls.localize('accounts', "Accounts"),
cssClass: 'codicon-account'
cssClass: Codicon.account.classNames
});
this.globalActivityActionBar.push(profileAction);
@@ -425,7 +449,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
} else {
const cachedComposite = this.cachedViewlets.filter(c => c.id === compositeId)[0];
compositeActions = {
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite?.name || compositeId, cachedComposite?.iconUrl ? URI.revive(cachedComposite.iconUrl) : undefined),
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite?.icon),
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
};
}
@@ -457,13 +481,16 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
for (const viewlet of viewlets) {
this.enableCompositeActions(viewlet);
const viewContainer = this.getViewContainer(viewlet.id);
if (viewContainer?.hideIfEmpty) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
this.onDidChangeActiveViews(viewlet, viewDescriptors);
this.viewletDisposables.set(viewlet.id, viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(viewlet, viewDescriptors)));
}
const viewContainer = this.getViewContainer(viewlet.id)!;
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
this.updateActivity(viewContainer, viewContainerModel);
this.onDidChangeActiveViews(viewContainer, viewContainerModel);
const disposables = new DisposableStore();
disposables.add(viewContainerModel.onDidChangeContainerInfo(() => this.updateActivity(viewContainer, viewContainerModel)));
disposables.add(viewContainerModel.onDidChangeActiveViewDescriptors(() => this.onDidChangeActiveViews(viewContainer, viewContainerModel)));
this.viewletDisposables.set(viewlet.id, disposables);
}
}
@@ -477,11 +504,31 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.hideComposite(viewletId);
}
private onDidChangeActiveViews(viewlet: ViewletDescriptor, viewDescriptors: IViewDescriptorCollection): void {
if (viewDescriptors.activeViewDescriptors.length) {
this.compositeBar.addComposite(viewlet);
} else {
this.hideComposite(viewlet.id);
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
const activity: IActivity = {
id: viewContainer.id,
name: viewContainerModel.title,
iconUrl: URI.isUri(viewContainerModel.icon) ? viewContainerModel.icon : undefined,
cssClass: isString(viewContainerModel.icon) ? viewContainerModel.icon : undefined,
keybindingId: viewContainer.focusCommand?.id || viewContainer.id
};
const { activityAction, pinnedAction } = this.getCompositeActions(viewContainer.id);
activityAction.setActivity(activity);
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
pinnedAction.setActivity(activity);
}
this.saveCachedViewlets();
}
private onDidChangeActiveViews(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
if (viewContainerModel.activeViewDescriptors.length) {
this.compositeBar.addComposite(viewContainer);
} else if (viewContainer.hideIfEmpty) {
this.hideComposite(viewContainer.id);
}
}
@@ -516,17 +563,6 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
}
private enableCompositeActions(viewlet: ViewletDescriptor): void {
const { activityAction, pinnedAction } = this.getCompositeActions(viewlet.id);
if (activityAction instanceof PlaceHolderViewletActivityAction) {
activityAction.setActivity(viewlet);
}
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
pinnedAction.setActivity(viewlet);
}
}
getPinnedViewletIds(): string[] {
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id);
@@ -549,15 +585,14 @@ export class ActivitybarPart extends Part implements IActivityBarService {
if (this.globalActivityActionBar) {
availableHeight -= (this.globalActivityActionBar.viewItems.length * ActivitybarPart.ACTION_HEIGHT); // adjust height for global actions showing
}
if (this.menubar) {
availableHeight -= this.menubar.clientHeight;
if (this.menuBarContainer) {
availableHeight -= this.menuBarContainer.clientHeight;
}
this.compositeBar.layout(new Dimension(width, availableHeight));
}
private getViewContainer(viewletId: string): ViewContainer | undefined {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
return viewContainerRegistry.get(viewletId);
return this.viewDescriptorService.getViewContainerById(viewletId) || undefined;
}
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
@@ -595,21 +630,25 @@ export class ActivitybarPart extends Part implements IActivityBarService {
private saveCachedViewlets(): void {
const state: ICachedViewlet[] = [];
const allViewlets = this.viewletService.getViewlets();
const compositeItems = this.compositeBar.getCompositeBarItems();
for (const compositeItem of compositeItems) {
const viewContainer = this.getViewContainer(compositeItem.id);
const viewlet = allViewlets.filter(({ id }) => id === compositeItem.id)[0];
if (viewlet) {
if (viewContainer) {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
const views: { when: string | undefined }[] = [];
if (viewContainer) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
for (const { when } of viewDescriptors.allViewDescriptors) {
views.push({ when: when ? when.serialize() : undefined });
}
for (const { when } of viewContainerModel.allViewDescriptors) {
views.push({ when: when ? when.serialize() : undefined });
}
state.push({ id: compositeItem.id, name: viewlet.name, iconUrl: viewlet.iconUrl && viewlet.iconUrl.scheme === Schemas.file ? viewlet.iconUrl : undefined, views, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
state.push({
id: compositeItem.id,
name: viewContainerModel.title,
icon: URI.isUri(viewContainerModel.icon) && viewContainerModel.icon.scheme === Schemas.file ? viewContainerModel.icon : viewContainerModel.icon,
views,
pinned: compositeItem.pinned,
order: compositeItem.order,
visible: compositeItem.visible
});
} else {
state.push({ id: compositeItem.id, pinned: compositeItem.pinned, order: compositeItem.order, visible: false });
}
@@ -619,12 +658,13 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
private getCachedViewlets(): ICachedViewlet[] {
const cachedViewlets: Array<ICachedViewlet> = JSON.parse(this.pinnedViewletsValue);
for (const placeholderViewlet of JSON.parse(this.placeholderViewletsValue)) {
const cachedViewlets: ICachedViewlet[] = this.getPinnedViewlets();
for (const placeholderViewlet of this.getPlaceholderViewlets()) {
const cachedViewlet = cachedViewlets.filter(cached => cached.id === placeholderViewlet.id)[0];
if (cachedViewlet) {
cachedViewlet.name = placeholderViewlet.name;
cachedViewlet.iconUrl = placeholderViewlet.iconUrl;
cachedViewlet.icon = placeholderViewlet.iconCSS ? placeholderViewlet.iconCSS :
placeholderViewlet.iconUrl ? URI.revive(placeholderViewlet.iconUrl) : undefined;
cachedViewlet.views = placeholderViewlet.views;
}
}
@@ -633,8 +673,27 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
private storeCachedViewletsState(cachedViewlets: ICachedViewlet[]): void {
this.pinnedViewletsValue = JSON.stringify(cachedViewlets.map(({ id, pinned, visible, order }) => (<IPinnedViewlet>{ id, pinned, visible, order })));
this.placeholderViewletsValue = JSON.stringify(cachedViewlets.map(({ id, iconUrl, name, views }) => (<IPlaceholderViewlet>{ id, iconUrl, name, views })));
this.setPinnedViewlets(cachedViewlets.map(({ id, pinned, visible, order }) => (<IPinnedViewlet>{
id,
pinned,
visible,
order
})));
this.setPlaceholderViewlets(cachedViewlets.map(({ id, icon, name, views }) => (<IPlaceholderViewlet>{
id,
iconUrl: URI.isUri(icon) ? icon : undefined,
iconCSS: isString(icon) ? icon : undefined,
name,
views
})));
}
private getPinnedViewlets(): IPinnedViewlet[] {
return JSON.parse(this.pinnedViewletsValue);
}
private setPinnedViewlets(pinnedViewlets: IPinnedViewlet[]): void {
this.pinnedViewletsValue = JSON.stringify(pinnedViewlets);
}
private _pinnedViewletsValue: string | undefined;
@@ -661,6 +720,14 @@ export class ActivitybarPart extends Part implements IActivityBarService {
this.storageService.store(ActivitybarPart.PINNED_VIEWLETS, value, StorageScope.GLOBAL);
}
private getPlaceholderViewlets(): IPlaceholderViewlet[] {
return JSON.parse(this.placeholderViewletsValue);
}
private setPlaceholderViewlets(placeholderViewlets: IPlaceholderViewlet[]): void {
this.placeholderViewletsValue = JSON.stringify(placeholderViewlets);
}
private _placeholderViewletsValue: string | undefined;
private get placeholderViewletsValue(): string {
if (!this._placeholderViewletsValue) {
@@ -690,7 +757,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
if (value !== undefined) {
const storedStates: Array<string | ICachedViewlet> = JSON.parse(value);
const cachedViewlets = storedStates.map(c => {
const serialized: ICachedViewlet = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: undefined, visible: true, name: undefined, iconUrl: undefined, views: undefined } : c;
const serialized: ICachedViewlet = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: undefined, visible: true, name: undefined, icon: undefined, views: undefined } : c;
serialized.visible = isUndefinedOrNull(serialized.visible) ? true : serialized.visible;
return serialized;
});

View File

@@ -9,6 +9,10 @@
margin-bottom: 4px;
}
.monaco-workbench .activitybar > .content > .home-bar > .monaco-action-bar .action-item {
margin-bottom: 0;
}
.monaco-workbench .activitybar > .content .composite-bar > .monaco-action-bar .action-item::before,
.monaco-workbench .activitybar > .content .composite-bar > .monaco-action-bar .action-item::after {
position: absolute;

View File

@@ -14,6 +14,27 @@
justify-content: space-between;
}
/*
* Fix menu jumping and background inheritance in Safari
*/
.monaco-workbench .activitybar > .content {
position: absolute;
background-color: inherit;
}
/** Home Bar */
.monaco-workbench .activitybar > .content > .home-bar {
width: 100%;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
order: -1;
}
/** Viewlet Switcher */
.monaco-workbench .activitybar > .content .monaco-action-bar {
text-align: left;
background-color: inherit;
@@ -31,6 +52,8 @@
height: 100%;
}
/** Menu Bar */
.monaco-workbench .activitybar .menubar {
width: 100%;
height: 35px;

View File

@@ -19,8 +19,7 @@ import { Widget } from 'vs/base/browser/ui/widget';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { IColorTheme } from 'vs/platform/theme/common/themeService';
import { Emitter } from 'vs/base/common/event';
import { Registry } from 'vs/platform/registry/common/platform';
import { IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation, IViewDescriptorService } from 'vs/workbench/common/views';
import { ViewContainerLocation, IViewDescriptorService } from 'vs/workbench/common/views';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
import { IComposite } from 'vs/workbench/common/composite';
import { CompositeDragAndDropData, CompositeDragAndDropObserver, IDraggedCompositeData, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd';
@@ -42,65 +41,55 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
private moveComposite: (from: string, to: string, before?: Before2D) => void,
) { }
drop(data: CompositeDragAndDropData, targetCompositeId: string | undefined, originalEvent: DragEvent, before?: Before2D): void {
drop(data: CompositeDragAndDropData, targetCompositeId: string, originalEvent: DragEvent, before?: Before2D): void {
const dragData = data.getData();
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
if (dragData.type === 'composite') {
const currentContainer = viewContainerRegistry.get(dragData.id)!;
const currentLocation = viewContainerRegistry.getViewContainerLocation(currentContainer);
const currentContainer = this.viewDescriptorService.getViewContainerById(dragData.id)!;
const currentLocation = this.viewDescriptorService.getViewContainerLocation(currentContainer);
// Inserting a composite between composites
if (targetCompositeId) {
// ... on the same composite bar
if (currentLocation === this.targetContainerLocation) {
this.moveComposite(dragData.id, targetCompositeId, before);
// ... on the same composite bar
if (currentLocation === this.targetContainerLocation) {
this.moveComposite(dragData.id, targetCompositeId, before);
}
// ... on a different composite bar
else {
const viewsToMove = this.viewDescriptorService.getViewContainerModel(currentContainer)!.allViewDescriptors;
if (viewsToMove.some(v => !v.canMoveView)) {
return;
}
// ... on a different composite bar
else {
const viewsToMove = this.viewDescriptorService.getViewDescriptors(currentContainer)!.allViewDescriptors.filter(vd => vd.canMoveView);
if (viewsToMove.length === 1) {
this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation);
const newContainer = this.viewDescriptorService.getViewContainer(viewsToMove[0].id)!;
this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation);
const newContainer = this.viewDescriptorService.getViewContainerById(viewsToMove[0].id)!;
this.moveComposite(newContainer.id, targetCompositeId, before);
this.moveComposite(newContainer.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(newContainer.id, true).then(composite => {
if (composite && viewsToMove.length === 1) {
composite.openView(viewsToMove[0].id, true);
}
}
} else {
const draggedViews = this.viewDescriptorService.getViewDescriptors(currentContainer).allViewDescriptors;
if (draggedViews.length === 1 && draggedViews[0].canMoveView) {
dragData.type = 'view';
dragData.id = draggedViews[0].id;
}
});
}
}
if (dragData.type === 'view') {
if (targetCompositeId) {
const viewToMove = this.viewDescriptorService.getViewDescriptor(dragData.id)!;
const viewToMove = this.viewDescriptorService.getViewDescriptorById(dragData.id)!;
if (viewToMove && viewToMove.canMoveView) {
this.viewDescriptorService.moveViewToLocation(viewToMove, this.targetContainerLocation);
if (viewToMove && viewToMove.canMoveView) {
this.viewDescriptorService.moveViewToLocation(viewToMove, this.targetContainerLocation);
const newContainer = this.viewDescriptorService.getViewContainer(viewToMove.id)!;
const newContainer = this.viewDescriptorService.getViewContainerByViewId(viewToMove.id)!;
this.moveComposite(newContainer.id, targetCompositeId, before);
this.openComposite(newContainer.id, true).then(composite => {
if (composite) {
composite.openView(viewToMove.id, true);
}
});
}
} else {
this.moveComposite(newContainer.id, targetCompositeId, before);
this.openComposite(newContainer.id, true).then(composite => {
if (composite) {
composite.openView(viewToMove.id, true);
}
});
}
}
}
@@ -115,12 +104,11 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
private canDrop(data: CompositeDragAndDropData, targetCompositeId: string | undefined): boolean {
const dragData = data.getData();
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
if (dragData.type === 'composite') {
// Dragging a composite
const currentContainer = viewContainerRegistry.get(dragData.id)!;
const currentLocation = viewContainerRegistry.getViewContainerLocation(currentContainer);
const currentContainer = this.viewDescriptorService.getViewContainerById(dragData.id)!;
const currentLocation = this.viewDescriptorService.getViewContainerLocation(currentContainer);
// ... to the same composite location
if (currentLocation === this.targetContainerLocation) {
@@ -128,16 +116,13 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
}
// ... to another composite location
const draggedViews = this.viewDescriptorService.getViewDescriptors(currentContainer)!.allViewDescriptors;
if (draggedViews.length !== 1) {
return false;
}
const draggedViews = this.viewDescriptorService.getViewContainerModel(currentContainer)!.allViewDescriptors;
// ... single view
return !!draggedViews[0].canMoveView;
// ... all views must be movable
return !draggedViews.some(v => !v.canMoveView);
} else {
// Dragging an individual view
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dragData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dragData.id);
// ... that cannot move
if (!viewDescriptor || !viewDescriptor.canMoveView) {
@@ -581,7 +566,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
}
overflowingIds = overflowingIds.filter(compositeId => this.visibleComposites.indexOf(compositeId) === -1);
return this.model.visibleItems.filter(c => overflowingIds.indexOf(c.id) !== -1);
return this.model.visibleItems.filter(c => overflowingIds.indexOf(c.id) !== -1).map(item => { return { id: item.id, name: this.getAction(item.id)?.label || item.name }; });
}
private showContextMenu(e: MouseEvent): void {
@@ -597,7 +582,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
const actions: IAction[] = this.model.visibleItems
.map(({ id, name, activityAction }) => (<IAction>{
id,
label: name || id,
label: this.getAction(id).label || name || id,
checked: this.isPinned(id),
enabled: activityAction.enabled,
run: () => {

View File

@@ -18,8 +18,9 @@ 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 { LocalSelectionTransfer, DraggedCompositeIdentifier, DraggedViewIdentifier, CompositeDragAndDropObserver, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd';
import { CompositeDragAndDropObserver, ICompositeDragAndDrop, Before2D } from 'vs/workbench/browser/dnd';
import { Color } from 'vs/base/common/color';
import { Codicon } from 'vs/base/common/codicons';
export interface ICompositeActivity {
badge: IBadge;
@@ -69,6 +70,7 @@ export class ActivityAction extends Action {
}
set activity(activity: IActivity) {
this._label = activity.name;
this._activity = activity;
this._onDidChangeActivity.fire(this);
}
@@ -161,9 +163,11 @@ export class ActivityActionViewItem extends BaseActionViewItem {
if (this.activity.iconUrl) {
// Apply background color to activity bar item provided with iconUrls
this.label.style.backgroundColor = foreground ? foreground.toString() : '';
this.label.style.color = '';
} else {
// Apply foreground color to activity bar items provided with codicons
this.label.style.color = foreground ? foreground.toString() : '';
this.label.style.backgroundColor = '';
}
const dragColor = colors.activeBackgroundColor || colors.activeForegroundColor;
@@ -321,7 +325,7 @@ export class ActivityActionViewItem extends BaseActionViewItem {
this.label.className = 'action-label';
if (this.activity.cssClass) {
dom.addClass(this.label, this.activity.cssClass);
dom.addClasses(this.label, this.activity.cssClass);
}
if (this.options.icon && !this.activity.iconUrl) {
@@ -362,7 +366,7 @@ export class CompositeOverflowActivityAction extends ActivityAction {
super({
id: 'additionalComposites.action',
name: nls.localize('additionalViews', "Additional Views"),
cssClass: 'codicon-more'
cssClass: Codicon.more.classNames
});
}
@@ -452,7 +456,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
private static manageExtensionAction: ManageExtensionAction;
private compositeActivity: IActivity | undefined;
private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier | DraggedViewIdentifier>;
constructor(
private compositeActivityAction: ActivityAction,
@@ -470,8 +473,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
) {
super(compositeActivityAction, { draggable: true, colors, icon }, themeService);
this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier | DraggedViewIdentifier>();
if (!CompositeActionViewItem.manageExtensionAction) {
CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
}
@@ -670,9 +671,6 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
dispose(): void {
super.dispose();
this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype);
this.label.remove();
}
}

View File

@@ -48,6 +48,7 @@ export abstract class BaseEditor extends Composite implements IEditorPane {
get input(): EditorInput | undefined { return this._input; }
protected _options: EditorOptions | undefined;
get options(): EditorOptions | undefined { return this._options; }
private _group?: IEditorGroup;
get group(): IEditorGroup | undefined { return this._group; }
@@ -106,6 +107,8 @@ export abstract class BaseEditor extends Composite implements IEditorPane {
onHide() { }
onWillHide() { }
/**
* Called to create the editor in the parent HTMLElement.
*/

View File

@@ -104,7 +104,7 @@ class Item extends BreadcrumbsItem {
} else if (this.element instanceof OutlineGroup) {
// provider
let label = new IconLabel(container);
label.setLabel(this.element.provider.displayName || '');
label.setLabel(this.element.label);
this._disposables.add(label);
} else if (this.element instanceof OutlineElement) {
@@ -504,7 +504,7 @@ export class BreadcrumbsControl {
const model = OutlineModel.get(element);
if (model) {
this._codeEditorService.openCodeEditor({
resource: model.textModel.uri,
resource: model.uri,
options: {
selection: Range.collapseToStart(element.symbol.selectionRange),
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport
@@ -753,7 +753,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
// open symbol in editor
return editors.openEditor({
resource: outlineElement.textModel.uri,
resource: outlineElement.uri,
options: { selection: Range.collapseToStart(element.symbol.selectionRange) }
}, SIDE_GROUP);

View File

@@ -6,7 +6,6 @@
import { equals } from 'vs/base/common/arrays';
import { TimeoutTimer } from 'vs/base/common/async';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { size, values } from 'vs/base/common/collections';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { DisposableStore } from 'vs/base/common/lifecycle';
@@ -250,7 +249,7 @@ export class EditorBreadcrumbsModel {
if (parent instanceof OutlineModel) {
break;
}
if (parent instanceof OutlineGroup && parent.parent && size(parent.parent.children) === 1) {
if (parent instanceof OutlineGroup && parent.parent && parent.parent.children.size === 1) {
break;
}
item = parent;
@@ -270,7 +269,12 @@ export class EditorBreadcrumbsModel {
}
private _getOutlineElementsRoot(model: OutlineModel): (OutlineModel | OutlineGroup | OutlineElement)[] {
return values(model.children).every(e => this._isFiltered(e)) ? [] : [model];
for (const child of model.children.values()) {
if (!this._isFiltered(child)) {
return [model];
}
}
return [];
}
private _isFiltered(element: TreeElement): boolean {

View File

@@ -26,9 +26,12 @@ 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 } from 'vs/editor/contrib/documentSymbols/outlineTree';
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';
import { IFileIconTheme, IThemeService } from 'vs/platform/theme/common/themeService';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { IModeService } from 'vs/editor/common/services/modeService';
import { localize } from 'vs/nls';
export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker {
return element instanceof FileElement
@@ -272,6 +275,17 @@ class FileNavigationLabelProvider implements IKeyboardNavigationLabelProvider<IW
}
}
class FileAccessibilityProvider implements IListAccessibilityProvider<IWorkspaceFolder | IFileStat> {
getWidgetAriaLabel(): string {
return localize('breadcrumbs', "Breadcrumbs");
}
getAriaLabel(element: IWorkspaceFolder | IFileStat): string | null {
return element.name;
}
}
class FileFilter implements ITreeFilter<IWorkspaceFolder | IFileStat> {
private readonly _cachedExpressions = new Map<string, glob.ParsedExpression>();
@@ -374,16 +388,24 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
const labels = this._instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER /* TODO@Jo visibility propagation */);
this._disposables.add(labels);
return <WorkbenchAsyncDataTree<IWorkspace | URI, IWorkspaceFolder | IFileStat, FuzzyScore>>this._instantiationService.createInstance(WorkbenchAsyncDataTree, 'BreadcrumbsFilePicker', container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), {
multipleSelectionSupport: false,
sorter: new FileSorter(),
filter: this._instantiationService.createInstance(FileFilter),
identityProvider: new FileIdentityProvider(),
keyboardNavigationLabelProvider: new FileNavigationLabelProvider(),
overrideStyles: {
listBackground: breadcrumbsPickerBackground
}
});
return <WorkbenchAsyncDataTree<IWorkspace | URI, IWorkspaceFolder | IFileStat, FuzzyScore>>this._instantiationService.createInstance(
WorkbenchAsyncDataTree,
'BreadcrumbsFilePicker',
container,
new FileVirtualDelegate(),
[this._instantiationService.createInstance(FileRenderer, labels)],
this._instantiationService.createInstance(FileDataSource),
{
multipleSelectionSupport: false,
sorter: new FileSorter(),
filter: this._instantiationService.createInstance(FileFilter),
identityProvider: new FileIdentityProvider(),
keyboardNavigationLabelProvider: new FileNavigationLabelProvider(),
accessibilityProvider: this._instantiationService.createInstance(FileAccessibilityProvider),
overrideStyles: {
listBackground: breadcrumbsPickerBackground
},
});
}
_setInput(element: BreadcrumbElement): Promise<void> {
@@ -436,6 +458,7 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker {
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IConfigurationService configurationService: IConfigurationService,
@IModeService private readonly _modeService: IModeService,
) {
super(parent, instantiationService, themeService, configurationService);
this._symbolSortOrder = BreadcrumbsConfig.SymbolSortOrder.bindTo(this._configurationService);
@@ -457,6 +480,7 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker {
sorter: this._outlineComparator,
identityProvider: new OutlineIdentityProvider(),
keyboardNavigationLabelProvider: new OutlineNavigationLabelProvider(),
accessibilityProvider: new OutlineAccessibilityProvider(localize('breadcrumbs', "Breadcrumbs")),
filter: this._instantiationService.createInstance(OutlineFilter, 'breadcrumbs')
}
);
@@ -472,10 +496,9 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker {
const model = OutlineModel.get(element)!;
const tree = this._tree as WorkbenchDataTree<OutlineModel, any, FuzzyScore>;
const textModel = model.textModel;
const overrideConfiguration = {
resource: textModel.uri,
overrideIdentifier: textModel.getLanguageIdentifier().language
resource: model.uri,
overrideIdentifier: this._modeService.getModeIdByFilepathOrFirstLine(model.uri)
};
this._outlineComparator.type = this._getOutlineItemCompareType(overrideConfiguration);

View File

@@ -258,11 +258,11 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).regi
// Register Status Actions
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ChangeModeAction, ChangeModeAction.ID, ChangeModeAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_M) }), 'Change Language Mode');
registry.registerWorkbenchAction(SyncActionDescriptor.create(ChangeEOLAction, ChangeEOLAction.ID, ChangeEOLAction.LABEL), 'Change End of Line Sequence');
registry.registerWorkbenchAction(SyncActionDescriptor.from(ChangeModeAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_M) }), 'Change Language Mode');
registry.registerWorkbenchAction(SyncActionDescriptor.from(ChangeEOLAction), 'Change End of Line Sequence');
if (Object.keys(SUPPORTED_ENCODINGS).length > 1) {
registry.registerWorkbenchAction(SyncActionDescriptor.create(ChangeEncodingAction, ChangeEncodingAction.ID, ChangeEncodingAction.LABEL), 'Change File Encoding');
registry.registerWorkbenchAction(SyncActionDescriptor.from(ChangeEncodingAction), 'Change File Encoding');
}
// Register Editor Quick Access
@@ -296,90 +296,90 @@ quickAccessRegistry.registerQuickAccessProvider({
// Register Editor Actions
const category = nls.localize('view', "View");
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNextEditor, OpenNextEditor.ID, OpenNextEditor.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.PageDown, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET] } }), 'View: Open Next Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenPreviousEditor, OpenPreviousEditor.ID, OpenPreviousEditor.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.PageUp, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_OPEN_SQUARE_BRACKET] } }), 'View: Open Previous Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNextEditorInGroup, OpenNextEditorInGroup.ID, OpenNextEditorInGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.PageDown), mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow) } }), 'View: Open Next Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenPreviousEditorInGroup, OpenPreviousEditorInGroup.ID, OpenPreviousEditorInGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.PageUp), mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow) } }), 'View: Open Previous Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNextRecentlyUsedEditorAction, OpenNextRecentlyUsedEditorAction.ID, OpenNextRecentlyUsedEditorAction.LABEL), 'View: Open Next Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenPreviousRecentlyUsedEditorAction, OpenPreviousRecentlyUsedEditorAction.ID, OpenPreviousRecentlyUsedEditorAction.LABEL), 'View: Open Previous Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenNextRecentlyUsedEditorInGroupAction, OpenNextRecentlyUsedEditorInGroupAction.ID, OpenNextRecentlyUsedEditorInGroupAction.LABEL), 'View: Open Next Recently Used Editor In Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenPreviousRecentlyUsedEditorInGroupAction, OpenPreviousRecentlyUsedEditorInGroupAction.ID, OpenPreviousRecentlyUsedEditorInGroupAction.LABEL), 'View: Open Previous Recently Used Editor In Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenFirstEditorInGroup, OpenFirstEditorInGroup.ID, OpenFirstEditorInGroup.LABEL), 'View: Open First Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenLastEditorInGroup, OpenLastEditorInGroup.ID, OpenLastEditorInGroup.LABEL, { primary: KeyMod.Alt | KeyCode.KEY_0, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_9], mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_0, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_9] } }), 'View: Open Last Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ReopenClosedEditorAction, ReopenClosedEditorAction.ID, ReopenClosedEditorAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), 'View: Reopen Closed Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ShowAllEditorsByAppearanceAction, ShowAllEditorsByAppearanceAction.ID, ShowAllEditorsByAppearanceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_P), mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Tab } }), 'View: Show All Editors By Appearance', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ShowAllEditorsByMostRecentlyUsedAction, ShowAllEditorsByMostRecentlyUsedAction.ID, ShowAllEditorsByMostRecentlyUsedAction.LABEL), 'View: Show All Editors By Most Recently Used', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ShowEditorsInActiveGroupByMostRecentlyUsedAction, ShowEditorsInActiveGroupByMostRecentlyUsedAction.ID, ShowEditorsInActiveGroupByMostRecentlyUsedAction.LABEL), 'View: Show Editors in Active Group By Most Recently Used', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ClearRecentFilesAction, ClearRecentFilesAction.ID, ClearRecentFilesAction.LABEL), 'File: Clear Recently Opened', nls.localize('file', "File"));
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseAllEditorsAction, CloseAllEditorsAction.ID, CloseAllEditorsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_W) }), 'View: Close All Editors', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseAllEditorGroupsAction, CloseAllEditorGroupsAction.ID, CloseAllEditorGroupsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_W) }), 'View: Close All Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseLeftEditorsInGroupAction, CloseLeftEditorsInGroupAction.ID, CloseLeftEditorsInGroupAction.LABEL), 'View: Close Editors to the Left in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseEditorsInOtherGroupsAction, CloseEditorsInOtherGroupsAction.ID, CloseEditorsInOtherGroupsAction.LABEL), 'View: Close Editors in Other Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(CloseEditorInAllGroupsAction, CloseEditorInAllGroupsAction.ID, CloseEditorInAllGroupsAction.LABEL), 'View: Close Editor in All Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorAction, SplitEditorAction.ID, SplitEditorAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH }), 'View: Split Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorOrthogonalAction, SplitEditorOrthogonalAction.ID, SplitEditorOrthogonalAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_BACKSLASH) }), 'View: Split Editor Orthogonal', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorLeftAction, SplitEditorLeftAction.ID, SplitEditorLeftAction.LABEL), 'View: Split Editor Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorRightAction, SplitEditorRightAction.ID, SplitEditorRightAction.LABEL), 'View: Split Editor Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorUpAction, SplitEditorUpAction.ID, SplitEditorUpAction.LABEL), 'Split Editor Up', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(SplitEditorDownAction, SplitEditorDownAction.ID, SplitEditorDownAction.LABEL), 'View: Split Editor Down', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(JoinTwoGroupsAction, JoinTwoGroupsAction.ID, JoinTwoGroupsAction.LABEL), 'View: Join Editor Group with Next Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(JoinAllGroupsAction, JoinAllGroupsAction.ID, JoinAllGroupsAction.LABEL), 'View: Join All Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateBetweenGroupsAction, NavigateBetweenGroupsAction.ID, NavigateBetweenGroupsAction.LABEL), 'View: Navigate Between Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ResetGroupSizesAction, ResetGroupSizesAction.ID, ResetGroupSizesAction.LABEL), 'View: Reset Editor Group Sizes', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleGroupSizesAction, ToggleGroupSizesAction.ID, ToggleGroupSizesAction.LABEL), 'View: Toggle Editor Group Sizes', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MaximizeGroupAction, MaximizeGroupAction.ID, MaximizeGroupAction.LABEL), 'View: Maximize Editor Group and Hide Side Bar', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MinimizeOtherGroupsAction, MinimizeOtherGroupsAction.ID, MinimizeOtherGroupsAction.LABEL), 'View: Maximize Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorLeftInGroupAction, MoveEditorLeftInGroupAction.ID, MoveEditorLeftInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageUp, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow) } }), 'View: Move Editor Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorRightInGroupAction, MoveEditorRightInGroupAction.ID, MoveEditorRightInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageDown, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow) } }), 'View: Move Editor Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveGroupLeftAction, MoveGroupLeftAction.ID, MoveGroupLeftAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.LeftArrow) }), 'View: Move Editor Group Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveGroupRightAction, MoveGroupRightAction.ID, MoveGroupRightAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.RightArrow) }), 'View: Move Editor Group Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveGroupUpAction, MoveGroupUpAction.ID, MoveGroupUpAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.UpArrow) }), 'View: Move Editor Group Up', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveGroupDownAction, MoveGroupDownAction.ID, MoveGroupDownAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.DownArrow) }), 'View: Move Editor Group Down', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToPreviousGroupAction, MoveEditorToPreviousGroupAction.ID, MoveEditorToPreviousGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow } }), 'View: Move Editor into Previous Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToNextGroupAction, MoveEditorToNextGroupAction.ID, MoveEditorToNextGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow } }), 'View: Move Editor into Next Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToFirstGroupAction, MoveEditorToFirstGroupAction.ID, MoveEditorToFirstGroupAction.LABEL, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_1, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_1 } }), 'View: Move Editor into First Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToLastGroupAction, MoveEditorToLastGroupAction.ID, MoveEditorToLastGroupAction.LABEL, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_9, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_9 } }), 'View: Move Editor into Last Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToLeftGroupAction, MoveEditorToLeftGroupAction.ID, MoveEditorToLeftGroupAction.LABEL), 'View: Move Editor into Left Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToRightGroupAction, MoveEditorToRightGroupAction.ID, MoveEditorToRightGroupAction.LABEL), 'View: Move Editor into Right Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToAboveGroupAction, MoveEditorToAboveGroupAction.ID, MoveEditorToAboveGroupAction.LABEL), 'View: Move Editor into Above Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(MoveEditorToBelowGroupAction, MoveEditorToBelowGroupAction.ID, MoveEditorToBelowGroupAction.LABEL), 'View: Move Editor into Below Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusActiveGroupAction, FocusActiveGroupAction.ID, FocusActiveGroupAction.LABEL), 'View: Focus Active Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusFirstGroupAction, FocusFirstGroupAction.ID, FocusFirstGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_1 }), 'View: Focus First Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusLastGroupAction, FocusLastGroupAction.ID, FocusLastGroupAction.LABEL), 'View: Focus Last Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusPreviousGroup, FocusPreviousGroup.ID, FocusPreviousGroup.LABEL), 'View: Focus Previous Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusNextGroup, FocusNextGroup.ID, FocusNextGroup.LABEL), 'View: Focus Next Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusLeftGroup, FocusLeftGroup.ID, FocusLeftGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.LeftArrow) }), 'View: Focus Left Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusRightGroup, FocusRightGroup.ID, FocusRightGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.RightArrow) }), 'View: Focus Right Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusAboveGroup, FocusAboveGroup.ID, FocusAboveGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.UpArrow) }), 'View: Focus Above Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusBelowGroup, FocusBelowGroup.ID, FocusBelowGroup.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.DownArrow) }), 'View: Focus Below Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NewEditorGroupLeftAction, NewEditorGroupLeftAction.ID, NewEditorGroupLeftAction.LABEL), 'View: New Editor Group to the Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NewEditorGroupRightAction, NewEditorGroupRightAction.ID, NewEditorGroupRightAction.LABEL), 'View: New Editor Group to the Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NewEditorGroupAboveAction, NewEditorGroupAboveAction.ID, NewEditorGroupAboveAction.LABEL), 'View: New Editor Group Above', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NewEditorGroupBelowAction, NewEditorGroupBelowAction.ID, NewEditorGroupBelowAction.LABEL), 'View: New Editor Group Below', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateForwardAction, NavigateForwardAction.ID, NavigateForwardAction.LABEL, { primary: 0, win: { primary: KeyMod.Alt | KeyCode.RightArrow }, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_MINUS }, linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_MINUS } }), 'Go Forward');
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateBackwardsAction, NavigateBackwardsAction.ID, NavigateBackwardsAction.LABEL, { primary: 0, win: { primary: KeyMod.Alt | KeyCode.LeftArrow }, mac: { primary: KeyMod.WinCtrl | KeyCode.US_MINUS }, linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.US_MINUS } }), 'Go Back');
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateToLastEditLocationAction, NavigateToLastEditLocationAction.ID, NavigateToLastEditLocationAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_Q) }), 'Go to Last Edit Location');
registry.registerWorkbenchAction(SyncActionDescriptor.create(NavigateLastAction, NavigateLastAction.ID, NavigateLastAction.LABEL), 'Go Last');
registry.registerWorkbenchAction(SyncActionDescriptor.create(ClearEditorHistoryAction, ClearEditorHistoryAction.ID, ClearEditorHistoryAction.LABEL), 'Clear Editor History');
registry.registerWorkbenchAction(SyncActionDescriptor.create(RevertAndCloseEditorAction, RevertAndCloseEditorAction.ID, RevertAndCloseEditorAction.LABEL), 'View: Revert and Close Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutSingleAction, EditorLayoutSingleAction.ID, EditorLayoutSingleAction.LABEL), 'View: Single Column Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutTwoColumnsAction, EditorLayoutTwoColumnsAction.ID, EditorLayoutTwoColumnsAction.LABEL), 'View: Two Columns Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutThreeColumnsAction, EditorLayoutThreeColumnsAction.ID, EditorLayoutThreeColumnsAction.LABEL), 'View: Three Columns Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutTwoRowsAction, EditorLayoutTwoRowsAction.ID, EditorLayoutTwoRowsAction.LABEL), 'View: Two Rows Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutThreeRowsAction, EditorLayoutThreeRowsAction.ID, EditorLayoutThreeRowsAction.LABEL), 'View: Three Rows Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutTwoByTwoGridAction, EditorLayoutTwoByTwoGridAction.ID, EditorLayoutTwoByTwoGridAction.LABEL), 'View: Grid Editor Layout (2x2)', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutTwoRowsRightAction, EditorLayoutTwoRowsRightAction.ID, EditorLayoutTwoRowsRightAction.LABEL), 'View: Two Rows Right Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(EditorLayoutTwoColumnsBottomAction, EditorLayoutTwoColumnsBottomAction.ID, EditorLayoutTwoColumnsBottomAction.LABEL), 'View: Two Columns Bottom Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenNextEditor, { primary: KeyMod.CtrlCmd | KeyCode.PageDown, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET] } }), 'View: Open Next Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenPreviousEditor, { primary: KeyMod.CtrlCmd | KeyCode.PageUp, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_OPEN_SQUARE_BRACKET] } }), 'View: Open Previous Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenNextEditorInGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.PageDown), mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow) } }), 'View: Open Next Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenPreviousEditorInGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.PageUp), mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow) } }), 'View: Open Previous Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenNextRecentlyUsedEditorAction), 'View: Open Next Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenPreviousRecentlyUsedEditorAction), 'View: Open Previous Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenNextRecentlyUsedEditorInGroupAction), 'View: Open Next Recently Used Editor In Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenPreviousRecentlyUsedEditorInGroupAction), 'View: Open Previous Recently Used Editor In Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenFirstEditorInGroup), 'View: Open First Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenLastEditorInGroup, { primary: KeyMod.Alt | KeyCode.KEY_0, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_9], mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_0, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_9] } }), 'View: Open Last Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReopenClosedEditorAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), 'View: Reopen Closed Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowAllEditorsByAppearanceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_P), mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Tab } }), 'View: Show All Editors By Appearance', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowAllEditorsByMostRecentlyUsedAction), 'View: Show All Editors By Most Recently Used', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowEditorsInActiveGroupByMostRecentlyUsedAction), 'View: Show Editors in Active Group By Most Recently Used', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ClearRecentFilesAction), 'File: Clear Recently Opened', nls.localize('file', "File"));
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseAllEditorsAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_W) }), 'View: Close All Editors', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseAllEditorGroupsAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_W) }), 'View: Close All Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseLeftEditorsInGroupAction), 'View: Close Editors to the Left in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseEditorsInOtherGroupsAction), 'View: Close Editors in Other Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseEditorInAllGroupsAction), 'View: Close Editor in All Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorAction, { primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH }), 'View: Split Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorOrthogonalAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_BACKSLASH) }), 'View: Split Editor Orthogonal', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorLeftAction), 'View: Split Editor Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorRightAction), 'View: Split Editor Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorUpAction), 'Split Editor Up', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(SplitEditorDownAction), 'View: Split Editor Down', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(JoinTwoGroupsAction), 'View: Join Editor Group with Next Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(JoinAllGroupsAction), 'View: Join All Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateBetweenGroupsAction), 'View: Navigate Between Editor Groups', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ResetGroupSizesAction), 'View: Reset Editor Group Sizes', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleGroupSizesAction), 'View: Toggle Editor Group Sizes', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MaximizeGroupAction), 'View: Maximize Editor Group and Hide Side Bar', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MinimizeOtherGroupsAction), 'View: Maximize Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorLeftInGroupAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageUp, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow) } }), 'View: Move Editor Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorRightInGroupAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageDown, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow) } }), 'View: Move Editor Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveGroupLeftAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.LeftArrow) }), 'View: Move Editor Group Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveGroupRightAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.RightArrow) }), 'View: Move Editor Group Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveGroupUpAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.UpArrow) }), 'View: Move Editor Group Up', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveGroupDownAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.DownArrow) }), 'View: Move Editor Group Down', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToPreviousGroupAction, { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow } }), 'View: Move Editor into Previous Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToNextGroupAction, { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.RightArrow, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow } }), 'View: Move Editor into Next Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToFirstGroupAction, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_1, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_1 } }), 'View: Move Editor into First Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToLastGroupAction, { primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_9, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_9 } }), 'View: Move Editor into Last Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToLeftGroupAction), 'View: Move Editor into Left Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToRightGroupAction), 'View: Move Editor into Right Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToAboveGroupAction), 'View: Move Editor into Above Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(MoveEditorToBelowGroupAction), 'View: Move Editor into Below Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusActiveGroupAction), 'View: Focus Active Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusFirstGroupAction, { primary: KeyMod.CtrlCmd | KeyCode.KEY_1 }), 'View: Focus First Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusLastGroupAction), 'View: Focus Last Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusPreviousGroup), 'View: Focus Previous Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusNextGroup), 'View: Focus Next Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusLeftGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.LeftArrow) }), 'View: Focus Left Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusRightGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.RightArrow) }), 'View: Focus Right Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusAboveGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.UpArrow) }), 'View: Focus Above Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusBelowGroup, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.DownArrow) }), 'View: Focus Below Editor Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NewEditorGroupLeftAction), 'View: New Editor Group to the Left', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NewEditorGroupRightAction), 'View: New Editor Group to the Right', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NewEditorGroupAboveAction), 'View: New Editor Group Above', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NewEditorGroupBelowAction), 'View: New Editor Group Below', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateForwardAction, { primary: 0, win: { primary: KeyMod.Alt | KeyCode.RightArrow }, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_MINUS }, linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_MINUS } }), 'Go Forward');
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateBackwardsAction, { primary: 0, win: { primary: KeyMod.Alt | KeyCode.LeftArrow }, mac: { primary: KeyMod.WinCtrl | KeyCode.US_MINUS }, linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.US_MINUS } }), 'Go Back');
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateToLastEditLocationAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_Q) }), 'Go to Last Edit Location');
registry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateLastAction), 'Go Last');
registry.registerWorkbenchAction(SyncActionDescriptor.from(ClearEditorHistoryAction), 'Clear Editor History');
registry.registerWorkbenchAction(SyncActionDescriptor.from(RevertAndCloseEditorAction), 'View: Revert and Close Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutSingleAction), 'View: Single Column Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutTwoColumnsAction), 'View: Two Columns Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutThreeColumnsAction), 'View: Three Columns Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutTwoRowsAction), 'View: Two Rows Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutThreeRowsAction), 'View: Three Rows Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutTwoByTwoGridAction), 'View: Grid Editor Layout (2x2)', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutTwoRowsRightAction), 'View: Two Rows Right Editor Layout', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(EditorLayoutTwoColumnsBottomAction), 'View: Two Columns Bottom Editor Layout', category);
// Register Quick Editor Actions including built in quick navigate support for some
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessPreviousRecentlyUsedEditorAction, QuickAccessPreviousRecentlyUsedEditorAction.ID, QuickAccessPreviousRecentlyUsedEditorAction.LABEL), 'View: Quick Open Previous Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessLeastRecentlyUsedEditorAction, QuickAccessLeastRecentlyUsedEditorAction.ID, QuickAccessLeastRecentlyUsedEditorAction.LABEL), 'View: Quick Open Least Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessPreviousRecentlyUsedEditorAction), 'View: Quick Open Previous Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessLeastRecentlyUsedEditorAction), 'View: Quick Open Least Recently Used Editor', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessPreviousRecentlyUsedEditorInGroupAction, QuickAccessPreviousRecentlyUsedEditorInGroupAction.ID, QuickAccessPreviousRecentlyUsedEditorInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.Tab, mac: { primary: KeyMod.WinCtrl | KeyCode.Tab } }), 'View: Quick Open Previous Recently Used Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessLeastRecentlyUsedEditorInGroupAction, QuickAccessLeastRecentlyUsedEditorInGroupAction.ID, QuickAccessLeastRecentlyUsedEditorInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Tab, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Tab } }), 'View: Quick Open Least Recently Used Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessPreviousRecentlyUsedEditorInGroupAction, { primary: KeyMod.CtrlCmd | KeyCode.Tab, mac: { primary: KeyMod.WinCtrl | KeyCode.Tab } }), 'View: Quick Open Previous Recently Used Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessLeastRecentlyUsedEditorInGroupAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Tab, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Tab } }), 'View: Quick Open Least Recently Used Editor in Group', category);
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickAccessPreviousEditorFromHistoryAction, QuickAccessPreviousEditorFromHistoryAction.ID, QuickAccessPreviousEditorFromHistoryAction.LABEL), 'Quick Open Previous Editor from History');
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickAccessPreviousEditorFromHistoryAction), 'Quick Open Previous Editor from History');
const quickAccessNavigateNextInEditorPickerId = 'workbench.action.quickOpenNavigateNextInEditorPicker';
KeybindingsRegistry.registerCommandAndKeybindingRule({

View File

@@ -20,6 +20,7 @@ import { IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/di
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
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';
export class ExecuteCommandAction extends Action {
@@ -395,7 +396,7 @@ export class CloseEditorAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-close');
super(id, label, Codicon.close.classNames);
}
run(context?: IEditorCommandsContext): Promise<void> {
@@ -413,7 +414,7 @@ export class CloseOneEditorAction extends Action {
label: string,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
) {
super(id, label, 'codicon-close');
super(id, label, Codicon.close.classNames);
}
async run(context?: IEditorCommandsContext): Promise<void> {
@@ -609,7 +610,7 @@ export class CloseAllEditorsAction extends BaseCloseAllAction {
@IEditorGroupsService editorGroupService: IEditorGroupsService,
@IEditorService editorService: IEditorService
) {
super(id, label, 'codicon-close-all', workingCopyService, fileDialogService, editorGroupService, editorService);
super(id, label, Codicon.closeAll.classNames, workingCopyService, fileDialogService, editorGroupService, editorService);
}
protected async doCloseAll(): Promise<void> {

View File

@@ -205,6 +205,7 @@ export class EditorControl extends Disposable {
// Remove editor pane from parent and hide
const editorPaneContainer = this._activeEditorPane.getContainer();
if (editorPaneContainer) {
this._activeEditorPane.onWillHide();
this.parent.removeChild(editorPaneContainer);
hide(editorPaneContainer);
this._activeEditorPane.onHide();

View File

@@ -16,7 +16,7 @@ import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
import { IThemeService, registerThemingParticipant, Themable } from 'vs/platform/theme/common/themeService';
import { editorBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { EDITOR_GROUP_HEADER_TABS_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND, EDITOR_GROUP_EMPTY_BACKGROUND, EDITOR_GROUP_FOCUSED_EMPTY_BORDER } from 'vs/workbench/common/theme';
import { EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND, EDITOR_GROUP_EMPTY_BACKGROUND, EDITOR_GROUP_FOCUSED_EMPTY_BORDER, EDITOR_GROUP_HEADER_BORDER } from 'vs/workbench/common/theme';
import { IMoveEditorOptions, ICopyEditorOptions, ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, GroupsOrder, ICloseEditorOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
import { TabsTitleControl } from 'vs/workbench/browser/parts/editor/tabsTitleControl';
import { EditorControl } from 'vs/workbench/browser/parts/editor/editorControl';
@@ -51,6 +51,7 @@ import { Schemas } from 'vs/base/common/network';
import { EditorActivation, EditorOpenContext } from 'vs/platform/editor/common/editor';
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';
export class EditorGroupView extends Themable implements IEditorGroupView {
@@ -290,7 +291,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
const removeGroupAction = this._register(new Action(
CLOSE_EDITOR_GROUP_COMMAND_ID,
localize('closeGroupAction', "Close"),
'codicon-close',
Codicon.close.classNames,
true,
async () => this.accessor.removeGroup(this)));
@@ -1549,10 +1550,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
}
// Title control
const { showTabs } = this.accessor.partOptions;
const borderColor = this.getColor(EDITOR_GROUP_HEADER_TABS_BORDER) || this.getColor(contrastBorder);
if (!isEmpty && showTabs && borderColor) {
const borderColor = this.getColor(EDITOR_GROUP_HEADER_BORDER) || this.getColor(contrastBorder);
if (!isEmpty && borderColor) {
addClass(this.titleContainer, 'title-border-bottom');
this.titleContainer.style.setProperty('--title-border-bottom-color', borderColor.toString());
} else {
@@ -1560,6 +1559,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this.titleContainer.style.removeProperty('--title-border-bottom-color');
}
const { showTabs } = this.accessor.partOptions;
this.titleContainer.style.backgroundColor = this.getColor(showTabs ? EDITOR_GROUP_HEADER_TABS_BACKGROUND : EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND) || '';
// Editor container

View File

@@ -831,6 +831,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
parent.appendChild(overlay);
CompositeDragAndDropObserver.INSTANCE.registerTarget(this.element, {
onDragOver: e => {
if (e.eventData.dataTransfer) {
e.eventData.dataTransfer.dropEffect = 'none';
}
},
onDragStart: e => {
toggleClass(overlay, 'visible', true);
},
@@ -849,7 +854,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
}
isLayoutCentered(): boolean {
return this.centeredLayoutWidget.isActive();
if (this.centeredLayoutWidget) {
return this.centeredLayoutWidget.isActive();
}
return false;
}
private doCreateGridControl(options?: IEditorPartCreationOptions): void {

View File

@@ -16,6 +16,7 @@ import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
import { prepareQuery, scoreItemFuzzy, compareItemsByFuzzyScore, FuzzyScorerCache } from 'vs/base/common/fuzzyScorer';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Codicon } from 'vs/base/common/codicons';
interface IEditorQuickPickItem extends IQuickPickItemWithResource, IPickerQuickAccessItem {
groupId: GroupIdentifier;
@@ -138,6 +139,8 @@ export abstract class BaseEditorQuickAccessProvider extends PickerQuickAccessPro
return this.doGetEditors().map(({ editor, groupId }): IEditorQuickPickItem => {
const resource = toResource(editor, { supportSideBySide: SideBySideEditor.MASTER });
const isDirty = editor.isDirty() && !editor.isSaving();
const description = editor.getDescription();
const nameAndDescription = description ? `${editor.getName()} ${description}` : editor.getName();
return {
groupId,
@@ -146,11 +149,11 @@ export abstract class BaseEditorQuickAccessProvider extends PickerQuickAccessPro
ariaLabel: (() => {
if (mapGroupIdToGroupAriaLabel.size > 1) {
return isDirty ?
localize('entryAriaLabelWithGroupDirty', "{0}, dirty, {1}", editor.getName(), mapGroupIdToGroupAriaLabel.get(groupId)) :
localize('entryAriaLabelWithGroup', "{0}, {1}", editor.getName(), mapGroupIdToGroupAriaLabel.get(groupId));
localize('entryAriaLabelWithGroupDirty', "{0}, dirty, {1}", nameAndDescription, mapGroupIdToGroupAriaLabel.get(groupId)) :
localize('entryAriaLabelWithGroup', "{0}, {1}", nameAndDescription, mapGroupIdToGroupAriaLabel.get(groupId));
}
return isDirty ? localize('entryAriaLabelDirty', "{0}, dirty", editor.getName()) : editor.getName();
return isDirty ? localize('entryAriaLabelDirty', "{0}, dirty", nameAndDescription) : nameAndDescription;
})(),
description: editor.getDescription(),
iconClasses: getIconClasses(this.modelService, this.modeService, resource),
@@ -158,7 +161,7 @@ export abstract class BaseEditorQuickAccessProvider extends PickerQuickAccessPro
buttons: (() => {
return [
{
iconClass: isDirty ? 'dirty-editor codicon-circle-filled' : 'codicon-close',
iconClass: isDirty ? ('dirty-editor ' + Codicon.closeDirty.classNames) : Codicon.close.classNames,
tooltip: localize('closeEditor', "Close Editor"),
alwaysVisible: isDirty
}

View File

@@ -404,8 +404,10 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
private updateTabFocusModeElement(visible: boolean): void {
if (visible) {
if (!this.tabFocusModeElement.value) {
const text = nls.localize('tabFocusModeEnabled', "Tab Moves Focus");
this.tabFocusModeElement.value = this.statusbarService.addEntry({
text: nls.localize('tabFocusModeEnabled', "Tab Moves Focus"),
text,
ariaLabel: text,
tooltip: nls.localize('disableTabMode', "Disable Accessibility Mode"),
command: 'editor.action.toggleTabFocusMode',
backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND),
@@ -420,8 +422,10 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
private updateColumnSelectionModeElement(visible: boolean): void {
if (visible) {
if (!this.columnSelectionModeElement.value) {
const text = nls.localize('columnSelectionModeEnabled', "Column Selection");
this.columnSelectionModeElement.value = this.statusbarService.addEntry({
text: nls.localize('columnSelectionModeEnabled', "Column Selection"),
text,
ariaLabel: text,
tooltip: nls.localize('disableColumnSelectionMode', "Disable Column Selection Mode"),
command: 'editor.action.toggleColumnSelection',
backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND),
@@ -436,8 +440,10 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
private updateScreenReaderModeElement(visible: boolean): void {
if (visible) {
if (!this.screenRedearModeElement.value) {
const text = nls.localize('screenReaderDetected', "Screen Reader Optimized");
this.screenRedearModeElement.value = this.statusbarService.addEntry({
text: nls.localize('screenReaderDetected', "Screen Reader Optimized"),
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),
@@ -457,6 +463,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('gotoLine', "Go to Line/Column"),
command: 'workbench.action.gotoLine'
};
@@ -472,6 +479,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('selectIndentation', "Select Indentation"),
command: 'changeEditorIndentation'
};
@@ -491,6 +499,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('selectEncoding', "Select Encoding"),
command: 'workbench.action.editor.changeEncoding'
};
@@ -506,6 +515,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('selectEOL', "Select End of Line Sequence"),
command: 'workbench.action.editor.changeEOL'
};
@@ -521,6 +531,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('selectLanguageMode', "Select Language Mode"),
command: 'workbench.action.editor.changeLanguageMode'
};
@@ -536,6 +547,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
tooltip: nls.localize('fileInfo', "File Information")
};
@@ -578,7 +590,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
this.updateColumnSelectionModeElement(!!this.state.columnSelectionMode);
this.updateScreenReaderModeElement(!!this.state.screenReaderMode);
this.updateIndentationElement(this.state.indentation);
this.updateSelectionElement(this.state.selectionStatus && !this.state.screenReaderMode ? this.state.selectionStatus : undefined);
this.updateSelectionElement(this.state.selectionStatus);
this.updateEncodingElement(this.state.encoding);
this.updateEOLElement(this.state.EOL ? this.state.EOL === '\r\n' ? nlsEOLCRLF : nlsEOLLF : undefined);
this.updateModeElement(this.state.mode);
@@ -918,9 +930,9 @@ class ShowCurrentMarkerInStatusbarContribution extends Disposable {
const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0];
const text = `${this.getType(this.currentMarker)} ${line}`;
if (!this.statusBarEntryAccessor.value) {
this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text: '' }, 'statusbar.currentProblem', nls.localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT);
this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text: '', ariaLabel: '' }, 'statusbar.currentProblem', nls.localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT);
}
this.statusBarEntryAccessor.value.update({ text });
this.statusBarEntryAccessor.value.update({ text, ariaLabel: text });
} else {
this.statusBarEntryAccessor.clear();
}
@@ -1334,7 +1346,7 @@ export class ChangeEncodingAction extends Action {
}
}
let action: IQuickPickItem;
let action: IQuickPickItem | undefined;
if (encodingSupport instanceof UntitledTextEditorInput) {
action = saveWithEncodingPick;
} else if (activeEditorPane.input.isReadonly()) {

View File

@@ -17,12 +17,9 @@
left: 0;
width: 100%;
height: 100%;
pointer-events: none; /* very important to not take events away from the parent */
opacity: 0; /* hidden initially */
transition: opacity 150ms ease-out;
/* color: red; */
}
#monaco-workbench-editor-drop-overlay > .editor-group-overlay-indicator.overlay-move-transition {

View File

@@ -9,6 +9,22 @@
display: flex;
}
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container.tabs-border-bottom {
position: relative;
}
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container.tabs-border-bottom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
z-index: 5;
pointer-events: none;
background-color: var(--tabs-border-bottom-color);
width: 100%;
height: 1px;
}
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element {
flex: 1;
}
@@ -159,15 +175,15 @@
}
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label,
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label > .monaco-icon-label-container > .monaco-icon-name-container {
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label > .monaco-icon-label-container {
overflow: visible; /* fixes https://github.com/Microsoft/vscode/issues/20182 */
}
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-container > .monaco-icon-name-container {
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-container {
text-overflow: clip;
}
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-container > .monaco-icon-name-container {
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-container {
text-overflow: ellipsis;
}

View File

@@ -25,7 +25,7 @@ import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElemen
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { getOrSet } from 'vs/base/common/map';
import { IThemeService, registerThemingParticipant, IColorTheme, ICssStyleCollector, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
import { TAB_INACTIVE_BACKGROUND, TAB_ACTIVE_BACKGROUND, TAB_ACTIVE_FOREGROUND, TAB_INACTIVE_FOREGROUND, TAB_BORDER, EDITOR_DRAG_AND_DROP_BACKGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_BACKGROUND, TAB_UNFOCUSED_ACTIVE_BORDER, TAB_ACTIVE_BORDER, TAB_HOVER_BACKGROUND, TAB_HOVER_BORDER, TAB_UNFOCUSED_HOVER_BACKGROUND, TAB_UNFOCUSED_HOVER_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, WORKBENCH_BACKGROUND, TAB_ACTIVE_BORDER_TOP, TAB_UNFOCUSED_ACTIVE_BORDER_TOP, TAB_ACTIVE_MODIFIED_BORDER, TAB_INACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER } from 'vs/workbench/common/theme';
import { TAB_INACTIVE_BACKGROUND, TAB_ACTIVE_BACKGROUND, TAB_ACTIVE_FOREGROUND, TAB_INACTIVE_FOREGROUND, TAB_BORDER, EDITOR_DRAG_AND_DROP_BACKGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_BACKGROUND, TAB_UNFOCUSED_ACTIVE_BORDER, TAB_ACTIVE_BORDER, TAB_HOVER_BACKGROUND, TAB_HOVER_BORDER, TAB_UNFOCUSED_HOVER_BACKGROUND, TAB_UNFOCUSED_HOVER_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, WORKBENCH_BACKGROUND, TAB_ACTIVE_BORDER_TOP, TAB_UNFOCUSED_ACTIVE_BORDER_TOP, TAB_ACTIVE_MODIFIED_BORDER, TAB_INACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_INACTIVE_BACKGROUND, TAB_HOVER_FOREGROUND, TAB_UNFOCUSED_HOVER_FOREGROUND, EDITOR_GROUP_HEADER_TABS_BORDER } from 'vs/workbench/common/theme';
import { activeContrastBorder, contrastBorder, editorBackground, breadcrumbsBackground } from 'vs/platform/theme/common/colorRegistry';
import { ResourcesDropHandler, fillResourceDataTransfers, DraggedEditorIdentifier, DraggedEditorGroupIdentifier, DragAndDropObserver } from 'vs/workbench/browser/dnd';
import { Color } from 'vs/base/common/color';
@@ -43,7 +43,7 @@ import { withNullAsUndefined, assertAllDefined, assertIsDefined } from 'vs/base/
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { basenameOrAuthority } from 'vs/base/common/resources';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IPath, win32, posix } from 'vs/base/common/path';
// {{SQL CARBON EDIT}} -- Display the editor's tab color
@@ -55,6 +55,7 @@ interface IEditorInputLabel {
name?: string;
description?: string;
title?: string;
ariaLabel?: string;
}
type AugmentedLabel = IEditorInputLabel & { editor: IEditorInput };
@@ -67,6 +68,7 @@ export class TabsTitleControl extends TitleControl {
};
private titleContainer: HTMLElement | undefined;
private tabsAndActionsContainer: HTMLElement | undefined;
private tabsContainer: HTMLElement | undefined;
private editorToolbarContainer: HTMLElement | undefined;
private tabsScrollbar: ScrollableElement | undefined;
@@ -100,7 +102,7 @@ export class TabsTitleControl extends TitleControl {
@IConfigurationService configurationService: IConfigurationService,
@IFileService fileService: IFileService,
@IEditorService private readonly editorService: EditorServiceImpl,
@IRemotePathService private readonly remotePathService: IRemotePathService
@IPathService private readonly pathService: IPathService
) {
super(parent, accessor, group, contextMenuService, instantiationService, contextKeyService, keybindingService, telemetryService, notificationService, menuService, quickInputService, themeService, extensionService, configurationService, fileService);
@@ -110,7 +112,7 @@ export class TabsTitleControl extends TitleControl {
// Resolve the correct path library for the OS we are on
// If we are connected to remote, this accounts for the
// remote OS.
(async () => this.path = await this.remotePathService.path)();
(async () => this.path = await this.pathService.path)();
}
protected registerListeners(): void {
@@ -127,9 +129,9 @@ export class TabsTitleControl extends TitleControl {
this.titleContainer = parent;
// Tabs and Actions Container (are on a single row with flex side-by-side)
const tabsAndActionsContainer = document.createElement('div');
addClass(tabsAndActionsContainer, 'tabs-and-actions-container');
this.titleContainer.appendChild(tabsAndActionsContainer);
this.tabsAndActionsContainer = document.createElement('div');
addClass(this.tabsAndActionsContainer, 'tabs-and-actions-container');
this.titleContainer.appendChild(this.tabsAndActionsContainer);
// Tabs Container
this.tabsContainer = document.createElement('div');
@@ -140,7 +142,7 @@ export class TabsTitleControl extends TitleControl {
// Tabs Scrollbar
this.tabsScrollbar = this._register(this.createTabsScrollbar(this.tabsContainer));
tabsAndActionsContainer.appendChild(this.tabsScrollbar.getDomNode());
this.tabsAndActionsContainer.appendChild(this.tabsScrollbar.getDomNode());
// Tabs Container listeners
this.registerTabsContainerListeners(this.tabsContainer, this.tabsScrollbar);
@@ -148,7 +150,7 @@ export class TabsTitleControl extends TitleControl {
// Editor Toolbar Container
this.editorToolbarContainer = document.createElement('div');
addClass(this.editorToolbarContainer, 'editor-actions');
tabsAndActionsContainer.appendChild(this.editorToolbarContainer);
this.tabsAndActionsContainer.appendChild(this.editorToolbarContainer);
// Editor Actions Toolbar
this.createEditorActionsToolBar(this.editorToolbarContainer);
@@ -212,7 +214,7 @@ export class TabsTitleControl extends TitleControl {
this._register(addDisposableListener(tabsContainer, EventType.SCROLL, () => {
if (hasClass(tabsContainer, 'scroll')) {
tabsScrollbar.setScrollPosition({
scrollLeft: tabsContainer.scrollLeft // during DND the container gets scrolled so we need to update the custom scrollbar
scrollLeft: tabsContainer.scrollLeft // during DND the container gets scrolled so we need to update the custom scrollbar
});
}
}));
@@ -323,6 +325,42 @@ export class TabsTitleControl extends TitleControl {
}
}
}));
// Mouse-wheel support to switch to tabs optionally
this._register(addDisposableListener(tabsContainer, EventType.MOUSE_WHEEL, (e: MouseWheelEvent) => {
const activeEditor = this.group.activeEditor;
if (!activeEditor || this.group.count < 2) {
return; // need at least 2 open editors
}
// 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 (e.shiftKey) {
return; // 'on': only enable this when Shift-key is not 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));
if (!nextEditor) {
return;
}
// Open it
this.group.openEditor(nextEditor);
// Disable normal scrolling, opening the editor will already reveal it properly
EventHelper.stop(e, true);
}));
}
protected updateEditorActionsToolbar(): void {
@@ -515,7 +553,7 @@ export class TabsTitleControl extends TitleControl {
const tabContainer = document.createElement('div');
tabContainer.draggable = true;
tabContainer.tabIndex = 0;
tabContainer.setAttribute('role', 'presentation'); // cannot use role "tab" here due to https://github.com/Microsoft/vscode/issues/8659
tabContainer.setAttribute('role', 'tab');
addClass(tabContainer, 'tab');
// Gesture Support
@@ -854,7 +892,8 @@ export class TabsTitleControl extends TitleControl {
editor,
name: editor.getName(),
description: editor.getDescription(verbosity),
title: withNullAsUndefined(editor.getTitle(Verbosity.LONG))
title: withNullAsUndefined(editor.getTitle(Verbosity.LONG)),
ariaLabel: editor.isReadonly() ? localize('readonlyEditor', "{0} readonly", editor.getTitle(Verbosity.SHORT)) : editor.getTitle(Verbosity.SHORT)
}));
// Shorten labels as needed
@@ -949,6 +988,18 @@ export class TabsTitleControl extends TitleControl {
private redraw(): void {
// Border below tabs if any
const tabsContainerBorderColor = this.getColor(EDITOR_GROUP_HEADER_TABS_BORDER);
if (this.tabsAndActionsContainer) {
if (tabsContainerBorderColor) {
addClass(this.tabsAndActionsContainer, 'tabs-border-bottom');
this.tabsAndActionsContainer.style.setProperty('--tabs-border-bottom-color', tabsContainerBorderColor.toString());
} else {
removeClass(this.tabsAndActionsContainer, 'tabs-border-bottom');
this.tabsAndActionsContainer.style.removeProperty('--tabs-border-bottom-color');
}
}
// For each tab
this.forEachTab((editor, index, tabContainer, tabLabelWidget, tabLabel) => {
this.redrawTab(editor, index, tabContainer, tabLabelWidget, tabLabel);
@@ -999,8 +1050,12 @@ export class TabsTitleControl extends TitleControl {
const description = tabLabel.description || '';
const title = tabLabel.title || '';
// Container
tabContainer.setAttribute('aria-label', `${name}, tab`);
if (tabLabel.ariaLabel) {
tabContainer.setAttribute('aria-label', tabLabel.ariaLabel);
// Set aria-description to empty string so that screen readers would not read the title as well
// More details https://github.com/microsoft/vscode/issues/95378
tabContainer.setAttribute('aria-description', '');
}
tabContainer.title = title;
// Label
@@ -1057,7 +1112,7 @@ export class TabsTitleControl extends TitleControl {
}
// Label
tabLabelWidget.element.style.color = this.getColor(isGroupActive ? TAB_ACTIVE_FOREGROUND : TAB_UNFOCUSED_ACTIVE_FOREGROUND) || '';
tabContainer.style.color = this.getColor(isGroupActive ? TAB_ACTIVE_FOREGROUND : TAB_UNFOCUSED_ACTIVE_FOREGROUND) || '';
}
// Tab is inactive
@@ -1066,11 +1121,11 @@ export class TabsTitleControl extends TitleControl {
// Container
removeClass(tabContainer, 'active');
tabContainer.setAttribute('aria-selected', 'false');
tabContainer.style.backgroundColor = this.getColor(TAB_INACTIVE_BACKGROUND) || '';
tabContainer.style.backgroundColor = this.getColor(isGroupActive ? TAB_INACTIVE_BACKGROUND : TAB_UNFOCUSED_INACTIVE_BACKGROUND) || '';
tabContainer.style.boxShadow = '';
// Label
tabLabelWidget.element.style.color = this.getColor(isGroupActive ? TAB_INACTIVE_FOREGROUND : TAB_UNFOCUSED_INACTIVE_FOREGROUND) || '';
tabContainer.style.color = this.getColor(isGroupActive ? TAB_INACTIVE_FOREGROUND : TAB_UNFOCUSED_INACTIVE_FOREGROUND) || '';
}
// {{SQL CARBON EDIT}} - Override the editor's tab color if query tab coloring is set
@@ -1323,15 +1378,17 @@ export class TabsTitleControl extends TitleControl {
}
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
// Add border between tabs and breadcrumbs in high contrast mode.
if (theme.type === HIGH_CONTRAST) {
const borderColor = (theme.getColor(TAB_BORDER) || theme.getColor(contrastBorder));
collector.addRule(`
.monaco-workbench div.tabs-and-actions-container {
border-bottom: 1px solid ${borderColor};
}
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container {
border-bottom: 1px solid ${borderColor};
}
`);
}
// Styling with Outline color (e.g. high contrast theme)
const activeContrastBorderColor = theme.getColor(activeContrastBorder);
if (activeContrastBorderColor) {
@@ -1385,6 +1442,25 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
`);
}
// Hover Foreground
const tabHoverForeground = theme.getColor(TAB_HOVER_FOREGROUND);
if (tabHoverForeground) {
collector.addRule(`
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
color: ${tabHoverForeground} !important;
}
`);
}
const tabUnfocusedHoverForeground = theme.getColor(TAB_UNFOCUSED_HOVER_FOREGROUND);
if (tabUnfocusedHoverForeground) {
collector.addRule(`
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
color: ${tabUnfocusedHoverForeground} !important;
}
`);
}
// Hover Border
const tabHoverBorder = theme.getColor(TAB_HOVER_BORDER);
if (tabHoverBorder) {
@@ -1423,13 +1499,13 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
// Adjust gradient for focused and unfocused hover background
const makeTabHoverBackgroundRule = (color: Color, colorDrag: Color, hasFocus = false) => `
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
background: linear-gradient(to left, ${color}, transparent) !important;
}
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
background: linear-gradient(to left, ${color}, transparent) !important;
}
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
background: linear-gradient(to left, ${colorDrag}, transparent) !important;
}
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
background: linear-gradient(to left, ${colorDrag}, transparent) !important;
}
`;
// Adjust gradient for (focused) hover background
@@ -1450,30 +1526,29 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
if (editorDragAndDropBackground && adjustedTabDragBackground) {
const adjustedColorDrag = editorDragAndDropBackground.flatten(adjustedTabDragBackground);
collector.addRule(`
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.active):not(.dragged) > .tab-label::after,
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
}
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.active):not(.dragged) > .tab-label::after,
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
}
`);
}
// Adjust gradient for active tab background (focused and unfocused editor groups)
const makeTabActiveBackgroundRule = (color: Color, colorDrag: Color, hasFocus = false) => `
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${hasFocus ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
const makeTabBackgroundRule = (color: Color, colorDrag: Color, focused: boolean, active: boolean) => `
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink${active ? '.active' : ''}:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${color}, transparent);
}
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container${hasFocus ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink${active ? '.active' : ''}:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${colorDrag}, transparent);
}
`;
// Adjust gradient for unfocused active tab background
// Adjust gradient for focused active tab background
const tabActiveBackground = theme.getColor(TAB_ACTIVE_BACKGROUND);
if (tabActiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
const adjustedColor = tabActiveBackground.flatten(adjustedTabBackground);
const adjustedColorDrag = tabActiveBackground.flatten(adjustedTabDragBackground);
collector.addRule(makeTabActiveBackgroundRule(adjustedColor, adjustedColorDrag, true));
collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, true, true));
}
// Adjust gradient for unfocused active tab background
@@ -1481,23 +1556,23 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
if (tabUnfocusedActiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
const adjustedColor = tabUnfocusedActiveBackground.flatten(adjustedTabBackground);
const adjustedColorDrag = tabUnfocusedActiveBackground.flatten(adjustedTabDragBackground);
collector.addRule(makeTabActiveBackgroundRule(adjustedColor, adjustedColorDrag));
collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, false, true));
}
// Adjust gradient for inactive tab background
// Adjust gradient for focused inactive tab background
const tabInactiveBackground = theme.getColor(TAB_INACTIVE_BACKGROUND);
if (tabInactiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
const adjustedColor = tabInactiveBackground.flatten(adjustedTabBackground);
const adjustedColorDrag = tabInactiveBackground.flatten(adjustedTabDragBackground);
collector.addRule(`
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${adjustedColor}, transparent);
}
collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, true, false));
}
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
background: linear-gradient(to left, ${adjustedColorDrag}, transparent);
}
`);
// Adjust gradient for unfocused inactive tab background
const tabUnfocusedInactiveBackground = theme.getColor(TAB_UNFOCUSED_INACTIVE_BACKGROUND);
if (tabUnfocusedInactiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
const adjustedColor = tabUnfocusedInactiveBackground.flatten(adjustedTabBackground);
const adjustedColorDrag = tabUnfocusedInactiveBackground.flatten(adjustedTabDragBackground);
collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, false, false));
}
}
});

View File

@@ -223,9 +223,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
const inputName = this.input?.getName();
if (this.input?.isReadonly()) {
ariaLabel = inputName ? nls.localize('readonlyEditorWithInputAriaLabel', "{0} readonly compare editor", inputName) : nls.localize('readonlyEditorAriaLabel', "Readonly compare editor");
ariaLabel = inputName ? nls.localize('readonlyEditorWithInputAriaLabel', "{0} readonly compare", inputName) : nls.localize('readonlyEditorAriaLabel', "Readonly compare");
} else {
ariaLabel = inputName ? nls.localize('editableEditorWithInputAriaLabel', "{0} compare editor", inputName) : nls.localize('editableEditorAriaLabel', "Compare editor");
ariaLabel = inputName ? nls.localize('editableEditorWithInputAriaLabel', "{0} compare", inputName) : nls.localize('editableEditorAriaLabel', "Compare");
}
return ariaLabel;

View File

@@ -109,16 +109,8 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
}
protected getAriaLabel(): string {
let ariaLabel: string;
const inputName = this.input instanceof UntitledTextEditorInput ? basenameOrAuthority(this.input.resource) : this.input?.getName();
if (this.input?.isReadonly()) {
ariaLabel = inputName ? nls.localize('readonlyEditorWithInputAriaLabel', "{0} readonly editor", inputName) : nls.localize('readonlyEditorAriaLabel', "Readonly editor");
} else {
ariaLabel = inputName ? nls.localize('writeableEditorWithInputAriaLabel', "{0} editor", inputName) : nls.localize('writeableEditorAriaLabel', "Editor");
}
return ariaLabel;
const inputName = this.input instanceof UntitledTextEditorInput ? basenameOrAuthority(this.input.resource) : this.input?.getName() || nls.localize('writeableEditorAriaLabel', "Editor");
return this.input?.isReadonly() ? nls.localize('readonlyEditor', "{0} readonly", inputName) : inputName;
}
/**

View File

@@ -12,6 +12,14 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { CLEAR_NOTIFICATION, EXPAND_NOTIFICATION, COLLAPSE_NOTIFICATION, CLEAR_ALL_NOTIFICATIONS, HIDE_NOTIFICATIONS_CENTER } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { Codicon, registerIcon } from 'vs/base/common/codicons';
const clearIcon = registerIcon('notifications-clear', Codicon.close);
const clearAllIcon = registerIcon('notifications-clear-all', Codicon.clearAll);
const hideIcon = registerIcon('notifications-hide', Codicon.chevronDown);
const expandIcon = registerIcon('notifications-expand', Codicon.chevronUp);
const collapseIcon = registerIcon('notifications-collapse', Codicon.chevronDown);
const configureIcon = registerIcon('notifications-configure', Codicon.gear);
export class ClearNotificationAction extends Action {
@@ -23,7 +31,7 @@ export class ClearNotificationAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-close');
super(id, label, clearIcon.classNames);
}
async run(notification: INotificationViewItem): Promise<void> {
@@ -41,7 +49,7 @@ export class ClearAllNotificationsAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-clear-all');
super(id, label, clearAllIcon.classNames);
}
async run(): Promise<void> {
@@ -59,7 +67,7 @@ export class HideNotificationsCenterAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-chevron-down');
super(id, label, hideIcon.classNames);
}
async run(): Promise<void> {
@@ -77,7 +85,7 @@ export class ExpandNotificationAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-chevron-up');
super(id, label, expandIcon.classNames);
}
async run(notification: INotificationViewItem): Promise<void> {
@@ -95,7 +103,7 @@ export class CollapseNotificationAction extends Action {
label: string,
@ICommandService private readonly commandService: ICommandService
) {
super(id, label, 'codicon-chevron-down');
super(id, label, collapseIcon.classNames);
}
async run(notification: INotificationViewItem): Promise<void> {
@@ -113,7 +121,7 @@ export class ConfigureNotificationAction extends Action {
label: string,
public readonly configurationActions: ReadonlyArray<IAction>
) {
super(id, label, 'codicon-gear');
super(id, label, configureIcon.classNames);
}
}

View File

@@ -44,6 +44,9 @@ export class NotificationsAlerts extends Disposable {
}
private triggerAriaAlert(notifiation: INotificationViewItem): void {
if (notifiation.silent) {
return;
}
// Trigger the alert again whenever the message changes
const listener = notifiation.onDidChangeContent(e => {

View File

@@ -157,10 +157,7 @@ export class NotificationsCenter extends Themable implements INotificationsCente
notificationsToolBar.push(hideAllAction, { icon: true, label: false, keybinding: this.getKeybindingLabel(hideAllAction) });
// Notifications List
this.notificationsList = this.instantiationService.createInstance(NotificationsList, this.notificationsCenterContainer, {
ariaLabel: localize('notificationsList', "Notifications List")
});
this.notificationsList = this.instantiationService.createInstance(NotificationsList, this.notificationsCenterContainer, {});
this.container.appendChild(this.notificationsCenterContainer);
}

View File

@@ -18,6 +18,7 @@ import { NotificationActionRunner, CopyNotificationMessageAction } from 'vs/work
import { NotificationFocusedContext } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { assertIsDefined, assertAllDefined } from 'vs/base/common/types';
import { Codicon } from 'vs/base/common/codicons';
export class NotificationsList extends Themable {
private listContainer: HTMLElement | undefined;
@@ -96,6 +97,12 @@ export class NotificationsList extends Themable {
}
return localize('notificationWithSourceAriaLabel', "{0}, source: {1}, notification", element.message.raw, element.source);
},
getWidgetAriaLabel(): string {
return localize('notificationsList', "Notifications List");
},
getRole(): string {
return 'dialog'; // https://github.com/microsoft/vscode/issues/82728
}
}
}
@@ -290,9 +297,10 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
// Notification Error Icon
const notificationErrorIconForegroundColor = theme.getColor(NOTIFICATIONS_ERROR_ICON_FOREGROUND);
if (notificationErrorIconForegroundColor) {
const errorCodiconSelector = Codicon.error.cssSelector;
collector.addRule(`
.monaco-workbench .notifications-center .codicon-error,
.monaco-workbench .notifications-toasts .codicon-error {
.monaco-workbench .notifications-center ${errorCodiconSelector},
.monaco-workbench .notifications-toasts ${errorCodiconSelector} {
color: ${notificationErrorIconForegroundColor};
}`);
}
@@ -300,9 +308,10 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
// Notification Warning Icon
const notificationWarningIconForegroundColor = theme.getColor(NOTIFICATIONS_WARNING_ICON_FOREGROUND);
if (notificationWarningIconForegroundColor) {
const warningCodiconSelector = Codicon.warning.cssSelector;
collector.addRule(`
.monaco-workbench .notifications-center .codicon-warning,
.monaco-workbench .notifications-toasts .codicon-warning {
.monaco-workbench .notifications-center ${warningCodiconSelector},
.monaco-workbench .notifications-toasts ${warningCodiconSelector} {
color: ${notificationWarningIconForegroundColor};
}`);
}
@@ -310,9 +319,10 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
// Notification Info Icon
const notificationInfoIconForegroundColor = theme.getColor(NOTIFICATIONS_INFO_ICON_FOREGROUND);
if (notificationInfoIconForegroundColor) {
const infoCodiconSelector = Codicon.info.cssSelector;
collector.addRule(`
.monaco-workbench .notifications-center .codicon-info,
.monaco-workbench .notifications-toasts .codicon-info {
.monaco-workbench .notifications-center ${infoCodiconSelector},
.monaco-workbench .notifications-toasts ${infoCodiconSelector} {
color: ${notificationInfoIconForegroundColor};
}`);
}

View File

@@ -72,6 +72,7 @@ export class NotificationsStatus extends Disposable {
// Show the bell with a dot if there are unread or in-progress notifications
const statusProperties: IStatusbarEntry = {
text: `${notificationsInProgress > 0 || this.newNotificationsCount > 0 ? '$(bell-dot)' : '$(bell)'}`,
ariaLabel: localize('status.notifications', "Notifications"),
command: this.isNotificationsCenterVisible ? HIDE_NOTIFICATIONS_CENTER : SHOW_NOTIFICATIONS_CENTER,
tooltip: this.getTooltip(notificationsInProgress),
showBeak: this.isNotificationsCenterVisible
@@ -179,7 +180,7 @@ export class NotificationsStatus extends Disposable {
let statusMessageEntry: IStatusbarEntryAccessor;
let showHandle: any = setTimeout(() => {
statusMessageEntry = this.statusbarService.addEntry(
{ text: message },
{ text: message, ariaLabel: message },
'status.message',
localize('status.message', "Status Message"),
StatusbarAlignment.LEFT,

View File

@@ -17,7 +17,6 @@ import { widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { NotificationsToastsVisibleContext, INotificationsToastController } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { localize } from 'vs/nls';
import { Severity, NotificationsFilter } from 'vs/platform/notification/common/notification';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
@@ -170,8 +169,6 @@ export class NotificationsToasts extends Themable implements INotificationsToast
// Create toast with item and show
const notificationList = this.instantiationService.createInstance(NotificationsList, notificationToast, {
ariaRole: 'dialog', // https://github.com/microsoft/vscode/issues/82728
ariaLabel: localize('notificationsToast', "Notification Toast"),
verticalScrollMode: ScrollbarVisibility.Hidden
});
itemDisposables.add(notificationList);

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import { clearNode, addClass, removeClass, toggleClass, addDisposableListener, EventType, EventHelper, $ } from 'vs/base/browser/dom';
import { clearNode, addClass, toggleClass, addDisposableListener, EventType, EventHelper, $, addClasses, removeClasses } from 'vs/base/browser/dom';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
@@ -23,6 +23,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { Severity } from 'vs/platform/notification/common/notification';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { Codicon } from 'vs/base/common/codicons';
export class NotificationsListDelegate implements IListVirtualDelegate<INotificationViewItem> {
@@ -275,7 +276,7 @@ export class NotificationTemplateRenderer extends Disposable {
private static expandNotificationAction: ExpandNotificationAction;
private static collapseNotificationAction: CollapseNotificationAction;
private static readonly SEVERITIES: Array<'info' | 'warning' | 'error'> = ['info', 'warning', 'error'];
private static readonly SEVERITIES = [Severity.Info, Severity.Warning, Severity.Error];
private readonly inputDisposables = this._register(new DisposableStore());
@@ -352,10 +353,13 @@ export class NotificationTemplateRenderer extends Disposable {
}
private renderSeverity(notification: INotificationViewItem): void {
// first remove, then set as the codicon class names overlap
NotificationTemplateRenderer.SEVERITIES.forEach(severity => {
const domAction = notification.severity === this.toSeverity(severity) ? addClass : removeClass;
domAction(this.template.icon, `codicon-${severity}`);
if (notification.severity !== severity) {
removeClasses(this.template.icon, this.toSeverityIcon(severity).classNames);
}
});
addClasses(this.template.icon, this.toSeverityIcon(notification.severity).classNames);
}
private renderMessage(notification: INotificationViewItem): boolean {
@@ -488,15 +492,14 @@ export class NotificationTemplateRenderer extends Disposable {
}
}
private toSeverity(severity: 'info' | 'warning' | 'error'): Severity {
private toSeverityIcon(severity: Severity): Codicon {
switch (severity) {
case 'info':
return Severity.Info;
case 'warning':
return Severity.Warning;
case 'error':
return Severity.Error;
case Severity.Warning:
return Codicon.warning;
case Severity.Error:
return Codicon.error;
}
return Codicon.info;
}
private getKeybindingLabel(action: IAction): string | null {

View File

@@ -170,14 +170,14 @@
/* Rotate icons when panel is on right */
.monaco-workbench .part.panel.right .title-actions .codicon-split-horizontal,
.monaco-workbench .part.panel.right .title-actions .codicon-chevron-up,
.monaco-workbench .part.panel.right .title-actions .codicon-chevron-down {
.monaco-workbench .part.panel.right .title-actions .codicon-panel-maximize,
.monaco-workbench .part.panel.right .title-actions .codicon-panel-restore {
transform: rotate(-90deg);
}
/* Rotate icons when panel is on left */
.monaco-workbench .part.panel.left .title-actions .codicon-split-horizontal,
.monaco-workbench .part.panel.left .title-actions .codicon-chevron-up,
.monaco-workbench .part.panel.left .title-actions .codicon-chevron-down {
.monaco-workbench .part.panel.left .title-actions .codicon-panel-maximize,
.monaco-workbench .part.panel.left .title-actions .codicon-panel-restore {
transform: rotate(90deg);
}

View File

@@ -18,6 +18,11 @@ import { IActivity } from 'vs/workbench/common/activity';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ActivePanelContext, PanelPositionContext } from 'vs/workbench/common/panel';
import { ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
import { Codicon, registerIcon } from 'vs/base/common/codicons';
const maximizeIcon = registerIcon('panel-maximize', Codicon.chevronUp);
const restoreIcon = registerIcon('panel-restore', Codicon.chevronDown);
const closeIcon = registerIcon('panel-close', Codicon.close);
export class ClosePanelAction extends Action {
@@ -29,7 +34,7 @@ export class ClosePanelAction extends Action {
name: string,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
) {
super(id, name, 'codicon-close');
super(id, name, closeIcon.classNames);
}
async run(): Promise<void> {
@@ -101,11 +106,11 @@ export class ToggleMaximizedPanelAction extends Action {
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IEditorGroupsService editorGroupsService: IEditorGroupsService
) {
super(id, label, layoutService.isPanelMaximized() ? 'codicon-chevron-down' : 'codicon-chevron-up');
super(id, label, layoutService.isPanelMaximized() ? restoreIcon.classNames : maximizeIcon.classNames);
this.toDispose.add(editorGroupsService.onDidLayout(() => {
const maximized = this.layoutService.isPanelMaximized();
this.class = maximized ? 'codicon-chevron-down' : 'codicon-chevron-up';
this.class = maximized ? restoreIcon.classNames : maximizeIcon.classNames;
this.label = maximized ? ToggleMaximizedPanelAction.RESTORE_LABEL : ToggleMaximizedPanelAction.MAXIMIZE_LABEL;
}));
}
@@ -273,13 +278,13 @@ export class NextPanelViewAction extends SwitchPanelViewAction {
}
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchExtensions.WorkbenchActions);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL), 'View: Toggle Maximized Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, undefined), 'View: Toggle Panel Position', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(PreviousPanelViewAction, PreviousPanelViewAction.ID, PreviousPanelViewAction.LABEL), 'View: Previous Panel View', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NextPanelViewAction, NextPanelViewAction.ID, NextPanelViewAction.LABEL), 'View: Next Panel View', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(TogglePanelAction, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(FocusPanelAction), 'View: Focus into Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleMaximizedPanelAction), 'View: Toggle Maximized Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ClosePanelAction), 'View: Close Panel', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleMaximizedPanelAction), 'View: Toggle Panel Position', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(PreviousPanelViewAction), 'View: Previous Panel View', nls.localize('view', "View"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(NextPanelViewAction), 'View: Next Panel View', nls.localize('view', "View"));
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
group: '2_workbench_layout',

View File

@@ -33,15 +33,17 @@ import { IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/con
import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, IViewDescriptorService, IViewDescriptorCollection, ViewContainerLocation } from 'vs/workbench/common/views';
import { ViewContainer, IViewDescriptorService, IViewContainerModel, ViewContainerLocation } from 'vs/workbench/common/views';
import { MenuId } from 'vs/platform/actions/common/actions';
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { Before2D } from 'vs/workbench/browser/dnd';
import { IActivity } from 'vs/workbench/common/activity';
interface ICachedPanel {
id: string;
name?: string;
pinned: boolean;
order?: number;
visible: boolean;
@@ -176,9 +178,9 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
const result: IAction[] = [];
const container = this.getViewContainer(compositeId);
if (container) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(container);
if (viewDescriptors.allViewDescriptors.length === 1) {
const viewMenuActions = this.instantiationService.createInstance(ViewMenuActions, viewDescriptors.allViewDescriptors[0].id, MenuId.ViewTitle, MenuId.ViewTitleContext);
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(container);
if (viewContainerModel.allViewDescriptors.length === 1) {
const viewMenuActions = this.instantiationService.createInstance(ViewMenuActions, viewContainerModel.allViewDescriptors[0].id, MenuId.ViewTitle, MenuId.ViewTitleContext);
result.push(...viewMenuActions.getContextMenuActions());
viewMenuActions.dispose();
}
@@ -207,13 +209,16 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
}
for (const panel of panels) {
this.enableCompositeActions(panel);
const viewContainer = this.getViewContainer(panel.id);
if (viewContainer?.hideIfEmpty) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
this.onDidChangeActiveViews(panel, viewDescriptors);
this.panelDisposables.set(panel.id, viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(panel, viewDescriptors)));
}
const viewContainer = this.getViewContainer(panel.id)!;
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
this.updateActivity(viewContainer, viewContainerModel);
this.onDidChangeActiveViews(viewContainer, viewContainerModel);
const disposables = new DisposableStore();
disposables.add(viewContainerModel.onDidChangeActiveViewDescriptors(() => this.onDidChangeActiveViews(viewContainer, viewContainerModel)));
disposables.add(viewContainerModel.onDidChangeContainerInfo(() => this.updateActivity(viewContainer, viewContainerModel)));
this.panelDisposables.set(panel.id, disposables);
}
}
@@ -227,22 +232,28 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
this.hideComposite(panelId);
}
private enableCompositeActions(panel: PanelDescriptor): void {
const { activityAction, pinnedAction } = this.getCompositeActions(panel.id);
if (activityAction instanceof PlaceHolderPanelActivityAction) {
activityAction.setActivity(panel);
}
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
const activity: IActivity = {
id: viewContainer.id,
name: viewContainerModel.title,
keybindingId: viewContainer.focusCommand?.id
};
const { activityAction, pinnedAction } = this.getCompositeActions(viewContainer.id);
activityAction.setActivity(activity);
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
pinnedAction.setActivity(panel);
pinnedAction.setActivity(activity);
}
this.saveCachedPanels();
}
private onDidChangeActiveViews(panel: PanelDescriptor, viewDescriptors: IViewDescriptorCollection): void {
if (viewDescriptors.activeViewDescriptors.length) {
this.compositeBar.addComposite(panel);
} else {
this.hideComposite(panel.id);
private onDidChangeActiveViews(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
if (viewContainerModel.activeViewDescriptors.length) {
this.compositeBar.addComposite(viewContainer);
} else if (viewContainer.hideIfEmpty) {
this.hideComposite(viewContainer.id);
}
}
@@ -319,8 +330,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
if (panelDescriptor) {
const viewContainer = this.getViewContainer(panelDescriptor.id);
if (viewContainer?.hideIfEmpty) {
const viewDescriptors = this.viewDescriptorService.getViewDescriptors(viewContainer);
if (viewDescriptors.activeViewDescriptors.length === 0 && this.compositeBar.getPinnedComposites().length > 1) {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
if (viewContainerModel.activeViewDescriptors.length === 0 && this.compositeBar.getPinnedComposites().length > 1) {
this.hideComposite(panelDescriptor.id); // Update the composite bar by hiding
}
}
@@ -500,6 +511,12 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
let compositeActions = this.compositeActions.get(compositeId);
if (!compositeActions) {
const panel = this.getPanel(compositeId);
const cachedPanel = this.getCachedPanels().filter(p => p.id === compositeId)[0];
if (panel && cachedPanel?.name) {
panel.name = cachedPanel.name;
}
if (panel) {
compositeActions = {
activityAction: new PanelActivityAction(assertIsDefined(this.getPanel(compositeId)), this),
@@ -580,7 +597,11 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
const compositeItems = this.compositeBar.getCompositeBarItems();
for (const compositeItem of compositeItems) {
state.push({ id: compositeItem.id, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
const viewContainer = this.getViewContainer(compositeItem.id);
if (viewContainer) {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
state.push({ id: compositeItem.id, name: viewContainerModel.title, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
}
}
this.cachedPanelsValue = JSON.stringify(state);
@@ -625,8 +646,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
}
private getViewContainer(panelId: string): ViewContainer | undefined {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
return viewContainerRegistry.get(panelId);
return this.viewDescriptorService.getViewContainerById(panelId) || undefined;
}
toJSON(): object {

View File

@@ -331,7 +331,7 @@ class FocusSideBarAction extends Action {
}
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(FocusSideBarAction, FocusSideBarAction.ID, FocusSideBarAction.LABEL, {
registry.registerWorkbenchAction(SyncActionDescriptor.from(FocusSideBarAction, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_0
}), 'View: Focus into Side Bar', nls.localize('viewCategory', "View"));

View File

@@ -7,7 +7,7 @@ import 'vs/css!./media/statusbarpart';
import * as nls from 'vs/nls';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { dispose, IDisposable, Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { CodiconLabel } from 'vs/base/browser/ui/codiconLabel/codiconLabel';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Part } from 'vs/workbench/browser/part';
@@ -449,6 +449,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
this.leftItemsContainer = document.createElement('div');
addClasses(this.leftItemsContainer, 'left-items', 'items-container');
this.element.appendChild(this.leftItemsContainer);
this.element.tabIndex = -1;
// Right items container
this.rightItemsContainer = document.createElement('div');
@@ -624,6 +625,10 @@ export class StatusbarPart extends Part implements IStatusbarService {
return itemContainer;
}
focus(): void {
this.getContainer();
}
layout(width: number, height: number): void {
super.layout(width, height);
super.layoutContents(width, height);
@@ -689,6 +694,10 @@ class StatusbarEntryItem extends Disposable {
}
}
if (!this.entry || entry.ariaLabel !== this.entry.ariaLabel) {
this.labelContainer.setAttribute('aria-label', entry.ariaLabel);
}
// Update: Tooltip (on the container, because label can be disabled)
if (!this.entry || entry.tooltip !== this.entry.tooltip) {
if (entry.tooltip) {

View File

@@ -6,6 +6,7 @@
.monaco-pane-view .split-view-view:first-of-type > .pane > .pane-header {
border-top: none !important; /* less clutter: do not show any border for first views in a pane */
}
.monaco-pane-view .split-view-view:first-of-type > .pane {
border-left: none !important; /* less clutter: do not show any border for first views in a pane */
}

View File

@@ -27,7 +27,7 @@ import { URI } from 'vs/base/common/uri';
import { dirname, basename } from 'vs/base/common/resources';
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, ThemeIcon, IThemeService } from 'vs/platform/theme/common/themeService';
import { FileKind } from 'vs/platform/files/common/files';
import { WorkbenchAsyncDataTree, ResourceNavigator } from 'vs/platform/list/browser/listService';
import { WorkbenchAsyncDataTree, TreeResourceNavigator } from 'vs/platform/list/browser/listService';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { localize } from 'vs/nls';
import { timeout } from 'vs/base/common/async';
@@ -89,6 +89,7 @@ export class TreeViewPane extends ViewPane {
}
layoutBody(height: number, width: number): void {
super.layoutBody(height, width);
this.treeView.layout(height, width);
}
@@ -198,11 +199,11 @@ export class TreeView extends Disposable implements ITreeView {
}
get viewContainer(): ViewContainer {
return this.viewDescriptorService.getViewContainer(this.id)!;
return this.viewDescriptorService.getViewContainerByViewId(this.id)!;
}
get viewLocation(): ViewContainerLocation {
return this.viewDescriptorService.getViewLocation(this.id)!;
return this.viewDescriptorService.getViewLocationById(this.id)!;
}
private _dataProvider: ITreeViewDataProvider | undefined;
@@ -417,6 +418,7 @@ export class TreeView extends Disposable implements ITreeView {
const dataSource = this.instantiationService.createInstance(TreeDataSource, this, <T>(task: Promise<T>) => this.progressService.withProgress({ location: this.id }, () => task));
const aligner = new Aligner(this.themeService);
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, treeMenus, this.treeLabels, actionViewItemProvider, aligner);
const widgetAriaLabel = this._title;
this.tree = this._register(this.instantiationService.createInstance(Tree, this.id, this.treeContainer, new TreeViewDelegate(), [renderer],
dataSource, {
@@ -424,9 +426,11 @@ export class TreeView extends Disposable implements ITreeView {
accessibilityProvider: {
getAriaLabel(element: ITreeItem): string {
return element.tooltip ? element.tooltip : element.label ? element.label.label : '';
},
getWidgetAriaLabel(): string {
return widgetAriaLabel;
}
},
ariaLabel: this._title,
keyboardNavigationLabelProvider: {
getKeyboardNavigationLabel: (item: ITreeItem) => {
return item.label ? item.label.label : (item.resourceUri ? basename(URI.revive(item.resourceUri)) : undefined);
@@ -462,7 +466,7 @@ export class TreeView extends Disposable implements ITreeView {
}));
this.tree.setInput(this.root).then(() => this.updateContentAreas());
const treeNavigator = ResourceNavigator.createTreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false });
const treeNavigator = new TreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false });
this._register(treeNavigator);
this._register(treeNavigator.onDidOpenResource(e => {
if (!e.browserEvent) {

View File

@@ -24,11 +24,10 @@ import { PaneView, IPaneViewOptions, IPaneOptions, Pane } from 'vs/base/browser/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService, Position } from 'vs/workbench/services/layout/browser/layoutService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewPaneContainer, IViewsRegistry, IViewContentDescriptor } from 'vs/workbench/common/views';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewPaneContainer, IViewsRegistry, IViewContentDescriptor, IAddedViewDescriptorRef, IViewDescriptorRef, IViewContainerModel } from 'vs/workbench/common/views';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { assertIsDefined } from 'vs/base/common/types';
import { PersistentContributableViewsModel, IAddedViewDescriptorRef, IViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
@@ -205,7 +204,7 @@ export abstract class ViewPane extends Pane implements IView {
@IThemeService protected themeService: IThemeService,
@ITelemetryService protected telemetryService: ITelemetryService,
) {
super({ ...options, ...{ orientation: viewDescriptorService.getViewLocation(options.id) === ViewContainerLocation.Panel ? Orientation.HORIZONTAL : Orientation.VERTICAL } });
super({ ...options, ...{ orientation: viewDescriptorService.getViewLocationById(options.id) === ViewContainerLocation.Panel ? Orientation.HORIZONTAL : Orientation.VERTICAL } });
this.id = options.id;
this.title = options.title;
@@ -353,11 +352,11 @@ export abstract class ViewPane extends Pane implements IView {
}
protected getProgressLocation(): string {
return this.viewDescriptorService.getViewContainer(this.id)!.id;
return this.viewDescriptorService.getViewContainerByViewId(this.id)!.id;
}
protected getBackgroundColor(): string {
return this.viewDescriptorService.getViewLocation(this.id) === ViewContainerLocation.Panel ? PANEL_BACKGROUND : SIDE_BAR_BACKGROUND;
return this.viewDescriptorService.getViewLocationById(this.id) === ViewContainerLocation.Panel ? PANEL_BACKGROUND : SIDE_BAR_BACKGROUND;
}
focus(): void {
@@ -746,7 +745,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
private readonly visibleViewsCountFromCache: number | undefined;
private readonly visibleViewsStorageId: string;
protected readonly viewsModel: PersistentContributableViewsModel;
protected readonly viewContainerModel: IViewContainerModel;
private viewDisposables: IDisposable[] = [];
private readonly _onTitleAreaUpdate: Emitter<void> = this._register(new Emitter<void>());
@@ -782,7 +781,6 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
constructor(
id: string,
viewPaneContainerStateStorageId: string,
private options: IViewPaneContainerOptions,
@IInstantiationService protected instantiationService: IInstantiationService,
@IConfigurationService protected configurationService: IConfigurationService,
@@ -798,7 +796,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
super(id, themeService, storageService);
const container = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).get(id);
const container = this.viewDescriptorService.getViewContainerById(id);
if (!container) {
throw new Error('Could not find container');
}
@@ -808,7 +806,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
this.visibleViewsStorageId = `${id}.numberOfVisibleViews`;
this.visibleViewsCountFromCache = this.storageService.getNumber(this.visibleViewsStorageId, StorageScope.WORKSPACE, undefined);
this._register(toDisposable(() => this.viewDisposables = dispose(this.viewDisposables)));
this.viewsModel = this._register(this.instantiationService.createInstance(PersistentContributableViewsModel, container, viewPaneContainerStateStorageId));
this.viewContainerModel = this.viewDescriptorService.getViewContainerModel(container);
}
create(parent: HTMLElement): void {
@@ -825,10 +823,10 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
const dropData = e.dragAndDropData.getData();
if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id);
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView)) {
if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView || this.viewContainer.rejectAddedViews)) {
return;
}
@@ -836,12 +834,10 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
const container = viewContainerRegistry.get(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors;
if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) {
if (!viewsToMove.some(v => !v.canMoveView)) {
overlay = new ViewPaneDropOverlay(parent, undefined, this.themeService);
}
}
@@ -855,27 +851,25 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
onDrop: (e) => {
if (overlay) {
const dropData = e.dragAndDropData.getData();
const viewsToMove: IViewDescriptor[] = [];
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
const container = viewContainerRegistry.get(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors;
if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) {
dropData.type = 'view';
dropData.id = viewsToMove[0].id;
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const allViews = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
if (!allViews.some(v => !v.canMoveView)) {
viewsToMove.push(...allViews);
}
}
if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id);
} else if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView) {
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], this.viewContainer);
}
}
if (viewsToMove.length > 0) {
this.viewDescriptorService.moveViewsToContainer(viewsToMove, this.viewContainer);
}
}
overlay?.dispose();
@@ -884,11 +878,11 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}));
this._register(this.onDidSashChange(() => this.saveViewSizes()));
this.viewsModel.onDidAdd(added => this.onDidAddViewDescriptors(added));
this.viewsModel.onDidRemove(removed => this.onDidRemoveViewDescriptors(removed));
const addedViews: IAddedViewDescriptorRef[] = this.viewsModel.visibleViewDescriptors.map((viewDescriptor, index) => {
const size = this.viewsModel.getSize(viewDescriptor.id);
const collapsed = this.viewsModel.isCollapsed(viewDescriptor.id);
this.viewContainerModel.onDidAddVisibleViewDescriptors(added => this.onDidAddViewDescriptors(added));
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);
return ({ viewDescriptor, index, size, collapsed });
});
if (addedViews.length) {
@@ -906,15 +900,17 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
getTitle(): string {
const containerTitle = this.viewContainerModel.title;
if (this.isViewMergedWithContainer()) {
const paneItemTitle = this.paneItems[0].pane.title;
if (this.options.donotShowContainerTitleWhenMergedWithContainer || this.viewContainer.name === paneItemTitle) {
if (this.options.donotShowContainerTitleWhenMergedWithContainer || containerTitle === paneItemTitle) {
return this.paneItems[0].pane.title;
}
return paneItemTitle ? `${this.viewContainer.name}: ${paneItemTitle}` : this.viewContainer.name;
return paneItemTitle ? `${containerTitle}: ${paneItemTitle}` : containerTitle;
}
return this.viewContainer.name;
return containerTitle;
}
private showContextMenu(event: StandardMouseEvent): void {
@@ -939,7 +935,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
const result: IAction[] = [];
if (!viewDescriptor && this.isViewMergedWithContainer()) {
viewDescriptor = this.viewDescriptorService.getViewDescriptor(this.panes[0].id) || undefined;
viewDescriptor = this.viewDescriptorService.getViewDescriptorById(this.panes[0].id) || undefined;
}
if (viewDescriptor) {
@@ -955,10 +951,10 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
}
const viewToggleActions = this.viewsModel.viewDescriptors.map(viewDescriptor => (<IAction>{
const viewToggleActions = this.viewContainerModel.activeViewDescriptors.map(viewDescriptor => (<IAction>{
id: `${viewDescriptor.id}.toggleVisibility`,
label: viewDescriptor.name,
checked: this.viewsModel.isVisible(viewDescriptor.id),
checked: this.viewContainerModel.isVisible(viewDescriptor.id),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor.id)
}));
@@ -1087,7 +1083,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
// Save size only when the layout has happened
if (this.didLayout) {
for (const view of this.panes) {
this.viewsModel.setSize(view.id, this.getPaneSize(view));
this.viewContainerModel.setSize(view.id, this.getPaneSize(view));
}
}
}
@@ -1096,10 +1092,10 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
// Restore sizes only when the layout has happened
if (this.didLayout) {
let initialSizes;
for (let i = 0; i < this.viewsModel.visibleViewDescriptors.length; i++) {
for (let i = 0; i < this.viewContainerModel.visibleViewDescriptors.length; i++) {
const pane = this.panes[i];
const viewDescriptor = this.viewsModel.visibleViewDescriptors[i];
const size = this.viewsModel.getSize(viewDescriptor.id);
const viewDescriptor = this.viewContainerModel.visibleViewDescriptors[i];
const size = this.viewContainerModel.getSize(viewDescriptor.id);
if (typeof size === 'number') {
this.resizePane(pane, size);
@@ -1114,8 +1110,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
private computeInitialSizes(): Map<string, number> {
const sizes: Map<string, number> = new Map<string, number>();
if (this.dimension) {
const totalWeight = this.viewsModel.visibleViewDescriptors.reduce((totalWeight, { weight }) => totalWeight + (weight || 20), 0);
for (const viewDescriptor of this.viewsModel.visibleViewDescriptors) {
const totalWeight = this.viewContainerModel.visibleViewDescriptors.reduce((totalWeight, { weight }) => totalWeight + (weight || 20), 0);
for (const viewDescriptor of this.viewContainerModel.visibleViewDescriptors) {
if (this.orientation === Orientation.VERTICAL) {
sizes.set(viewDescriptor.id, this.dimension.height * (viewDescriptor.weight || 20) / totalWeight);
} else {
@@ -1145,9 +1141,6 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
openView(id: string, focus?: boolean): IView {
if (focus) {
this.focus();
}
let view = this.getView(id);
if (!view) {
this.toggleViewVisibility(id);
@@ -1179,7 +1172,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
});
const collapseDisposable = Event.latch(Event.map(pane.onDidChange, () => !pane.isExpanded()))(collapsed => {
this.viewsModel.setCollapsed(viewDescriptor.id, collapsed);
this.viewContainerModel.setCollapsed(viewDescriptor.id, collapsed);
});
this.viewDisposables.splice(index, 0, combinedDisposable(contextMenuDisposable, collapseDisposable));
@@ -1210,13 +1203,13 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
protected toggleViewVisibility(viewId: string): void {
const visible = !this.viewsModel.isVisible(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.viewsModel.setVisible(viewId, visible);
this.viewContainerModel.setVisible(viewId, visible);
}
private addPane(pane: ViewPane, size: number, index = this.paneItems.length - 1): void {
@@ -1257,27 +1250,24 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
const dropData = e.dragAndDropData.getData();
if (dropData.type === 'view' && dropData.id !== pane.id) {
const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id);
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView)) {
if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView || this.viewContainer.rejectAddedViews)) {
return;
}
overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, this.themeService);
}
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id && !this.viewContainer.rejectAddedViews) {
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
const container = viewContainerRegistry.get(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors;
if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) {
if (!viewsToMove.some(v => !v.canMoveView)) {
overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, this.themeService);
}
}
}
},
onDragLeave: (e) => {
@@ -1287,31 +1277,38 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
onDrop: (e) => {
if (overlay) {
const dropData = e.dragAndDropData.getData();
const viewsToMove: IViewDescriptor[] = [];
let anchorView: IViewDescriptor | undefined;
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) {
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id && !this.viewContainer.rejectAddedViews) {
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const allViews = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
const container = viewContainerRegistry.get(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors;
if (allViews.length > 0 && !allViews.some(v => !v.canMoveView)) {
viewsToMove.push(...allViews);
anchorView = allViews[0];
}
} else if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView && !this.viewContainer.rejectAddedViews) {
viewsToMove.push(viewDescriptor);
}
if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) {
dropData.type = 'view';
dropData.id = viewsToMove[0].id;
if (viewDescriptor) {
anchorView = viewDescriptor;
}
}
if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id);
if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView) {
this.viewDescriptorService.moveViewsToContainer([viewDescriptor], this.viewContainer);
}
if (viewsToMove) {
this.viewDescriptorService.moveViewsToContainer(viewsToMove, this.viewContainer);
}
if (anchorView) {
if (overlay.currentDropOperation === DropDirection.DOWN ||
overlay.currentDropOperation === DropDirection.RIGHT) {
const fromIndex = this.panes.findIndex(p => p.id === dropData.id);
const fromIndex = this.panes.findIndex(p => p.id === anchorView!.id);
let toIndex = this.panes.findIndex(p => p.id === pane.id);
if (fromIndex >= 0 && toIndex >= 0) {
@@ -1327,7 +1324,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
if (overlay.currentDropOperation === DropDirection.UP ||
overlay.currentDropOperation === DropDirection.LEFT) {
const fromIndex = this.panes.findIndex(p => p.id === dropData.id);
const fromIndex = this.panes.findIndex(p => p.id === anchorView!.id);
let toIndex = this.panes.findIndex(p => p.id === pane.id);
if (fromIndex >= 0 && toIndex >= 0) {
@@ -1340,6 +1337,23 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
}
}
}
if (viewsToMove.length > 1) {
viewsToMove.slice(1).forEach(view => {
let toIndex = this.panes.findIndex(p => p.id === anchorView!.id);
let fromIndex = this.panes.findIndex(p => p.id === view.id);
if (fromIndex >= 0 && toIndex >= 0) {
if (fromIndex > toIndex) {
toIndex++;
}
if (toIndex < this.panes.length && toIndex !== fromIndex) {
this.movePane(this.panes[fromIndex], this.panes[toIndex]);
anchorView = view;
}
}
});
}
}
}
@@ -1383,8 +1397,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
const fromIndex = firstIndex(this.paneItems, item => item.pane === from);
const toIndex = firstIndex(this.paneItems, item => item.pane === to);
const fromViewDescriptor = this.viewsModel.visibleViewDescriptors[fromIndex];
const toViewDescriptor = this.viewsModel.visibleViewDescriptors[toIndex];
const fromViewDescriptor = this.viewContainerModel.visibleViewDescriptors[fromIndex];
const toViewDescriptor = this.viewContainerModel.visibleViewDescriptors[toIndex];
if (fromIndex < 0 || fromIndex >= this.paneItems.length) {
return;
@@ -1399,7 +1413,9 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
assertIsDefined(this.paneview).movePane(from, to);
this.viewsModel.move(fromViewDescriptor.id, toViewDescriptor.id);
this.viewContainerModel.move(fromViewDescriptor.id, toViewDescriptor.id);
this.updateTitleArea();
}
resizePane(pane: ViewPane, size: number): void {

View File

@@ -7,16 +7,14 @@ import 'vs/css!./media/views';
import { Disposable, IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IViewDescriptorService, ViewContainer, IViewDescriptor, IViewContainersRegistry, Extensions as ViewExtensions, IView, ViewContainerLocation, IViewsService, IViewPaneContainer, getVisbileViewContextKey } from 'vs/workbench/common/views';
import { Registry } from 'vs/platform/registry/common/platform';
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { Event, Emitter } from 'vs/base/common/event';
import { firstIndex, move } from 'vs/base/common/arrays';
import { isUndefinedOrNull, isUndefined, isString } from 'vs/base/common/types';
import { isString } from 'vs/base/common/types';
import { MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { localize } from 'vs/nls';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { values } from 'vs/base/common/map';
import { toggleClass, addClass } from 'vs/base/browser/dom';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
@@ -34,488 +32,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { URI } from 'vs/base/common/uri';
import { IProgressIndicator } from 'vs/platform/progress/common/progress';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
export interface IViewState {
visibleGlobal: boolean | undefined;
visibleWorkspace: boolean | undefined;
collapsed: boolean | undefined;
order?: number;
size?: number;
}
export interface IViewDescriptorRef {
viewDescriptor: IViewDescriptor;
index: number;
}
export interface IAddedViewDescriptorRef extends IViewDescriptorRef {
collapsed: boolean;
size?: number;
}
export class ContributableViewsModel extends Disposable {
private _viewDescriptors: IViewDescriptor[] = [];
get viewDescriptors(): ReadonlyArray<IViewDescriptor> {
return this._viewDescriptors;
}
get visibleViewDescriptors(): IViewDescriptor[] {
return this.viewDescriptors.filter(v => this.isViewDescriptorVisible(v));
}
private _onDidAdd = this._register(new Emitter<IAddedViewDescriptorRef[]>());
readonly onDidAdd: Event<IAddedViewDescriptorRef[]> = this._onDidAdd.event;
private _onDidRemove = this._register(new Emitter<IViewDescriptorRef[]>());
readonly onDidRemove: Event<IViewDescriptorRef[]> = this._onDidRemove.event;
private _onDidMove = this._register(new Emitter<{ from: IViewDescriptorRef; to: IViewDescriptorRef; }>());
readonly onDidMove: Event<{ from: IViewDescriptorRef; to: IViewDescriptorRef; }> = this._onDidMove.event;
private _onDidChangeViewState = this._register(new Emitter<IViewDescriptorRef>());
protected readonly onDidChangeViewState: Event<IViewDescriptorRef> = this._onDidChangeViewState.event;
private _onDidChangeActiveViews = this._register(new Emitter<ReadonlyArray<IViewDescriptor>>());
readonly onDidChangeActiveViews: Event<ReadonlyArray<IViewDescriptor>> = this._onDidChangeActiveViews.event;
constructor(
container: ViewContainer,
viewsService: IViewDescriptorService,
protected viewStates = new Map<string, IViewState>(),
) {
super();
const viewDescriptorCollection = viewsService.getViewDescriptors(container);
this._register(viewDescriptorCollection.onDidChangeActiveViews(() => this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors)));
this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors);
}
isVisible(id: string): boolean {
const viewDescriptor = this.viewDescriptors.filter(v => v.id === id)[0];
if (!viewDescriptor) {
throw new Error(`Unknown view ${id}`);
}
return this.isViewDescriptorVisible(viewDescriptor);
}
setVisible(id: string, visible: boolean, size?: number): void {
this.doSetVisible([{ id, visible, size }]);
}
protected doSetVisible(viewDescriptors: { id: string, visible: boolean, size?: number }[]): void {
const added: IAddedViewDescriptorRef[] = [];
const removed: IViewDescriptorRef[] = [];
for (const { visibleIndex, viewDescriptor, state, visible, size } of viewDescriptors.map(({ id, visible, size }) => ({ ...this.find(id), visible, size }))) {
if (!viewDescriptor.canToggleVisibility) {
throw new Error(`Can't toggle this view's visibility`);
}
if (this.isViewDescriptorVisible(viewDescriptor) === visible) {
return;
}
if (viewDescriptor.workspace) {
state.visibleWorkspace = visible;
} else {
state.visibleGlobal = visible;
}
if (typeof size === 'number') {
state.size = size;
}
if (visible) {
added.push({ index: visibleIndex, viewDescriptor, size: state.size, collapsed: !!state.collapsed });
} else {
removed.push({ index: visibleIndex, viewDescriptor });
}
}
if (added.length) {
this._onDidAdd.fire(added);
}
if (removed.length) {
this._onDidRemove.fire(removed);
}
}
isCollapsed(id: string): boolean {
const state = this.viewStates.get(id);
if (!state) {
throw new Error(`Unknown view ${id}`);
}
return !!state.collapsed;
}
setCollapsed(id: string, collapsed: boolean): void {
const { index, state, viewDescriptor } = this.find(id);
if (state.collapsed !== collapsed) {
state.collapsed = collapsed;
this._onDidChangeViewState.fire({ viewDescriptor, index });
}
}
getSize(id: string): number | undefined {
const state = this.viewStates.get(id);
if (!state) {
throw new Error(`Unknown view ${id}`);
}
return state.size;
}
setSize(id: string, size: number): void {
const { index, state, viewDescriptor } = this.find(id);
if (state.size !== size) {
state.size = size;
this._onDidChangeViewState.fire({ viewDescriptor, index });
}
}
move(from: string, to: string): void {
const fromIndex = firstIndex(this.viewDescriptors, v => v.id === from);
const toIndex = firstIndex(this.viewDescriptors, v => v.id === to);
const fromViewDescriptor = this.viewDescriptors[fromIndex];
const toViewDescriptor = this.viewDescriptors[toIndex];
move(this._viewDescriptors, fromIndex, toIndex);
for (let index = 0; index < this.viewDescriptors.length; index++) {
const state = this.viewStates.get(this.viewDescriptors[index].id)!;
state.order = index;
}
this._onDidMove.fire({
from: { index: fromIndex, viewDescriptor: fromViewDescriptor },
to: { index: toIndex, viewDescriptor: toViewDescriptor }
});
}
private isViewDescriptorVisible(viewDescriptor: IViewDescriptor): boolean {
const viewState = this.viewStates.get(viewDescriptor.id);
if (!viewState) {
throw new Error(`Unknown view ${viewDescriptor.id}`);
}
return viewDescriptor.workspace ? !!viewState.visibleWorkspace : !!viewState.visibleGlobal;
}
private find(id: string): { index: number, visibleIndex: number, viewDescriptor: IViewDescriptor, state: IViewState; } {
for (let i = 0, visibleIndex = 0; i < this.viewDescriptors.length; i++) {
const viewDescriptor = this.viewDescriptors[i];
const state = this.viewStates.get(viewDescriptor.id);
if (!state) {
throw new Error(`View state for ${id} not found`);
}
if (viewDescriptor.id === id) {
return { index: i, visibleIndex, viewDescriptor, state };
}
if (viewDescriptor.workspace ? state.visibleWorkspace : state.visibleGlobal) {
visibleIndex++;
}
}
throw new Error(`view descriptor ${id} not found`);
}
private compareViewDescriptors(a: IViewDescriptor, b: IViewDescriptor): number {
if (a.id === b.id) {
return 0;
}
return (this.getViewOrder(a) - this.getViewOrder(b)) || this.getGroupOrderResult(a, b);
}
private getGroupOrderResult(a: IViewDescriptor, b: IViewDescriptor) {
if (!a.group || !b.group) {
return 0;
}
if (a.group === b.group) {
return 0;
}
return a.group < b.group ? -1 : 1;
}
private getViewOrder(viewDescriptor: IViewDescriptor): number {
const viewState = this.viewStates.get(viewDescriptor.id);
const viewOrder = viewState && typeof viewState.order === 'number' ? viewState.order : viewDescriptor.order;
return typeof viewOrder === 'number' ? viewOrder : Number.MAX_VALUE;
}
private onDidChangeViewDescriptors(viewDescriptors: IViewDescriptor[]): void {
for (const viewDescriptor of viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id);
if (viewState) {
// set defaults if not set
if (viewDescriptor.workspace) {
viewState.visibleWorkspace = isUndefinedOrNull(viewState.visibleWorkspace) ? !viewDescriptor.hideByDefault : viewState.visibleWorkspace;
} else {
viewState.visibleGlobal = isUndefinedOrNull(viewState.visibleGlobal) ? !viewDescriptor.hideByDefault : viewState.visibleGlobal;
}
viewState.collapsed = isUndefinedOrNull(viewState.collapsed) ? !!viewDescriptor.collapsed : viewState.collapsed;
} else {
this.viewStates.set(viewDescriptor.id, {
visibleGlobal: !viewDescriptor.hideByDefault,
visibleWorkspace: !viewDescriptor.hideByDefault,
collapsed: !!viewDescriptor.collapsed
});
}
}
viewDescriptors = viewDescriptors.sort(this.compareViewDescriptors.bind(this));
const toRemove: { index: number, viewDescriptor: IViewDescriptor; }[] = [];
for (let index = 0; index < this._viewDescriptors.length; index++) {
const previousViewDescriptor = this._viewDescriptors[index];
if (this.isViewDescriptorVisible(previousViewDescriptor) && viewDescriptors.every(viewDescriptor => viewDescriptor.id !== previousViewDescriptor.id)) {
const { visibleIndex } = this.find(previousViewDescriptor.id);
toRemove.push({ index: visibleIndex, viewDescriptor: previousViewDescriptor });
}
}
const previous = this._viewDescriptors;
this._viewDescriptors = viewDescriptors.slice(0);
const toAdd: { index: number, viewDescriptor: IViewDescriptor, size?: number, collapsed: boolean; }[] = [];
for (let i = 0; i < this._viewDescriptors.length; i++) {
const viewDescriptor = this._viewDescriptors[i];
if (this.isViewDescriptorVisible(viewDescriptor) && previous.every(previousViewDescriptor => previousViewDescriptor.id !== viewDescriptor.id)) {
const { visibleIndex, state } = this.find(viewDescriptor.id);
toAdd.push({ index: visibleIndex, viewDescriptor, size: state.size, collapsed: !!state.collapsed });
}
}
if (toRemove.length) {
this._onDidRemove.fire(toRemove);
}
if (toAdd.length) {
this._onDidAdd.fire(toAdd);
}
this._onDidChangeActiveViews.fire(this.viewDescriptors);
}
}
interface IStoredWorkspaceViewState {
collapsed: boolean;
isHidden: boolean;
size?: number;
order?: number;
}
interface IStoredGlobalViewState {
id: string;
isHidden: boolean;
order?: number;
}
export class PersistentContributableViewsModel extends ContributableViewsModel {
private readonly workspaceViewsStateStorageId: string;
private readonly globalViewsStateStorageId: string;
private storageService: IStorageService;
constructor(
container: ViewContainer,
viewletStateStorageId: string,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IStorageService storageService: IStorageService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
) {
const globalViewsStateStorageId = `${viewletStateStorageId}.hidden`;
storageKeysSyncRegistryService.registerStorageKey({ key: globalViewsStateStorageId, version: 1 });
const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, globalViewsStateStorageId, storageService);
super(container, viewDescriptorService, viewStates);
this.storageService = storageService;
this.workspaceViewsStateStorageId = viewletStateStorageId;
this.globalViewsStateStorageId = globalViewsStateStorageId;
this._register(Event.any(
this.onDidAdd,
this.onDidRemove,
Event.map(this.onDidMove, ({ from, to }) => [from, to]),
Event.map(this.onDidChangeViewState, viewDescriptorRef => [viewDescriptorRef]))
(viewDescriptorRefs => this.saveViewsStates()));
this._globalViewsStatesValue = this.getStoredGlobalViewsStatesValue();
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
}
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
if (e.key === this.globalViewsStateStorageId && e.scope === StorageScope.GLOBAL
&& this.globalViewsStatesValue !== this.getStoredGlobalViewsStatesValue() /* This checks if current window changed the value or not */) {
this._globalViewsStatesValue = undefined;
const storedViewsVisibilityStates = PersistentContributableViewsModel.loadGlobalViewsState(this.globalViewsStateStorageId, this.storageService, StorageScope.GLOBAL);
const changedViews: { id: string, visible: boolean }[] = [];
for (const [id, state] of storedViewsVisibilityStates) {
const viewState = this.viewStates.get(id);
if (viewState) {
if (viewState.visibleGlobal !== !state.isHidden) {
changedViews.push({ id, visible: !state.isHidden });
}
}
}
if (changedViews.length) {
this.doSetVisible(changedViews);
}
}
}
private saveViewsStates(): void {
this.saveWorkspaceViewsStates();
this.saveGlobalViewsStates();
}
private saveWorkspaceViewsStates(): void {
const storedViewsStates: { [id: string]: IStoredWorkspaceViewState; } = JSON.parse(this.storageService.get(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}'));
for (const viewDescriptor of this.viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id);
if (viewState) {
storedViewsStates[viewDescriptor.id] = {
collapsed: !!viewState.collapsed,
isHidden: !viewState.visibleWorkspace,
size: viewState.size,
order: viewDescriptor.workspace && viewState ? viewState.order : undefined
};
}
}
if (Object.keys(storedViewsStates).length > 0) {
this.storageService.store(this.workspaceViewsStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE);
} else {
this.storageService.remove(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE);
}
}
private saveGlobalViewsStates(): void {
const storedViewsVisibilityStates = PersistentContributableViewsModel.loadGlobalViewsState(this.globalViewsStateStorageId, this.storageService, StorageScope.GLOBAL);
for (const viewDescriptor of this.viewDescriptors) {
const viewState = this.viewStates.get(viewDescriptor.id);
storedViewsVisibilityStates.set(viewDescriptor.id, {
id: viewDescriptor.id,
isHidden: viewState && viewDescriptor.canToggleVisibility ? !viewState.visibleGlobal : false,
order: !viewDescriptor.workspace && viewState ? viewState.order : undefined
});
}
this.globalViewsStatesValue = JSON.stringify(values(storedViewsVisibilityStates));
}
private _globalViewsStatesValue: string | undefined;
private get globalViewsStatesValue(): string {
if (!this._globalViewsStatesValue) {
this._globalViewsStatesValue = this.getStoredGlobalViewsStatesValue();
}
return this._globalViewsStatesValue;
}
private set globalViewsStatesValue(globalViewsStatesValue: string) {
if (this.globalViewsStatesValue !== globalViewsStatesValue) {
this._globalViewsStatesValue = globalViewsStatesValue;
this.setStoredGlobalViewsStatesValue(globalViewsStatesValue);
}
}
private getStoredGlobalViewsStatesValue(): string {
return this.storageService.get(this.globalViewsStateStorageId, StorageScope.GLOBAL, '[]');
}
private setStoredGlobalViewsStatesValue(value: string): void {
this.storageService.store(this.globalViewsStateStorageId, value, StorageScope.GLOBAL);
}
private static loadViewsStates(workspaceViewsStateStorageId: string, globalViewsStateStorageId: string, storageService: IStorageService): Map<string, IViewState> {
const viewStates = new Map<string, IViewState>();
const workspaceViewsStates = <{ [id: string]: IStoredWorkspaceViewState; }>JSON.parse(storageService.get(workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}'));
for (const id of Object.keys(workspaceViewsStates)) {
const workspaceViewState = workspaceViewsStates[id];
viewStates.set(id, {
visibleGlobal: undefined,
visibleWorkspace: isUndefined(workspaceViewState.isHidden) ? undefined : !workspaceViewState.isHidden,
collapsed: workspaceViewState.collapsed,
order: workspaceViewState.order,
size: workspaceViewState.size
});
}
// Migrate to `viewletStateStorageId`
const workspaceVisibilityStates = this.loadGlobalViewsState(globalViewsStateStorageId, storageService, StorageScope.WORKSPACE);
if (workspaceVisibilityStates.size > 0) {
for (const { id, isHidden } of values(workspaceVisibilityStates)) {
let viewState = viewStates.get(id);
// Not migrated to `viewletStateStorageId`
if (viewState) {
if (isUndefined(viewState.visibleWorkspace)) {
viewState.visibleWorkspace = !isHidden;
}
} else {
viewStates.set(id, {
collapsed: undefined,
visibleGlobal: undefined,
visibleWorkspace: !isHidden,
});
}
}
storageService.remove(globalViewsStateStorageId, StorageScope.WORKSPACE);
}
const globalViewsStates = this.loadGlobalViewsState(globalViewsStateStorageId, storageService, StorageScope.GLOBAL);
for (const { id, isHidden, order } of values(globalViewsStates)) {
let viewState = viewStates.get(id);
if (viewState) {
viewState.visibleGlobal = !isHidden;
if (!isUndefined(order)) {
viewState.order = order;
}
} else {
viewStates.set(id, {
visibleGlobal: !isHidden,
order,
collapsed: undefined,
visibleWorkspace: undefined,
});
}
}
return viewStates;
}
private static loadGlobalViewsState(globalViewsStateStorageId: string, storageService: IStorageService, scope: StorageScope): Map<string, IStoredGlobalViewState> {
const storedValue = <Array<string | IStoredGlobalViewState>>JSON.parse(storageService.get(globalViewsStateStorageId, scope, '[]'));
let hasDuplicates = false;
const storedGlobalViewsState = storedValue.reduce((result, storedState) => {
if (typeof storedState === 'string' /* migration */) {
hasDuplicates = hasDuplicates || result.has(storedState);
result.set(storedState, { id: storedState, isHidden: true });
} else {
hasDuplicates = hasDuplicates || result.has(storedState.id);
result.set(storedState.id, storedState);
}
return result;
}, new Map<string, IStoredGlobalViewState>());
if (hasDuplicates) {
storageService.store(globalViewsStateStorageId, JSON.stringify(values(storedGlobalViewsState)), scope);
}
return storedGlobalViewsState;
}
}
export class ViewsService extends Disposable implements IViewsService {
@@ -536,6 +52,7 @@ export class ViewsService extends Disposable implements IViewsService {
@IPanelService private readonly panelService: IPanelService,
@IViewletService private readonly viewletService: IViewletService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
) {
super();
@@ -549,7 +66,7 @@ export class ViewsService extends Disposable implements IViewsService {
this.viewDisposable.clear();
}));
this.viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer, this.viewContainersRegistry.getViewContainerLocation(viewContainer)));
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)));
@@ -592,17 +109,17 @@ export class ViewsService extends Disposable implements IViewsService {
private onDidRegisterViewContainer(viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation): void {
this.registerViewletOrPanel(viewContainer, viewContainerLocation);
const viewDescriptorCollection = this.viewDescriptorService.getViewDescriptors(viewContainer);
this.onViewDescriptorsAdded(viewDescriptorCollection.allViewDescriptors, viewContainer);
this._register(viewDescriptorCollection.onDidChangeViews(({ added, removed }) => {
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
this.onViewDescriptorsAdded(viewContainerModel.allViewDescriptors, viewContainer);
this._register(viewContainerModel.onDidChangeAllViewDescriptors(({ added, removed }) => {
this.onViewDescriptorsAdded(added, viewContainer);
this.onViewDescriptorsRemoved(removed);
}));
}
private onViewDescriptorsAdded(views: IViewDescriptor[], container: ViewContainer): void {
const location = this.viewContainersRegistry.getViewContainerLocation(container);
if (location === undefined) {
private onViewDescriptorsAdded(views: ReadonlyArray<IViewDescriptor>, container: ViewContainer): void {
const location = this.viewDescriptorService.getViewContainerLocation(container);
if (location === null) {
return;
}
@@ -655,7 +172,7 @@ export class ViewsService extends Disposable implements IViewsService {
}
run(accessor: ServicesAccessor): void {
const viewDescriptorService = accessor.get(IViewDescriptorService);
viewDescriptorService.moveViewsToContainer([viewDescriptor], viewDescriptorService.getDefaultContainer(viewDescriptor.id)!);
viewDescriptorService.moveViewsToContainer([viewDescriptor], viewDescriptorService.getDefaultContainerById(viewDescriptor.id)!);
accessor.get(IViewsService).openView(viewDescriptor.id, true);
}
}));
@@ -664,7 +181,7 @@ export class ViewsService extends Disposable implements IViewsService {
}
}
private onViewDescriptorsRemoved(views: IViewDescriptor[]): void {
private onViewDescriptorsRemoved(views: ReadonlyArray<IViewDescriptor>): void {
for (const view of views) {
const disposable = this.viewDisposable.get(view);
if (disposable) {
@@ -699,7 +216,7 @@ export class ViewsService extends Disposable implements IViewsService {
}
getActiveViewWithId<T extends IView>(id: string): T | null {
const viewContainer = this.viewDescriptorService.getViewContainer(id);
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
if (viewContainer) {
const activeViewPaneContainer = this.getActiveViewPaneContainer(viewContainer);
if (activeViewPaneContainer) {
@@ -710,14 +227,16 @@ export class ViewsService extends Disposable implements IViewsService {
}
async openView<T extends IView>(id: string, focus: boolean): Promise<T | null> {
const viewContainer = this.viewDescriptorService.getViewContainer(id);
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
if (viewContainer) {
const location = this.viewContainersRegistry.getViewContainerLocation(viewContainer);
const location = this.viewDescriptorService.getViewContainerLocation(viewContainer);
const compositeDescriptor = this.getComposite(viewContainer.id, location!);
if (compositeDescriptor) {
const paneComposite = await this.openComposite(compositeDescriptor.id, location!, focus) as IPaneComposite | undefined;
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();
}
}
}
@@ -726,16 +245,16 @@ export class ViewsService extends Disposable implements IViewsService {
}
closeView(id: string): void {
const viewContainer = this.viewDescriptorService.getViewContainer(id);
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
if (viewContainer) {
const activeViewPaneContainer = this.getActiveViewPaneContainer(viewContainer);
if (activeViewPaneContainer) {
const view = activeViewPaneContainer.getView(id);
if (view) {
if (activeViewPaneContainer.views.length === 1) {
const location = this.viewContainersRegistry.getViewContainerLocation(viewContainer);
const location = this.viewDescriptorService.getViewContainerLocation(viewContainer);
if (location === ViewContainerLocation.Sidebar) {
this.viewletService.hideActiveViewlet();
this.layoutService.setSideBarHidden(true);
} else if (location === ViewContainerLocation.Panel) {
this.panelService.hideActivePanel();
}
@@ -748,7 +267,7 @@ export class ViewsService extends Disposable implements IViewsService {
}
private getActiveViewPaneContainer(viewContainer: ViewContainer): IViewPaneContainer | null {
const location = this.viewContainersRegistry.getViewContainerLocation(viewContainer);
const location = this.viewDescriptorService.getViewContainerLocation(viewContainer);
if (location === ViewContainerLocation.Sidebar) {
const activeViewlet = this.viewletService.getActiveViewlet();
@@ -766,7 +285,7 @@ export class ViewsService extends Disposable implements IViewsService {
}
getProgressIndicator(id: string): IProgressIndicator | undefined {
const viewContainer = this.viewDescriptorService.getViewContainer(id);
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
if (viewContainer === null) {
return undefined;
}

View File

@@ -6,7 +6,7 @@
import { IAction } from 'vs/base/common/actions';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IViewDescriptor, IViewDescriptorService } from 'vs/workbench/common/views';
import { IViewDescriptor, IViewDescriptorService, IAddedViewDescriptorRef } from 'vs/workbench/common/views';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -16,7 +16,6 @@ import { ViewPaneContainer, ViewPane, IViewPaneOptions } from 'vs/workbench/brow
import { Event } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
export interface IViewletViewOptions extends IViewPaneOptions {
}
@@ -41,14 +40,14 @@ export abstract class FilterViewPaneContainer extends ViewPaneContainer {
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
) {
super(viewletId, `${viewletId}.state`, { mergeViewWithContainerWhenSingleView: false }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
super(viewletId, { mergeViewWithContainerWhenSingleView: false }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
this._register(onDidChangeFilterValue(newFilterValue => {
this.filterValue = newFilterValue;
this.onFilterChanged(newFilterValue);
}));
this._register(this.viewsModel.onDidChangeActiveViews((viewDescriptors) => {
this.updateAllViews(viewDescriptors);
this._register(this.viewContainerModel.onDidChangeActiveViewDescriptors(() => {
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
}));
}
@@ -63,7 +62,7 @@ export abstract class FilterViewPaneContainer extends ViewPaneContainer {
}
this.allViews.get(filterOnValue)!.set(descriptor.id, descriptor);
if (this.filterValue && !this.filterValue.includes(filterOnValue)) {
this.viewsModel.setVisible(descriptor.id, false);
this.viewContainerModel.setVisible(descriptor.id, false);
}
});
}
@@ -76,17 +75,17 @@ export abstract class FilterViewPaneContainer extends ViewPaneContainer {
private onFilterChanged(newFilterValue: string[]) {
if (this.allViews.size === 0) {
this.updateAllViews(this.viewsModel.viewDescriptors);
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
}
this.getViewsNotForTarget(newFilterValue).forEach(item => this.viewsModel.setVisible(item.id, false));
this.getViewsForTarget(newFilterValue).forEach(item => this.viewsModel.setVisible(item.id, true));
this.getViewsNotForTarget(newFilterValue).forEach(item => this.viewContainerModel.setVisible(item.id, false));
this.getViewsForTarget(newFilterValue).forEach(item => this.viewContainerModel.setVisible(item.id, true));
}
getContextMenuActions(): IAction[] {
const result: IAction[] = Array.from(this.constantViewDescriptors.values()).map(viewDescriptor => (<IAction>{
id: `${viewDescriptor.id}.toggleVisibility`,
label: viewDescriptor.name,
checked: this.viewsModel.isVisible(viewDescriptor.id),
checked: this.viewContainerModel.isVisible(viewDescriptor.id),
enabled: viewDescriptor.canToggleVisibility,
run: () => this.toggleViewVisibility(viewDescriptor.id)
}));
@@ -134,7 +133,7 @@ export abstract class FilterViewPaneContainer extends ViewPaneContainer {
}
// Check that allViews is ready
if (this.allViews.size === 0) {
this.updateAllViews(this.viewsModel.viewDescriptors);
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
}
return panes;
}

View File

@@ -193,7 +193,11 @@ export class ShowViewletAction extends Action {
}
export class CollapseAction extends Action {
constructor(tree: AsyncDataTree<any, any, any> | AbstractTree<any, any, any>, enabled: boolean, clazz?: string) {
super('workbench.action.collapse', nls.localize('collapse', "Collapse All"), clazz, enabled, async () => tree.collapseAll());
// We need a tree getter because the action is sometimes instantiated too early
constructor(treeGetter: () => AsyncDataTree<any, any, any> | AbstractTree<any, any, any>, enabled: boolean, clazz?: string) {
super('workbench.action.collapse', nls.localize('collapse', "Collapse All"), clazz, enabled, async () => {
const tree = treeGetter();
tree.collapseAll();
});
}
}

View File

@@ -33,12 +33,12 @@ import { WorkspaceService } from 'vs/workbench/services/configuration/browser/co
import { ConfigurationCache } from 'vs/workbench/services/configuration/browser/configurationCache';
import { ISignService } from 'vs/platform/sign/common/sign';
import { SignService } from 'vs/platform/sign/browser/signService';
import { IWorkbenchConstructionOptions, IWorkspace } from 'vs/workbench/workbench.web.api';
import { IWorkbenchConstructionOptions, IWorkspace, IWorkbench } from 'vs/workbench/workbench.web.api';
import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider';
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 } from 'vs/platform/storage/common/storage';
import { IStorageService, StorageScope } 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';
@@ -51,6 +51,24 @@ import { getWorkspaceIdentifier } from 'vs/workbench/services/workspaces/browser
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 {
@@ -61,7 +79,7 @@ class BrowserMain extends Disposable {
super();
}
async open(): Promise<void> {
async open(): Promise<IWorkbench> {
const services = await this.initServices();
await domContentLoaded();
@@ -80,13 +98,196 @@ class BrowserMain extends Disposable {
// Listeners
this.registerListeners(workbench, services.storageService);
this.applyDefaultLayout(services.storageService);
// Driver
if (this.configuration.driver) {
(async () => this._register(await registerWindowDriver()))();
}
// Startup
workbench.startup();
const instantiationService = workbench.startup();
// Return API Facade
return instantiationService.invokeFunction(accessor => {
const commandService = accessor.get(ICommandService);
return {
commands: {
executeCommand: (command, ...args) => commandService.executeCommand(command, ...args)
}
};
});
}
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 {
@@ -335,8 +536,8 @@ class BrowserMain extends Disposable {
}
}
export function main(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise<void> {
const renderer = new BrowserMain(domElement, options);
export function main(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise<IWorkbench> {
const workbench = new BrowserMain(domElement, options);
return renderer.open();
return workbench.open();
}

View File

@@ -32,6 +32,17 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
'description': nls.localize('showEditorTabs', "Controls whether opened editors should show in tabs or not."),
'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.")
},
'workbench.editor.highlightModifiedTabs': {
'type': 'boolean',
'description': nls.localize('highlightModifiedTabs', "Controls whether a top border is drawn on modified (dirty) editor tabs or not."),

View File

@@ -320,7 +320,6 @@ export class Workbench extends Layout {
// ARIA
setARIAContainer(this.container);
this.container.setAttribute('role', 'application');
// State specific classes
const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac';
@@ -352,7 +351,7 @@ export class Workbench extends Layout {
{ id: Parts.SIDEBAR_PART, role: 'complementary', classes: ['sidebar', this.state.sideBar.position === Position.LEFT ? 'left' : 'right'] },
{ id: Parts.EDITOR_PART, role: 'main', classes: ['editor'], options: { restorePreviousState: this.state.editor.restoreEditors } },
{ id: Parts.PANEL_PART, role: 'complementary', classes: ['panel', positionToString(this.state.panel.position)] },
{ id: Parts.STATUSBAR_PART, role: 'contentinfo', classes: ['statusbar'] }
{ id: Parts.STATUSBAR_PART, role: 'status', classes: ['statusbar'] }
].forEach(({ id, role, classes, options }) => {
const partContainer = this.createPart(id, role, classes);
@@ -371,6 +370,9 @@ export class Workbench extends Layout {
addClasses(part, 'part', ...classes);
part.id = id;
part.setAttribute('role', role);
if (role === 'status') {
part.setAttribute('aria-live', 'off');
}
return part;
}