mirror of
https://github.com/coder/code-server.git
synced 2026-05-09 05:47:26 +02:00
Update to VS Code 1.52.1
This commit is contained in:
@@ -8,7 +8,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { SyncActionDescriptor, MenuId, MenuRegistry, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchActionRegistry, Extensions as WorkbenchExtensions, CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchLayoutService, Parts, Position } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IEditorGroupsService, GroupOrientation } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -21,7 +21,6 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
|
||||
import { InEditorZenModeContext, IsCenteredLayoutContext, EditorAreaVisibleContext } from 'vs/workbench/common/editor';
|
||||
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, 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';
|
||||
@@ -76,7 +75,7 @@ export class ToggleActivityBarVisibilityAction extends Action2 {
|
||||
const visibility = layoutService.isVisible(Parts.ACTIVITYBAR_PART);
|
||||
const newVisibilityValue = !visibility;
|
||||
|
||||
configurationService.updateValue(ToggleActivityBarVisibilityAction.activityBarVisibleKey, newVisibilityValue, ConfigurationTarget.USER);
|
||||
configurationService.updateValue(ToggleActivityBarVisibilityAction.activityBarVisibleKey, newVisibilityValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +195,7 @@ export class ToggleSidebarPositionAction extends Action {
|
||||
const position = this.layoutService.getSideBarPosition();
|
||||
const newPositionValue = (position === Position.LEFT) ? 'right' : 'left';
|
||||
|
||||
return this.configurationService.updateValue(ToggleSidebarPositionAction.sidebarPositionConfigurationKey, newPositionValue, ConfigurationTarget.USER);
|
||||
return this.configurationService.updateValue(ToggleSidebarPositionAction.sidebarPositionConfigurationKey, newPositionValue);
|
||||
}
|
||||
|
||||
static getLabel(layoutService: IWorkbenchLayoutService): string {
|
||||
@@ -317,7 +316,7 @@ export class ToggleStatusbarVisibilityAction extends Action {
|
||||
const visibility = this.layoutService.isVisible(Parts.STATUSBAR_PART);
|
||||
const newVisibilityValue = !visibility;
|
||||
|
||||
return this.configurationService.updateValue(ToggleStatusbarVisibilityAction.statusbarVisibleKey, newVisibilityValue, ConfigurationTarget.USER);
|
||||
return this.configurationService.updateValue(ToggleStatusbarVisibilityAction.statusbarVisibleKey, newVisibilityValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,14 +418,13 @@ export class ToggleMenuBarAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
let currentVisibilityValue = getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
let currentVisibilityValue = getMenuBarVisibility(this.configurationService);
|
||||
if (typeof currentVisibilityValue !== 'string') {
|
||||
currentVisibilityValue = 'default';
|
||||
}
|
||||
|
||||
@@ -356,19 +356,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
|
||||
// List
|
||||
if (focused instanceof List || focused instanceof PagedList) {
|
||||
const list = focused;
|
||||
|
||||
list.focusPreviousPage();
|
||||
list.reveal(list.getFocus()[0]);
|
||||
focused.focusPreviousPage();
|
||||
}
|
||||
|
||||
// Tree
|
||||
else if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) {
|
||||
const list = focused;
|
||||
|
||||
const fakeKeyboardEvent = new KeyboardEvent('keydown');
|
||||
list.focusPreviousPage(fakeKeyboardEvent);
|
||||
list.reveal(list.getFocus()[0]);
|
||||
focused.focusPreviousPage(fakeKeyboardEvent);
|
||||
}
|
||||
|
||||
// Ensure DOM Focus
|
||||
@@ -386,19 +380,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
|
||||
// List
|
||||
if (focused instanceof List || focused instanceof PagedList) {
|
||||
const list = focused;
|
||||
|
||||
list.focusNextPage();
|
||||
list.reveal(list.getFocus()[0]);
|
||||
focused.focusNextPage();
|
||||
}
|
||||
|
||||
// Tree
|
||||
else if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) {
|
||||
const list = focused;
|
||||
|
||||
const fakeKeyboardEvent = new KeyboardEvent('keydown');
|
||||
list.focusNextPage(fakeKeyboardEvent);
|
||||
list.reveal(list.getFocus()[0]);
|
||||
focused.focusNextPage(fakeKeyboardEvent);
|
||||
}
|
||||
|
||||
// Ensure DOM Focus
|
||||
|
||||
@@ -12,13 +12,10 @@ import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/bro
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IViewlet } from 'vs/workbench/common/viewlet';
|
||||
import { IPanel } from 'vs/workbench/common/panel';
|
||||
import { Action2, MenuId, registerAction2, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchActionRegistry, Extensions, CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { Direction } from 'vs/base/browser/ui/grid/grid';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { isAncestor } from 'vs/base/browser/dom';
|
||||
|
||||
@@ -275,29 +272,6 @@ export class FocusPreviousPart extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
class GoHomeContributor implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
const homeIndicator = environmentService.options?.homeIndicator;
|
||||
if (homeIndicator) {
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: `workbench.actions.goHome`,
|
||||
title: nls.localize('goHome', "Go Home"),
|
||||
menu: { id: MenuId.MenubarWebNavigationMenu }
|
||||
});
|
||||
}
|
||||
async run(): Promise<void> {
|
||||
window.location.href = homeIndicator.href;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Actions Registration
|
||||
|
||||
const actionsRegistry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
@@ -308,9 +282,12 @@ actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateLeftAc
|
||||
actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(NavigateRightAction, undefined), 'View: Navigate to the View on the Right', CATEGORIES.View.value);
|
||||
actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(FocusNextPart, { primary: KeyCode.F6 }), 'View: Focus Next Part', CATEGORIES.View.value);
|
||||
actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(FocusPreviousPart, { primary: KeyMod.Shift | KeyCode.F6 }), 'View: Focus Previous Part', CATEGORIES.View.value);
|
||||
<<<<<<< HEAD
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(GoHomeContributor, LifecyclePhase.Ready);
|
||||
export const _1 = workbenchRegistry;
|
||||
export const _2 = GoHomeContributor;
|
||||
export const _3 = LifecyclePhase.Ready;
|
||||
=======
|
||||
>>>>>>> e4a830e9b7ca039c7c70697786d29f5b6679d775
|
||||
|
||||
@@ -141,7 +141,7 @@ export class OpenWorkspaceConfigFileAction extends Action {
|
||||
async run(): Promise<void> {
|
||||
const configuration = this.workspaceContextService.getWorkspace().configuration;
|
||||
if (configuration) {
|
||||
await this.editorService.openEditor({ resource: configuration });
|
||||
await this.editorService.openEditor({ resource: configuration, options: { pinned: true } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/commo
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
@@ -18,6 +18,10 @@ import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IOpenWindowOptions, IWindowOpenable } from 'vs/platform/windows/common/windows';
|
||||
import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder';
|
||||
export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace...");
|
||||
@@ -61,7 +65,7 @@ CommandsRegistry.registerCommand({
|
||||
title: nls.localize('addFolderToWorkspaceTitle', "Add Folder to Workspace"),
|
||||
canSelectFolders: true,
|
||||
canSelectMany: true,
|
||||
defaultUri: dialogsService.defaultFolderPath()
|
||||
defaultUri: await dialogsService.defaultFolderPath()
|
||||
});
|
||||
|
||||
if (!folders || !folders.length) {
|
||||
@@ -116,3 +120,46 @@ CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, async functio
|
||||
|
||||
return;
|
||||
});
|
||||
|
||||
// API Command registration
|
||||
|
||||
interface IOpenFolderAPICommandOptions {
|
||||
forceNewWindow?: boolean;
|
||||
forceReuseWindow?: boolean;
|
||||
noRecentEntry?: boolean;
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: 'vscode.openFolder',
|
||||
handler: (accessor: ServicesAccessor, uri?: URI, arg?: boolean | IOpenFolderAPICommandOptions) => {
|
||||
const commandService = accessor.get(ICommandService);
|
||||
|
||||
// Be compatible to previous args by converting to options
|
||||
if (typeof arg === 'boolean') {
|
||||
arg = { forceNewWindow: arg };
|
||||
}
|
||||
|
||||
// Without URI, ask to pick a folder or workpsace to open
|
||||
if (!uri) {
|
||||
return commandService.executeCommand('_files.pickFolderAndOpen', { forceNewWindow: arg?.forceNewWindow });
|
||||
}
|
||||
|
||||
uri = URI.revive(uri);
|
||||
|
||||
const options: IOpenWindowOptions = {
|
||||
forceNewWindow: arg?.forceNewWindow,
|
||||
forceReuseWindow: arg?.forceReuseWindow,
|
||||
noRecentEntry: arg?.noRecentEntry
|
||||
};
|
||||
|
||||
const uriToOpen: IWindowOpenable = (hasWorkspaceFileExtension(uri) || uri.scheme === Schemas.untitled) ? { workspaceUri: uri } : { folderUri: uri };
|
||||
return commandService.executeCommand('_files.windowOpen', [uriToOpen], options);
|
||||
},
|
||||
description: {
|
||||
description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.',
|
||||
args: [
|
||||
{ name: 'uri', description: '(optional) Uri of the folder or workspace file to open. If not provided, a native dialog will ask the user for the folder', constraint: (value: any) => value === undefined || value instanceof URI },
|
||||
{ name: 'options', description: '(optional) Options. Object with the following properties: `forceNewWindow `: Whether to open the folder/workspace in a new window or the same. Defaults to opening in the same window. `noRecentEntry`: Wheter the opened URI will appear in the \'Open Recent\' list. Defaults to true. Note, for backward compatibility, options can also be of type boolean, representing the `forceNewWindow` setting.', constraint: (value: any) => value === undefined || typeof value === 'object' || typeof value === 'boolean' }
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { DragMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
import { MIME_BINARY } from 'vs/base/common/mime';
|
||||
import { isWindows, isWeb } from 'vs/base/common/platform';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IEditorIdentifier, GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
@@ -27,7 +27,6 @@ import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsSe
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { isStandalone } from 'vs/base/browser/browser';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
@@ -320,8 +319,7 @@ export function fillResourceDataTransfers(accessor: ServicesAccessor, resources:
|
||||
event.dataTransfer.setData(DataTransfers.TEXT, sources.map(source => source.resource.scheme === Schemas.file ? normalize(normalizeDriveLetter(source.resource.fsPath)) : source.resource.toString()).join(lineDelimiter));
|
||||
|
||||
// Download URL: enables support to drag a tab as file to desktop (only single file supported)
|
||||
// Disabled for PWA web due to: https://github.com/microsoft/vscode/issues/83441
|
||||
if (!sources[0].isDirectory && (!isWeb || !isStandalone)) {
|
||||
if (!sources[0].isDirectory) {
|
||||
event.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, basename(sources[0].resource), FileAccess.asBrowserUri(sources[0].resource).toString()].join(':'));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { EventType, addDisposableListener, isAncestor, getClientArea, Dimension, position, size, IDimension } from 'vs/base/browser/dom';
|
||||
import { EventType, addDisposableListener, getClientArea, Dimension, position, size, IDimension, isAncestorUsingFlowTo } from 'vs/base/browser/dom';
|
||||
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';
|
||||
@@ -16,7 +16,7 @@ import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart';
|
||||
import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
|
||||
import { Position, Parts, PanelOpensMaximizedOptions, IWorkbenchLayoutService, positionFromString, positionToString, panelOpensMaximizedFromString } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IStorageService, StorageScope, WillSaveStateReason } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
@@ -41,7 +41,6 @@ import { INotificationService, NotificationsFilter } from 'vs/platform/notificat
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { WINDOW_ACTIVE_BORDER, WINDOW_INACTIVE_BORDER } from 'vs/workbench/common/theme';
|
||||
import { LineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
@@ -91,21 +90,6 @@ enum Classes {
|
||||
WINDOW_BORDER = 'border'
|
||||
}
|
||||
|
||||
interface PanelActivityState {
|
||||
id: string;
|
||||
name?: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface SideBarActivityState {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export abstract class Layout extends Disposable implements IWorkbenchLayoutService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
@@ -319,7 +303,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this._register(addDisposableListener(this.container, EventType.SCROLL, () => this.container.scrollTop = 0));
|
||||
|
||||
// Menubar visibility changes
|
||||
if ((isWindows || isLinux || isWeb) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
if ((isWindows || isLinux || isWeb) && getTitleBarStyle(this.configurationService) === 'custom') {
|
||||
this._register(this.titleService.onMenubarVisibilityChange(visible => this.onMenubarToggled(visible)));
|
||||
}
|
||||
|
||||
@@ -357,8 +341,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
}
|
||||
|
||||
// Change edge snapping accordingly
|
||||
this.workbenchGrid.edgeSnapping = this.state.fullscreen;
|
||||
|
||||
// Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
if (getTitleBarStyle(this.configurationService) === 'custom') {
|
||||
// Propagate to grid
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART));
|
||||
|
||||
@@ -407,7 +394,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
// Menubar visibility
|
||||
const newMenubarVisibility = getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
const newMenubarVisibility = getMenuBarVisibility(this.configurationService);
|
||||
this.setMenubarVisibility(newMenubarVisibility, !!skipLayout);
|
||||
|
||||
// Centered Layout
|
||||
@@ -451,7 +438,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
private updateWindowBorder(skipLayout: boolean = false) {
|
||||
if (isWeb || getTitleBarStyle(this.configurationService, this.environmentService) !== 'custom') {
|
||||
if (isWeb || getTitleBarStyle(this.configurationService) !== 'custom') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -495,7 +482,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.state.fullscreen = isFullscreen();
|
||||
|
||||
// Menubar visibility
|
||||
this.state.menuBar.visibility = getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
this.state.menuBar.visibility = getMenuBarVisibility(this.configurationService);
|
||||
|
||||
// Activity bar visibility
|
||||
this.state.activityBar.hidden = !this.configurationService.getValue<string>(Settings.ACTIVITYBAR_VISIBLE);
|
||||
@@ -582,167 +569,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
const { views } = defaultLayout;
|
||||
if (views?.length) {
|
||||
this.state.views.defaults = views.map(v => v.id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO@eamodio Everything below here is deprecated and will be removed once Codespaces migrates
|
||||
|
||||
const { sidebar } = defaultLayout;
|
||||
if (sidebar) {
|
||||
if (sidebar.visible !== undefined) {
|
||||
if (sidebar.visible) {
|
||||
storageService.remove(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.store(Storage.SIDEBAR_HIDDEN, true, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebar.containers?.length) {
|
||||
const sidebarState: SideBarActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of sidebar.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let viewletId;
|
||||
switch (container.id) {
|
||||
case 'explorer':
|
||||
viewletId = 'workbench.view.explorer';
|
||||
break;
|
||||
case 'run':
|
||||
viewletId = 'workbench.view.debug';
|
||||
break;
|
||||
case 'scm':
|
||||
viewletId = 'workbench.view.scm';
|
||||
break;
|
||||
case 'search':
|
||||
viewletId = 'workbench.view.search';
|
||||
break;
|
||||
case 'extensions':
|
||||
viewletId = 'workbench.view.extensions';
|
||||
break;
|
||||
case 'remote':
|
||||
viewletId = 'workbench.view.remote';
|
||||
break;
|
||||
default:
|
||||
viewletId = `workbench.view.extension.${container.id}`;
|
||||
}
|
||||
|
||||
if (container.active) {
|
||||
storageService.store(SidebarPart.activeViewletSettingsKey, viewletId, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
if (container.order !== undefined || (container.active === undefined && container.visible !== undefined)) {
|
||||
order = container.order ?? (order + 1);
|
||||
const state: SideBarActivityState = {
|
||||
id: viewletId,
|
||||
order: order,
|
||||
pinned: (container.active || container.visible) ?? true,
|
||||
visible: (container.active || container.visible) ?? true
|
||||
};
|
||||
|
||||
sidebarState.push(state);
|
||||
}
|
||||
|
||||
if (container.views !== undefined) {
|
||||
const viewsState: { id: string, isHidden?: boolean, order?: number }[] = [];
|
||||
const viewsWorkspaceState: { [id: string]: { collapsed: boolean, isHidden?: boolean, size?: number } } = {};
|
||||
|
||||
for (const view of container.views) {
|
||||
if (view.order !== undefined || view.visible !== undefined) {
|
||||
viewsState.push({
|
||||
id: view.id,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
order: view.order === undefined ? undefined : view.order
|
||||
});
|
||||
}
|
||||
|
||||
if (view.collapsed !== undefined) {
|
||||
viewsWorkspaceState[view.id] = {
|
||||
collapsed: view.collapsed,
|
||||
isHidden: view.visible === undefined ? undefined : !view.visible,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
storageService.store(`${viewletId}.state.hidden`, JSON.stringify(viewsState), StorageScope.GLOBAL);
|
||||
storageService.store(`${viewletId}.state`, JSON.stringify(viewsWorkspaceState), StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sidebarState.length) {
|
||||
storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { panel } = defaultLayout;
|
||||
if (panel) {
|
||||
if (panel.visible !== undefined) {
|
||||
if (panel.visible) {
|
||||
storageService.store(Storage.PANEL_HIDDEN, false, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
storageService.remove(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel.containers?.length) {
|
||||
const panelState: PanelActivityState[] = [];
|
||||
|
||||
let order = -1;
|
||||
for (const container of panel.containers.sort((a, b) => (a.order ?? 1) - (b.order ?? 1))) {
|
||||
let name;
|
||||
let panelId = container.id;
|
||||
switch (panelId) {
|
||||
case 'terminal':
|
||||
name = 'Terminal';
|
||||
panelId = 'workbench.panel.terminal';
|
||||
break;
|
||||
case 'debug':
|
||||
name = 'Debug Console';
|
||||
panelId = 'workbench.panel.repl';
|
||||
break;
|
||||
case 'problems':
|
||||
name = 'Problems';
|
||||
panelId = 'workbench.panel.markers';
|
||||
break;
|
||||
case 'output':
|
||||
name = 'Output';
|
||||
panelId = 'workbench.panel.output';
|
||||
break;
|
||||
case 'comments':
|
||||
name = 'Comments';
|
||||
panelId = 'workbench.panel.comments';
|
||||
break;
|
||||
case 'refactor':
|
||||
name = 'Refactor Preview';
|
||||
panelId = 'refactorPreview';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (container.active) {
|
||||
storageService.store(PanelPart.activePanelSettingsKey, panelId, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
if (container.order !== undefined || (container.active === undefined && container.visible !== undefined)) {
|
||||
order = container.order ?? (order + 1);
|
||||
const state: PanelActivityState = {
|
||||
id: panelId,
|
||||
name: name,
|
||||
order: order,
|
||||
pinned: (container.active || container.visible) ?? true,
|
||||
visible: (container.active || container.visible) ?? true
|
||||
};
|
||||
|
||||
panelState.push(state);
|
||||
}
|
||||
}
|
||||
|
||||
if (panelState.length) {
|
||||
storageService.store(PanelPart.PINNED_PANELS, JSON.stringify(panelState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,7 +576,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
const initialFilesToOpen = this.getInitialFilesToOpen();
|
||||
|
||||
// Only restore editors if we are not instructed to open files initially
|
||||
this.state.editor.restoreEditors = initialFilesToOpen === undefined;
|
||||
// or when `window.restoreWindows` setting is explicitly set to `preserve`
|
||||
const forceRestoreEditors = this.configurationService.getValue<string>('window.restoreWindows') === 'preserve';
|
||||
this.state.editor.restoreEditors = !!forceRestoreEditors || initialFilesToOpen === undefined;
|
||||
|
||||
// Files to open, diff or create
|
||||
if (initialFilesToOpen !== undefined) {
|
||||
@@ -996,7 +824,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
const container = this.getContainer(part);
|
||||
|
||||
return !!container && isAncestor(activeElement, container);
|
||||
return !!container && isAncestorUsingFlowTo(activeElement, container);
|
||||
}
|
||||
|
||||
focusPart(part: Parts): void {
|
||||
@@ -1050,7 +878,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
isVisible(part: Parts): boolean {
|
||||
switch (part) {
|
||||
case Parts.TITLEBAR_PART:
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'native') {
|
||||
if (getTitleBarStyle(this.configurationService) === 'native') {
|
||||
return false;
|
||||
} else if (!this.state.fullscreen && !isWeb) {
|
||||
return true;
|
||||
@@ -1246,7 +1074,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// State
|
||||
if (this.state.zenMode.active) {
|
||||
this.storageService.store(Storage.ZEN_MODE_ENABLED, true, StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.ZEN_MODE_ENABLED, true, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
|
||||
// Exit zen mode on shutdown unless configured to keep
|
||||
this.state.zenMode.transitionDisposables.add(this.storageService.onWillSaveState(e => {
|
||||
@@ -1310,6 +1138,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.container.prepend(workbenchGrid.element);
|
||||
this.container.setAttribute('role', 'application');
|
||||
this.workbenchGrid = workbenchGrid;
|
||||
this.workbenchGrid.edgeSnapping = this.state.fullscreen;
|
||||
|
||||
[titleBar, editorPart, activityBar, panelPart, sideBar, statusBar].forEach((part: Part) => {
|
||||
this._register(part.onDidVisibilityChange((visible) => {
|
||||
@@ -1331,18 +1160,18 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
? grid.getViewCachedVisibleSize(this.sideBarPartView)
|
||||
: grid.getViewSize(this.sideBarPartView).width;
|
||||
|
||||
this.storageService.store(Storage.SIDEBAR_SIZE, sideBarSize, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.SIDEBAR_SIZE, sideBarSize, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
|
||||
const panelSize = this.state.panel.hidden
|
||||
? grid.getViewCachedVisibleSize(this.panelPartView)
|
||||
: (this.state.panel.position === Position.BOTTOM ? grid.getViewSize(this.panelPartView).height : grid.getViewSize(this.panelPartView).width);
|
||||
|
||||
this.storageService.store(Storage.PANEL_SIZE, panelSize, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.PANEL_DIMENSION, positionToString(this.state.panel.position), StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.PANEL_SIZE, panelSize, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
this.storageService.store(Storage.PANEL_DIMENSION, positionToString(this.state.panel.position), StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
|
||||
const gridSize = grid.getViewSize();
|
||||
this.storageService.store(Storage.GRID_WIDTH, gridSize.width, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.GRID_HEIGHT, gridSize.height, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.GRID_WIDTH, gridSize.width, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
this.storageService.store(Storage.GRID_HEIGHT, gridSize.height, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1373,7 +1202,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
centerEditorLayout(active: boolean, skipLayout?: boolean): void {
|
||||
this.state.editor.centered = active;
|
||||
|
||||
this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
|
||||
let smartActive = active;
|
||||
const activeEditor = this.editorService.activeEditor;
|
||||
@@ -1486,7 +1315,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Remember in settings
|
||||
if (hidden) {
|
||||
this.storageService.store(Storage.EDITOR_HIDDEN, true, StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.EDITOR_HIDDEN, true, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
} else {
|
||||
this.storageService.remove(Storage.EDITOR_HIDDEN, StorageScope.WORKSPACE);
|
||||
}
|
||||
@@ -1547,7 +1376,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
// Remember in settings
|
||||
const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY;
|
||||
if (hidden !== defaultHidden) {
|
||||
this.storageService.store(Storage.SIDEBAR_HIDDEN, hidden ? 'true' : 'false', StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.SIDEBAR_HIDDEN, hidden ? 'true' : 'false', StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
} else {
|
||||
this.storageService.remove(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE);
|
||||
}
|
||||
@@ -1612,14 +1441,14 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
// Remember in settings
|
||||
if (!hidden) {
|
||||
this.storageService.store(Storage.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
}
|
||||
else {
|
||||
this.storageService.remove(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE);
|
||||
|
||||
// Remember this setting only when panel is hiding
|
||||
if (this.state.panel.wasLastMaximized) {
|
||||
this.storageService.store(Storage.PANEL_LAST_IS_MAXIMIZED, true, StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.PANEL_LAST_IS_MAXIMIZED, true, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
}
|
||||
else {
|
||||
this.storageService.remove(Storage.PANEL_LAST_IS_MAXIMIZED, StorageScope.WORKSPACE);
|
||||
@@ -1637,10 +1466,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
if (!this.state.panel.hidden) {
|
||||
if (this.state.panel.position === Position.BOTTOM) {
|
||||
this.state.panel.lastNonMaximizedHeight = size.height;
|
||||
this.storageService.store(Storage.PANEL_LAST_NON_MAXIMIZED_HEIGHT, this.state.panel.lastNonMaximizedHeight, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.PANEL_LAST_NON_MAXIMIZED_HEIGHT, this.state.panel.lastNonMaximizedHeight, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
} else {
|
||||
this.state.panel.lastNonMaximizedWidth = size.width;
|
||||
this.storageService.store(Storage.PANEL_LAST_NON_MAXIMIZED_WIDTH, this.state.panel.lastNonMaximizedWidth, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.PANEL_LAST_NON_MAXIMIZED_WIDTH, this.state.panel.lastNonMaximizedWidth, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1715,7 +1544,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.state.panel.position = position;
|
||||
|
||||
// Save panel position
|
||||
this.storageService.store(Storage.PANEL_POSITION, newPositionValue, StorageScope.WORKSPACE);
|
||||
this.storageService.store(Storage.PANEL_POSITION, newPositionValue, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
|
||||
// Adjust CSS
|
||||
const panelContainer = assertIsDefined(panelPart.getContainer());
|
||||
|
||||
@@ -220,6 +220,10 @@ body.web {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.monaco-workbench input[type="checkbox"]:focus {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.monaco-workbench [tabindex="0"]:active,
|
||||
.monaco-workbench [tabindex="-1"]:active,
|
||||
.monaco-workbench select:active,
|
||||
|
||||
@@ -10,15 +10,14 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { Action, IAction, Separator, SubmenuAction } from 'vs/base/common/actions';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { SyncActionDescriptor, IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IMenuService, MenuId, IMenu, registerAction2, Action2, IAction2Options } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ActivityAction, ActivityActionViewItem, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { CATEGORIES, Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
|
||||
@@ -26,44 +25,31 @@ 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 { Codicon } from 'vs/base/common/codicons';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { isMacintosh, isWeb } from 'vs/base/common/platform';
|
||||
import { getCurrentAuthenticationSessionInfo, IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { AuthenticationSession } from 'vs/editor/common/modes';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { AnchorAlignment, AnchorAxisAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export class ViewContainerActivityAction extends ActivityAction {
|
||||
|
||||
private static readonly preventDoubleClickDelay = 300;
|
||||
|
||||
private readonly viewletService: IViewletService;
|
||||
private readonly layoutService: IWorkbenchLayoutService;
|
||||
private readonly telemetryService: ITelemetryService;
|
||||
private readonly configurationService: IConfigurationService;
|
||||
|
||||
private lastRun: number;
|
||||
private lastRun = 0;
|
||||
|
||||
constructor(
|
||||
activity: IActivity,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(activity);
|
||||
|
||||
this.lastRun = 0;
|
||||
this.viewletService = viewletService;
|
||||
this.layoutService = layoutService;
|
||||
this.telemetryService = telemetryService;
|
||||
this.configurationService = configurationService;
|
||||
}
|
||||
|
||||
updateActivity(activity: IActivity): void {
|
||||
@@ -105,6 +91,7 @@ export class ViewContainerActivityAction extends ActivityAction {
|
||||
|
||||
this.logAction('show');
|
||||
await this.viewletService.openViewlet(this.activity.id, true);
|
||||
|
||||
return this.activate();
|
||||
}
|
||||
|
||||
@@ -117,21 +104,18 @@ export class ViewContainerActivityAction extends ActivityAction {
|
||||
}
|
||||
}
|
||||
|
||||
export const ACCOUNTS_VISIBILITY_PREFERENCE_KEY = 'workbench.activity.showAccounts';
|
||||
class MenuActivityActionViewItem extends ActivityActionViewItem {
|
||||
|
||||
export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
constructor(
|
||||
private readonly menuId: MenuId,
|
||||
action: ActivityAction,
|
||||
colors: (theme: IColorTheme) => ICompositeBarColors,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService protected contextMenuService: IContextMenuService,
|
||||
@IMenuService protected menuService: IMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IAuthenticationService private readonly authenticationService: IAuthenticationService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IMenuService protected readonly menuService: IMenuService,
|
||||
@IContextMenuService protected readonly contextMenuService: IContextMenuService,
|
||||
@IContextKeyService protected readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService protected readonly configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
super(action, { draggable: false, colors, icon: true }, themeService);
|
||||
}
|
||||
@@ -161,12 +145,103 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
}));
|
||||
}
|
||||
|
||||
private async getActions(accountsMenu: IMenu) {
|
||||
protected async showContextMenu(e?: MouseEvent): Promise<void> {
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const menu = disposables.add(this.menuService.createMenu(this.menuId, this.contextKeyService));
|
||||
const actions = await this.resolveActions(menu, disposables);
|
||||
|
||||
const isUsingCustomMenu = isWeb || (getTitleBarStyle(this.configurationService) !== 'native' && !isMacintosh); // see #40262
|
||||
const position = this.configurationService.getValue('workbench.sideBar.location');
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => isUsingCustomMenu ? this.container : e || this.container,
|
||||
anchorAlignment: isUsingCustomMenu ? (position === 'left' ? AnchorAlignment.RIGHT : AnchorAlignment.LEFT) : undefined,
|
||||
anchorAxisAlignment: isUsingCustomMenu ? AnchorAxisAlignment.HORIZONTAL : AnchorAxisAlignment.VERTICAL,
|
||||
getActions: () => actions,
|
||||
onHide: () => disposables.dispose()
|
||||
});
|
||||
}
|
||||
|
||||
protected async resolveActions(menu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
|
||||
const actions: IAction[] = [];
|
||||
|
||||
disposables.add(createAndFillInActionBarActions(menu, undefined, { primary: [], secondary: actions }));
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
export class HomeActivityActionViewItem extends MenuActivityActionViewItem {
|
||||
|
||||
static readonly HOME_BAR_VISIBILITY_PREFERENCE = 'workbench.activity.showHomeIndicator';
|
||||
|
||||
constructor(
|
||||
private readonly goHomeHref: string,
|
||||
action: ActivityAction,
|
||||
colors: (theme: IColorTheme) => ICompositeBarColors,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
) {
|
||||
super(MenuId.MenubarHomeMenu, action, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
|
||||
}
|
||||
|
||||
protected async resolveActions(homeMenu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
|
||||
const actions = [];
|
||||
|
||||
// Go Home
|
||||
actions.push(disposables.add(new Action('goHome', nls.localize('goHome', "Go Home"), undefined, true, async () => window.location.href = this.goHomeHref)));
|
||||
actions.push(disposables.add(new Separator()));
|
||||
|
||||
// Contributed
|
||||
const contributedActions = await super.resolveActions(homeMenu, disposables);
|
||||
actions.push(...contributedActions);
|
||||
|
||||
// Hide
|
||||
if (contributedActions.length > 0) {
|
||||
actions.push(disposables.add(new Separator()));
|
||||
}
|
||||
actions.push(disposables.add(new Action('hide', nls.localize('hide', "Hide"), undefined, true, async () => {
|
||||
this.storageService.store(HomeActivityActionViewItem.HOME_BAR_VISIBILITY_PREFERENCE, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
})));
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountsActivityActionViewItem extends MenuActivityActionViewItem {
|
||||
|
||||
static readonly ACCOUNTS_VISIBILITY_PREFERENCE_KEY = 'workbench.activity.showAccounts';
|
||||
|
||||
constructor(
|
||||
action: ActivityAction,
|
||||
colors: (theme: IColorTheme) => ICompositeBarColors,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IAuthenticationService private readonly authenticationService: IAuthenticationService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
) {
|
||||
super(MenuId.AccountsContext, action, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
|
||||
}
|
||||
|
||||
protected async resolveActions(accountsMenu: IMenu, disposables: DisposableStore): Promise<IAction[]> {
|
||||
await super.resolveActions(accountsMenu, disposables);
|
||||
|
||||
const otherCommands = accountsMenu.getActions();
|
||||
const providers = this.authenticationService.getProviderIds();
|
||||
const allSessions = providers.map(async id => {
|
||||
const allSessions = providers.map(async providerId => {
|
||||
try {
|
||||
const sessions = await this.authenticationService.getSessions(id);
|
||||
const sessions = await this.authenticationService.getSessions(providerId);
|
||||
|
||||
const groupedSessions: { [label: string]: AuthenticationSession[] } = {};
|
||||
sessions.forEach(session => {
|
||||
@@ -177,14 +252,9 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
providerId: id,
|
||||
sessions: groupedSessions
|
||||
};
|
||||
return { providerId, sessions: groupedSessions };
|
||||
} catch {
|
||||
return {
|
||||
providerId: id
|
||||
};
|
||||
return { providerId };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -196,132 +266,67 @@ export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
|
||||
if (sessionInfo.sessions) {
|
||||
Object.keys(sessionInfo.sessions).forEach(accountName => {
|
||||
const hasEmbedderAccountSession = sessionInfo.sessions[accountName].some(session => session.id === (authenticationSession?.id));
|
||||
const manageExtensionsAction = new Action(`configureSessions${accountName}`, nls.localize('manageTrustedExtensions', "Manage Trusted Extensions"), '', true, _ => {
|
||||
const manageExtensionsAction = disposables.add(new Action(`configureSessions${accountName}`, nls.localize('manageTrustedExtensions', "Manage Trusted Extensions"), '', true, () => {
|
||||
return this.authenticationService.manageTrustedExtensionsForAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
const signOutAction = new Action('signOut', nls.localize('signOut', "Sign Out"), '', true, _ => {
|
||||
return this.authenticationService.signOutOfAccount(sessionInfo.providerId, accountName);
|
||||
});
|
||||
}));
|
||||
|
||||
const actions = [manageExtensionsAction];
|
||||
const signOutAction = disposables.add(new Action('signOut', nls.localize('signOut', "Sign Out"), '', true, () => {
|
||||
return this.authenticationService.signOutOfAccount(sessionInfo.providerId, accountName);
|
||||
}));
|
||||
|
||||
const providerSubMenuActions = [manageExtensionsAction];
|
||||
|
||||
const hasEmbedderAccountSession = sessionInfo.sessions[accountName].some(session => session.id === (authenticationSession?.id));
|
||||
if (!hasEmbedderAccountSession || authenticationSession?.canSignOut) {
|
||||
actions.push(signOutAction);
|
||||
providerSubMenuActions.push(signOutAction);
|
||||
}
|
||||
|
||||
const menu = new SubmenuAction('activitybar.submenu', `${accountName} (${providerDisplayName})`, actions);
|
||||
menus.push(menu);
|
||||
const providerSubMenu = disposables.add(new SubmenuAction('activitybar.submenu', `${accountName} (${providerDisplayName})`, providerSubMenuActions));
|
||||
menus.push(providerSubMenu);
|
||||
});
|
||||
} else {
|
||||
const menu = new Action('providerUnavailable', nls.localize('authProviderUnavailable', '{0} is currently unavailable', providerDisplayName));
|
||||
menus.push(menu);
|
||||
const providerUnavailableAction = disposables.add(new Action('providerUnavailable', nls.localize('authProviderUnavailable', '{0} is currently unavailable', providerDisplayName)));
|
||||
menus.push(providerUnavailableAction);
|
||||
}
|
||||
});
|
||||
|
||||
if (menus.length && otherCommands.length) {
|
||||
menus.push(new Separator());
|
||||
menus.push(disposables.add(new Separator()));
|
||||
}
|
||||
|
||||
otherCommands.forEach((group, i) => {
|
||||
const actions = group[1];
|
||||
menus = menus.concat(actions);
|
||||
if (i !== otherCommands.length - 1) {
|
||||
menus.push(new Separator());
|
||||
menus.push(disposables.add(new Separator()));
|
||||
}
|
||||
});
|
||||
|
||||
if (menus.length) {
|
||||
menus.push(new Separator());
|
||||
menus.push(disposables.add(new Separator()));
|
||||
}
|
||||
|
||||
menus.push(new Action('hide', nls.localize('hide', "Hide"), undefined, true, _ => {
|
||||
this.storageService.store(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, false, StorageScope.GLOBAL);
|
||||
return Promise.resolve();
|
||||
}));
|
||||
menus.push(disposables.add(new Action('hide', nls.localize('hide', "Hide"), undefined, true, async () => {
|
||||
this.storageService.store(AccountsActivityActionViewItem.ACCOUNTS_VISIBILITY_PREFERENCE_KEY, false, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
})));
|
||||
|
||||
return menus;
|
||||
}
|
||||
|
||||
private async showContextMenu(e?: MouseEvent): Promise<void> {
|
||||
const accountsActions: IAction[] = [];
|
||||
const accountsMenu = this.menuService.createMenu(MenuId.AccountsContext, this.contextKeyService);
|
||||
const actionsDisposable = createAndFillInActionBarActions(accountsMenu, undefined, { primary: [], secondary: accountsActions });
|
||||
const native = getTitleBarStyle(this.configurationService, this.environmentService) === 'native';
|
||||
const position = this.configurationService.getValue('workbench.sideBar.location');
|
||||
|
||||
const containerPosition = DOM.getDomNodePagePosition(this.container);
|
||||
const location = { x: containerPosition.left + (position === 'left' ? containerPosition.width : 0), y: containerPosition.top };
|
||||
const actions = await this.getActions(accountsMenu);
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => !native ? location : e || this.container,
|
||||
anchorAlignment: !native ? (position === 'left' ? AnchorAlignment.RIGHT : AnchorAlignment.LEFT) : undefined,
|
||||
getActions: () => actions,
|
||||
onHide: () => {
|
||||
accountsMenu.dispose();
|
||||
dispose(actionsDisposable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class GlobalActivityActionViewItem extends ActivityActionViewItem {
|
||||
export class GlobalActivityActionViewItem extends MenuActivityActionViewItem {
|
||||
|
||||
constructor(
|
||||
action: ActivityAction,
|
||||
colors: (theme: IColorTheme) => ICompositeBarColors,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IContextMenuService protected readonly contextMenuService: IContextMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
super(action, { draggable: false, colors, icon: true }, themeService);
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
|
||||
// Context menus are triggered on mouse down so that an item can be picked
|
||||
// and executed with releasing the mouse over it
|
||||
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this.showContextMenu(e);
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this.showContextMenu();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this.container, TouchEventType.Tap, (e: GestureEvent) => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this.showContextMenu();
|
||||
}));
|
||||
}
|
||||
|
||||
private showContextMenu(e?: MouseEvent): void {
|
||||
const globalActivityActions: IAction[] = [];
|
||||
const globalActivityMenu = this.menuService.createMenu(MenuId.GlobalActivity, this.contextKeyService);
|
||||
const actionsDisposable = createAndFillInActionBarActions(globalActivityMenu, undefined, { primary: [], secondary: globalActivityActions });
|
||||
const native = getTitleBarStyle(this.configurationService, this.environmentService) === 'native';
|
||||
const position = this.configurationService.getValue('workbench.sideBar.location');
|
||||
|
||||
const containerPosition = DOM.getDomNodePagePosition(this.container);
|
||||
const location = { x: containerPosition.left + (position === 'left' ? containerPosition.width : 0), y: containerPosition.top + containerPosition.height };
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => !native ? location : e || this.container,
|
||||
anchorAlignment: !native ? (position === 'left' ? AnchorAlignment.RIGHT : AnchorAlignment.LEFT) : undefined,
|
||||
getActions: () => globalActivityActions,
|
||||
onHide: () => {
|
||||
globalActivityMenu.dispose();
|
||||
dispose(actionsDisposable);
|
||||
}
|
||||
});
|
||||
super(MenuId.GlobalActivity, action, colors, themeService, menuService, contextMenuService, contextKeyService, configurationService, environmentService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,106 +343,62 @@ export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinne
|
||||
}
|
||||
}
|
||||
|
||||
class SwitchSideBarViewAction extends Action {
|
||||
class SwitchSideBarViewAction extends Action2 {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IActivityBarService private readonly activityBarService: IActivityBarService
|
||||
desc: Readonly<IAction2Options>,
|
||||
private readonly offset: number
|
||||
) {
|
||||
super(id, name);
|
||||
super(desc);
|
||||
}
|
||||
|
||||
async run(offset: number): Promise<void> {
|
||||
const visibleViewletIds = this.activityBarService.getVisibleViewContainerIds();
|
||||
async run(accessor: ServicesAccessor): Promise<void> {
|
||||
const activityBarService = accessor.get(IActivityBarService);
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
const visibleViewletIds = activityBarService.getVisibleViewContainerIds();
|
||||
|
||||
const activeViewlet = viewletService.getActiveViewlet();
|
||||
if (!activeViewlet) {
|
||||
return;
|
||||
}
|
||||
let targetViewletId: string | undefined;
|
||||
for (let i = 0; i < visibleViewletIds.length; i++) {
|
||||
if (visibleViewletIds[i] === activeViewlet.getId()) {
|
||||
targetViewletId = visibleViewletIds[(i + visibleViewletIds.length + offset) % visibleViewletIds.length];
|
||||
targetViewletId = visibleViewletIds[(i + visibleViewletIds.length + this.offset) % visibleViewletIds.length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await this.viewletService.openViewlet(targetViewletId, true);
|
||||
await viewletService.openViewlet(targetViewletId, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousSideBarViewAction extends SwitchSideBarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.previousSideBarView';
|
||||
static readonly LABEL = nls.localize('previousSideBarView', 'Previous Side Bar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityBarService activityBarService: IActivityBarService
|
||||
) {
|
||||
super(id, name, viewletService, activityBarService);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export class NextSideBarViewAction extends SwitchSideBarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.nextSideBarView';
|
||||
static readonly LABEL = nls.localize('nextSideBarView', 'Next Side Bar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityBarService activityBarService: IActivityBarService
|
||||
) {
|
||||
super(id, name, viewletService, activityBarService);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
export class HomeAction extends Action {
|
||||
|
||||
constructor(
|
||||
private readonly href: string,
|
||||
name: string,
|
||||
icon: Codicon
|
||||
) {
|
||||
super('workbench.action.home', name, icon.classNames);
|
||||
}
|
||||
|
||||
async run(event: MouseEvent): Promise<void> {
|
||||
let openInNewWindow = false;
|
||||
if (isMacintosh) {
|
||||
openInNewWindow = event.metaKey;
|
||||
} else {
|
||||
openInNewWindow = event.ctrlKey;
|
||||
}
|
||||
|
||||
if (openInNewWindow) {
|
||||
DOM.windowOpenNoOpener(this.href);
|
||||
} else {
|
||||
window.location.href = this.href;
|
||||
registerAction2(
|
||||
class PreviousSideBarViewAction extends SwitchSideBarViewAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.action.previousSideBarView',
|
||||
title: { value: nls.localize('previousSideBarView', "Previous Side Bar View"), original: 'Previous Side Bar View' },
|
||||
category: CATEGORIES.View,
|
||||
f1: true
|
||||
}, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export class HomeActionViewItem extends ActionViewItem {
|
||||
|
||||
constructor(action: IAction) {
|
||||
super(undefined, action, { icon: true, label: false, useEventAsContext: true });
|
||||
registerAction2(
|
||||
class NextSideBarViewAction extends SwitchSideBarViewAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.action.nextSideBarView',
|
||||
title: { value: nls.localize('nextSideBarView', "Next Side Bar View"), original: 'Next Side Bar View' },
|
||||
category: CATEGORIES.View,
|
||||
f1: true
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
|
||||
const activityBarBackgroundColor = theme.getColor(ACTIVITY_BAR_BACKGROUND);
|
||||
@@ -510,6 +471,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
|
||||
left: 9px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active:before,
|
||||
@@ -549,7 +511,3 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(PreviousSideBarViewAction), 'View: Previous Side Bar View', CATEGORIES.View.value);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(NextSideBarViewAction), 'View: Next Side Bar View', CATEGORIES.View.value);
|
||||
|
||||
@@ -8,24 +8,24 @@ import * as nls from 'vs/nls';
|
||||
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { GLOBAL_ACTIVITY_ID, IActivity, ACCOUNTS_ACTIVITY_ID } from 'vs/workbench/common/activity';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { GlobalActivityActionViewItem, ViewContainerActivityAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewContainerActivityAction, AccountsActionViewItem, HomeAction, HomeActionViewItem, ACCOUNTS_VISIBILITY_PREFERENCE_KEY } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
|
||||
import { GlobalActivityActionViewItem, ViewContainerActivityAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewContainerActivityAction, AccountsActivityActionViewItem, HomeActivityActionViewItem } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
|
||||
import { IBadge, NumberBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ToggleActivityBarVisibilityAction, ToggleMenuBarAction, ToggleSidebarPositionAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
|
||||
import { IThemeService, IColorTheme, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BORDER } from 'vs/workbench/common/theme';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar, ICompositeBarItem, CompositeDragAndDrop } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { Dimension, createCSSRule, asCSSUrl, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { IViewDescriptorService, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewContainerModel, ViewContainerLocation, IViewsService } from 'vs/workbench/common/views';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { isUndefinedOrNull, assertIsDefined, isString } from 'vs/base/common/types';
|
||||
import { assertIsDefined } 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';
|
||||
@@ -34,7 +34,6 @@ 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 { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Before2D } from 'vs/workbench/browser/dnd';
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { Action, Separator } from 'vs/base/common/actions';
|
||||
@@ -43,41 +42,45 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Action2, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
|
||||
interface IPlaceholderViewContainer {
|
||||
id: string;
|
||||
name?: string;
|
||||
iconUrl?: UriComponents;
|
||||
iconCSS?: string;
|
||||
views?: { when?: string }[];
|
||||
readonly id: string;
|
||||
readonly name?: string;
|
||||
readonly iconUrl?: UriComponents;
|
||||
readonly themeIcon?: ThemeIcon;
|
||||
readonly views?: { when?: string }[];
|
||||
}
|
||||
|
||||
interface IPinnedViewContainer {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order?: number;
|
||||
visible: boolean;
|
||||
readonly id: string;
|
||||
readonly pinned: boolean;
|
||||
readonly order?: number;
|
||||
readonly visible: boolean;
|
||||
}
|
||||
|
||||
interface ICachedViewContainer {
|
||||
id: string;
|
||||
readonly id: string;
|
||||
name?: string;
|
||||
icon?: URI | string;
|
||||
pinned: boolean;
|
||||
order?: number;
|
||||
icon?: URI | ThemeIcon;
|
||||
readonly pinned: boolean;
|
||||
readonly order?: number;
|
||||
visible: boolean;
|
||||
views?: { when?: string }[];
|
||||
}
|
||||
|
||||
const settingsViewBarIcon = registerIcon('settings-view-bar-icon', Codicon.settingsGear, nls.localize('settingsViewBarIcon', 'Settings icon in the view bar.'));
|
||||
const accountsViewBarIcon = registerIcon('accounts-view-bar-icon', Codicon.account, nls.localize('accountsViewBarIcon', 'Accounts icon in the view bar.'));
|
||||
|
||||
export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
static readonly PINNED_VIEW_CONTAINERS = 'workbench.activity.pinnedViewlets2';
|
||||
private static readonly PINNED_VIEW_CONTAINERS = 'workbench.activity.pinnedViewlets2';
|
||||
private static readonly PLACEHOLDER_VIEW_CONTAINERS = 'workbench.activity.placeholderViewlets';
|
||||
private static readonly HOME_BAR_VISIBILITY_PREFERENCE = 'workbench.activity.showHomeIndicator';
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
private static readonly ACCOUNTS_ACTION_INDEX = 0;
|
||||
|
||||
//#region IView
|
||||
|
||||
readonly minimumWidth: number = 48;
|
||||
@@ -100,17 +103,17 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
private globalActivityAction: ActivityAction | undefined;
|
||||
private globalActivityActionBar: ActionBar | undefined;
|
||||
private readonly globalActivity: ICompositeActivity[] = [];
|
||||
private globalActivitiesContainer: HTMLElement | undefined;
|
||||
private readonly globalActivity: ICompositeActivity[] = [];
|
||||
|
||||
private accountsActivityAction: ActivityAction | undefined;
|
||||
|
||||
private accountsActivity: ICompositeActivity[] = [];
|
||||
private readonly accountsActivity: ICompositeActivity[] = [];
|
||||
|
||||
private readonly compositeActions = new Map<string, { activityAction: ViewContainerActivityAction, pinnedAction: ToggleCompositePinnedAction }>();
|
||||
private readonly viewContainerDisposables = new Map<string, IDisposable>();
|
||||
|
||||
private readonly keyboardNavigationDisposables = new DisposableStore();
|
||||
private readonly keyboardNavigationDisposables = this._register(new DisposableStore());
|
||||
|
||||
private readonly location = ViewContainerLocation.Sidebar;
|
||||
|
||||
@@ -125,27 +128,36 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super(Parts.ACTIVITYBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.PINNED_VIEW_CONTAINERS, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, version: 1 });
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ACCOUNTS_VISIBILITY_PREFERENCE_KEY, version: 1 });
|
||||
|
||||
this.migrateFromOldCachedViewContainersValue();
|
||||
|
||||
for (const cachedViewContainer of this.cachedViewContainers) {
|
||||
if (environmentService.remoteAuthority // In remote window, hide activity bar entries until registered.
|
||||
|| this.shouldBeHidden(cachedViewContainer.id, cachedViewContainer)
|
||||
if (
|
||||
environmentService.remoteAuthority || // In remote window, hide activity bar entries until registered
|
||||
this.shouldBeHidden(cachedViewContainer.id, cachedViewContainer)
|
||||
) {
|
||||
cachedViewContainer.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.compositeBar = this.createCompositeBar();
|
||||
|
||||
this.onDidRegisterViewContainers(this.getViewContainers());
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private createCompositeBar() {
|
||||
const cachedItems = this.cachedViewContainers
|
||||
.map(v => ({ id: v.id, name: v.name, visible: v.visible, order: v.order, pinned: v.pinned }));
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, cachedItems, {
|
||||
.map(container => ({
|
||||
id: container.id,
|
||||
name: container.name,
|
||||
visible: container.visible,
|
||||
order: container.order,
|
||||
pinned: container.pinned
|
||||
}));
|
||||
|
||||
return this._register(this.instantiationService.createInstance(CompositeBar, cachedItems, {
|
||||
icon: true,
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
preventLoopNavigation: true,
|
||||
@@ -154,8 +166,9 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction,
|
||||
getOnCompositeClickAction: (compositeId: string) => new Action(compositeId, '', '', true, () => this.viewsService.isViewContainerVisible(compositeId) ? Promise.resolve(this.viewsService.closeViewContainer(compositeId)) : this.viewsService.openViewContainer(compositeId)),
|
||||
getContextMenuActions: () => {
|
||||
const menuBarVisibility = getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
const actions = [];
|
||||
|
||||
// Home
|
||||
if (this.homeBarContainer) {
|
||||
actions.push(new Action(
|
||||
'toggleHomeBarAction',
|
||||
@@ -166,22 +179,26 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
));
|
||||
}
|
||||
|
||||
// Menu
|
||||
const menuBarVisibility = getMenuBarVisibility(this.configurationService);
|
||||
if (menuBarVisibility === 'compact' || (menuBarVisibility === 'hidden' && isWeb)) {
|
||||
actions.push(this.instantiationService.createInstance(ToggleMenuBarAction, ToggleMenuBarAction.ID, menuBarVisibility === 'compact' ? nls.localize('hideMenu', "Hide Menu") : nls.localize('showMenu', "Show Menu")));
|
||||
}
|
||||
|
||||
const toggleAccountsVisibilityAction = new Action(
|
||||
// Accounts
|
||||
actions.push(new Action(
|
||||
'toggleAccountsVisibility',
|
||||
this.accountsVisibilityPreference ? nls.localize('hideAccounts', "Hide Accounts") : nls.localize('showAccounts', "Show Accounts"),
|
||||
undefined,
|
||||
true,
|
||||
async () => { this.accountsVisibilityPreference = !this.accountsVisibilityPreference; }
|
||||
);
|
||||
|
||||
actions.push(toggleAccountsVisibilityAction);
|
||||
));
|
||||
actions.push(new Separator());
|
||||
|
||||
// Toggle Sidebar
|
||||
actions.push(this.instantiationService.createInstance(ToggleSidebarPositionAction, ToggleSidebarPositionAction.ID, ToggleSidebarPositionAction.getLabel(this.layoutService)));
|
||||
|
||||
// Toggle Activity Bar
|
||||
actions.push(new Action(
|
||||
ToggleActivityBarVisibilityAction.ID,
|
||||
nls.localize('hideActivitBar', "Hide Activity Bar"),
|
||||
@@ -204,19 +221,12 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
colors: (theme: IColorTheme) => this.getActivitybarItemColors(theme),
|
||||
overflowActionSize: ActivitybarPart.ACTION_HEIGHT
|
||||
}));
|
||||
|
||||
this.onDidRegisterViewContainers(this.getViewContainers());
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
focusActivityBar(): void {
|
||||
this.compositeBar.focus();
|
||||
}
|
||||
|
||||
private getContextMenuActionsForComposite(compositeId: string): Action[] {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(compositeId)!;
|
||||
|
||||
const actions = [];
|
||||
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(compositeId)!;
|
||||
const defaultLocation = this.viewDescriptorService.getDefaultViewContainerLocation(viewContainer)!;
|
||||
if (defaultLocation !== this.viewDescriptorService.getViewContainerLocation(viewContainer)) {
|
||||
actions.push(new Action('resetLocationAction', nls.localize('resetLocation', "Reset Location"), undefined, true, async () => {
|
||||
@@ -253,13 +263,13 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedViewContainers(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
// Register for configuration changes
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('window.menuBarVisibility')) {
|
||||
if (getMenuBarVisibility(this.configurationService, this.environmentService) === 'compact') {
|
||||
if (getMenuBarVisibility(this.configurationService) === 'compact') {
|
||||
this.installMenubar();
|
||||
} else {
|
||||
this.uninstallMenubar();
|
||||
@@ -277,6 +287,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
if (from === this.location) {
|
||||
this.onDidDeregisterViewContainer(container);
|
||||
}
|
||||
|
||||
if (to === this.location) {
|
||||
this.onDidRegisterViewContainers([container]);
|
||||
}
|
||||
@@ -306,6 +317,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
private onDidViewContainerVisible(id: string): void {
|
||||
const viewContainer = this.getViewContainer(id);
|
||||
if (viewContainer) {
|
||||
|
||||
// Update the composite bar by adding
|
||||
this.compositeBar.addComposite(viewContainer);
|
||||
this.compositeBar.activateComposite(viewContainer.id);
|
||||
@@ -313,7 +325,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
if (viewContainer.hideIfEmpty) {
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
if (viewContainerModel.activeViewDescriptors.length === 0) {
|
||||
this.hideComposite(viewContainer.id); // Update the composite bar by hiding
|
||||
// Update the composite bar by hiding
|
||||
this.hideComposite(viewContainer.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,6 +352,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
if (typeof priority !== 'number') {
|
||||
priority = 0;
|
||||
}
|
||||
|
||||
const activity: ICompositeActivity = { badge, clazz, priority };
|
||||
const activityCache = activityId === GLOBAL_ACTIVITY_ID ? this.globalActivity : this.accountsActivity;
|
||||
|
||||
@@ -387,16 +401,18 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
private getCumulativeNumberBadge(activityCache: ICompositeActivity[], priority: number): NumberBadge {
|
||||
const numberActivities = activityCache.filter(activity => activity.badge instanceof NumberBadge && activity.priority === priority);
|
||||
let number = numberActivities.reduce((result, activity) => { return result + (<NumberBadge>activity.badge).number; }, 0);
|
||||
let descriptorFn = (): string => {
|
||||
const number = numberActivities.reduce((result, activity) => { return result + (<NumberBadge>activity.badge).number; }, 0);
|
||||
const descriptorFn = (): string => {
|
||||
return numberActivities.reduce((result, activity, index) => {
|
||||
result = result + (<NumberBadge>activity.badge).getDescription();
|
||||
if (index < numberActivities.length - 1) {
|
||||
result = result + '\n';
|
||||
result = `${result}\n`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}, '');
|
||||
};
|
||||
|
||||
return new NumberBadge(number, descriptorFn);
|
||||
}
|
||||
|
||||
@@ -414,11 +430,19 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private installMenubar() {
|
||||
if (this.menuBar) {
|
||||
return; // prevent menu bar from installing twice #110720
|
||||
}
|
||||
|
||||
this.menuBarContainer = document.createElement('div');
|
||||
this.menuBarContainer.classList.add('menubar');
|
||||
|
||||
const content = assertIsDefined(this.content);
|
||||
content.prepend(this.menuBarContainer);
|
||||
if (this.homeBarContainer) {
|
||||
content.insertBefore(this.menuBarContainer, this.homeBarContainer.nextSibling);
|
||||
} else {
|
||||
content.prepend(this.menuBarContainer);
|
||||
}
|
||||
|
||||
// Menubar: install a custom menu bar depending on configuration
|
||||
this.menuBar = this._register(this.instantiationService.createInstance(CustomMenubarControl));
|
||||
@@ -442,12 +466,12 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
codicon = Codicon.code;
|
||||
}
|
||||
|
||||
this.createHomeBar(homeIndicator.href, homeIndicator.title, codicon);
|
||||
this.createHomeBar(homeIndicator.href, codicon);
|
||||
this.onDidChangeHomeBarVisibility();
|
||||
}
|
||||
|
||||
// Install menubar if compact
|
||||
if (getMenuBarVisibility(this.configurationService, this.environmentService) === 'compact') {
|
||||
if (getMenuBarVisibility(this.configurationService) === 'compact') {
|
||||
this.installMenubar();
|
||||
}
|
||||
|
||||
@@ -456,11 +480,11 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
// Global action bar
|
||||
this.globalActivitiesContainer = document.createElement('div');
|
||||
this.globalActivitiesContainer.classList.add('global-activity');
|
||||
this.content.appendChild(this.globalActivitiesContainer);
|
||||
|
||||
this.createGlobalActivityActionBar(this.globalActivitiesContainer);
|
||||
|
||||
// Keyboard Navigation
|
||||
this.registerKeyboardNavigationListeners();
|
||||
|
||||
return this.content;
|
||||
@@ -528,23 +552,19 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private createHomeBar(href: string, title: string, icon: Codicon): void {
|
||||
private createHomeBar(href: string, icon: Codicon): void {
|
||||
this.homeBarContainer = document.createElement('div');
|
||||
this.homeBarContainer.setAttribute('aria-label', nls.localize('homeIndicator', "Home"));
|
||||
this.homeBarContainer.setAttribute('role', 'toolbar');
|
||||
this.homeBarContainer.classList.add('home-bar');
|
||||
|
||||
this.homeBar = this._register(new ActionBar(this.homeBarContainer, {
|
||||
actionViewItemProvider: action => this.instantiationService.createInstance(HomeActivityActionViewItem, href, action as ActivityAction, (theme: IColorTheme) => this.getActivitybarItemColors(theme)),
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
animated: false,
|
||||
ariaLabel: nls.localize('home', "Home"),
|
||||
actionViewItemProvider: action => new HomeActionViewItem(action),
|
||||
allowContextMenu: true,
|
||||
animated: false,
|
||||
preventLoopNavigation: true,
|
||||
ignoreOrientationForPreviousAndNextKey: true
|
||||
}));
|
||||
@@ -552,35 +572,15 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
const homeBarIconBadge = document.createElement('div');
|
||||
homeBarIconBadge.classList.add('home-bar-icon-badge');
|
||||
this.homeBarContainer.appendChild(homeBarIconBadge);
|
||||
this.homeBar.push(this._register(this.instantiationService.createInstance(HomeAction, href, title, icon)));
|
||||
|
||||
this.homeBar.push(this._register(new ActivityAction({
|
||||
id: 'workbench.actions.home',
|
||||
name: nls.localize('home', "Home"),
|
||||
cssClass: icon.classNames
|
||||
})));
|
||||
|
||||
const content = assertIsDefined(this.content);
|
||||
content.prepend(this.homeBarContainer);
|
||||
}
|
||||
|
||||
updateStyles(): void {
|
||||
super.updateStyles();
|
||||
|
||||
const container = assertIsDefined(this.getContainer());
|
||||
const background = this.getColor(ACTIVITY_BAR_BACKGROUND) || '';
|
||||
container.style.backgroundColor = background;
|
||||
|
||||
const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder) || '';
|
||||
container.classList.toggle('bordered', !!borderColor);
|
||||
container.style.borderColor = borderColor ? borderColor : '';
|
||||
}
|
||||
|
||||
private getActivitybarItemColors(theme: IColorTheme): ICompositeBarColors {
|
||||
return {
|
||||
activeForegroundColor: theme.getColor(ACTIVITY_BAR_FOREGROUND),
|
||||
inactiveForegroundColor: theme.getColor(ACTIVITY_BAR_INACTIVE_FOREGROUND),
|
||||
activeBorderColor: theme.getColor(ACTIVITY_BAR_ACTIVE_BORDER),
|
||||
activeBackground: theme.getColor(ACTIVITY_BAR_ACTIVE_BACKGROUND),
|
||||
badgeBackground: theme.getColor(ACTIVITY_BAR_BADGE_BACKGROUND),
|
||||
badgeForeground: theme.getColor(ACTIVITY_BAR_BADGE_FOREGROUND),
|
||||
dragAndDropBorder: theme.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BORDER),
|
||||
activeBackgroundColor: undefined, inactiveBackgroundColor: undefined, activeBorderBottomColor: undefined,
|
||||
};
|
||||
content.appendChild(this.homeBarContainer);
|
||||
}
|
||||
|
||||
private createGlobalActivityActionBar(container: HTMLElement): void {
|
||||
@@ -591,7 +591,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
if (action.id === 'workbench.actions.accounts') {
|
||||
return this.instantiationService.createInstance(AccountsActionViewItem, action as ActivityAction, (theme: IColorTheme) => this.getActivitybarItemColors(theme));
|
||||
return this.instantiationService.createInstance(AccountsActivityActionViewItem, action as ActivityAction, (theme: IColorTheme) => this.getActivitybarItemColors(theme));
|
||||
}
|
||||
|
||||
throw new Error(`No view item for action '${action.id}'`);
|
||||
@@ -603,18 +603,18 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
ignoreOrientationForPreviousAndNextKey: true
|
||||
}));
|
||||
|
||||
this.globalActivityAction = new ActivityAction({
|
||||
this.globalActivityAction = this._register(new ActivityAction({
|
||||
id: 'workbench.actions.manage',
|
||||
name: nls.localize('manage', "Manage"),
|
||||
cssClass: Codicon.settingsGear.classNames
|
||||
});
|
||||
cssClass: ThemeIcon.asClassName(settingsViewBarIcon)
|
||||
}));
|
||||
|
||||
if (this.accountsVisibilityPreference) {
|
||||
this.accountsActivityAction = new ActivityAction({
|
||||
this.accountsActivityAction = this._register(new ActivityAction({
|
||||
id: 'workbench.actions.accounts',
|
||||
name: nls.localize('accounts', "Accounts"),
|
||||
cssClass: Codicon.account.classNames
|
||||
});
|
||||
cssClass: ThemeIcon.asClassName(accountsViewBarIcon)
|
||||
}));
|
||||
|
||||
this.globalActivityActionBar.push(this.accountsActivityAction, { index: ActivitybarPart.ACCOUNTS_ACTION_INDEX });
|
||||
}
|
||||
@@ -628,11 +628,11 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
this.globalActivityActionBar.pull(ActivitybarPart.ACCOUNTS_ACTION_INDEX);
|
||||
this.accountsActivityAction = undefined;
|
||||
} else {
|
||||
this.accountsActivityAction = new ActivityAction({
|
||||
this.accountsActivityAction = this._register(new ActivityAction({
|
||||
id: 'workbench.actions.accounts',
|
||||
name: nls.localize('accounts', "Accounts"),
|
||||
cssClass: Codicon.account.classNames
|
||||
});
|
||||
}));
|
||||
this.globalActivityActionBar.push(this.accountsActivityAction, { index: ActivitybarPart.ACCOUNTS_ACTION_INDEX });
|
||||
}
|
||||
}
|
||||
@@ -723,7 +723,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
return ActivitybarPart.toActivity(id, name, icon, focusCommand?.id || id);
|
||||
}
|
||||
|
||||
private static toActivity(id: string, name: string, icon: URI | string | undefined, keybindingId: string | undefined): IActivity {
|
||||
private static toActivity(id: string, name: string, icon: URI | ThemeIcon | undefined, keybindingId: string | undefined): IActivity {
|
||||
let cssClass: string | undefined = undefined;
|
||||
let iconUrl: URI | undefined = undefined;
|
||||
if (URI.isUri(icon)) {
|
||||
@@ -736,9 +736,10 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
-webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%;
|
||||
-webkit-mask-size: 24px;
|
||||
`);
|
||||
} else if (isString(icon)) {
|
||||
cssClass = icon;
|
||||
} else if (ThemeIcon.isThemeIcon(icon)) {
|
||||
cssClass = ThemeIcon.asClassName(icon);
|
||||
}
|
||||
|
||||
return { id, name, cssClass, iconUrl, keybindingId };
|
||||
}
|
||||
|
||||
@@ -810,6 +811,35 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
focusActivityBar(): void {
|
||||
this.compositeBar.focus();
|
||||
}
|
||||
|
||||
updateStyles(): void {
|
||||
super.updateStyles();
|
||||
|
||||
const container = assertIsDefined(this.getContainer());
|
||||
const background = this.getColor(ACTIVITY_BAR_BACKGROUND) || '';
|
||||
container.style.backgroundColor = background;
|
||||
|
||||
const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder) || '';
|
||||
container.classList.toggle('bordered', !!borderColor);
|
||||
container.style.borderColor = borderColor ? borderColor : '';
|
||||
}
|
||||
|
||||
private getActivitybarItemColors(theme: IColorTheme): ICompositeBarColors {
|
||||
return {
|
||||
activeForegroundColor: theme.getColor(ACTIVITY_BAR_FOREGROUND),
|
||||
inactiveForegroundColor: theme.getColor(ACTIVITY_BAR_INACTIVE_FOREGROUND),
|
||||
activeBorderColor: theme.getColor(ACTIVITY_BAR_ACTIVE_BORDER),
|
||||
activeBackground: theme.getColor(ACTIVITY_BAR_ACTIVE_BACKGROUND),
|
||||
badgeBackground: theme.getColor(ACTIVITY_BAR_BADGE_BACKGROUND),
|
||||
badgeForeground: theme.getColor(ACTIVITY_BAR_BADGE_FOREGROUND),
|
||||
dragAndDropBorder: theme.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BORDER),
|
||||
activeBackgroundColor: undefined, inactiveBackgroundColor: undefined, activeBorderBottomColor: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
if (!this.layoutService.isVisible(Parts.ACTIVITYBAR_PART)) {
|
||||
return;
|
||||
@@ -834,6 +864,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
private getViewContainer(id: string): ViewContainer | undefined {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
|
||||
|
||||
return viewContainer && this.viewDescriptorService.getViewContainerLocation(viewContainer) === this.location ? viewContainer : undefined;
|
||||
}
|
||||
|
||||
@@ -841,7 +872,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
return this.viewDescriptorService.getViewContainersByLocation(this.location);
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === ActivitybarPart.PINNED_VIEW_CONTAINERS && e.scope === StorageScope.GLOBAL
|
||||
&& this.pinnedViewContainersValue !== this.getStoredPinnedViewContainersValue() /* This checks if current window changed the value or not */) {
|
||||
this._pinnedViewContainersValue = undefined;
|
||||
@@ -870,11 +901,11 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
this.compositeBar.setCompositeBarItems(newCompositeItems);
|
||||
}
|
||||
|
||||
if (e.key === ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE && e.scope === StorageScope.GLOBAL) {
|
||||
if (e.key === HomeActivityActionViewItem.HOME_BAR_VISIBILITY_PREFERENCE && e.scope === StorageScope.GLOBAL) {
|
||||
this.onDidChangeHomeBarVisibility();
|
||||
}
|
||||
|
||||
if (e.key === ACCOUNTS_VISIBILITY_PREFERENCE_KEY && e.scope === StorageScope.GLOBAL) {
|
||||
if (e.key === AccountsActivityActionViewItem.ACCOUNTS_VISIBILITY_PREFERENCE_KEY && e.scope === StorageScope.GLOBAL) {
|
||||
this.toggleAccountsActivity();
|
||||
}
|
||||
}
|
||||
@@ -917,12 +948,13 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
const cachedViewContainer = this._cachedViewContainers.filter(cached => cached.id === placeholderViewContainer.id)[0];
|
||||
if (cachedViewContainer) {
|
||||
cachedViewContainer.name = placeholderViewContainer.name;
|
||||
cachedViewContainer.icon = placeholderViewContainer.iconCSS ? placeholderViewContainer.iconCSS :
|
||||
cachedViewContainer.icon = placeholderViewContainer.themeIcon ? ThemeIcon.revive(placeholderViewContainer.themeIcon) :
|
||||
placeholderViewContainer.iconUrl ? URI.revive(placeholderViewContainer.iconUrl) : undefined;
|
||||
cachedViewContainer.views = placeholderViewContainer.views;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this._cachedViewContainers;
|
||||
}
|
||||
|
||||
@@ -933,10 +965,11 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
visible,
|
||||
order
|
||||
})));
|
||||
|
||||
this.setPlaceholderViewContainers(cachedViewContainers.map(({ id, icon, name, views }) => (<IPlaceholderViewContainer>{
|
||||
id,
|
||||
iconUrl: URI.isUri(icon) ? icon : undefined,
|
||||
iconCSS: isString(icon) ? icon : undefined,
|
||||
themeIcon: ThemeIcon.isThemeIcon(icon) ? icon : undefined,
|
||||
name,
|
||||
views
|
||||
})));
|
||||
@@ -971,7 +1004,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private setStoredPinnedViewContainersValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||
@@ -1003,37 +1036,23 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
|
||||
private setStoredPlaceholderViewContainersValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
private get homeBarVisibilityPreference(): boolean {
|
||||
return this.storageService.getBoolean(ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, StorageScope.GLOBAL, true);
|
||||
return this.storageService.getBoolean(HomeActivityActionViewItem.HOME_BAR_VISIBILITY_PREFERENCE, StorageScope.GLOBAL, true);
|
||||
}
|
||||
|
||||
private set homeBarVisibilityPreference(value: boolean) {
|
||||
this.storageService.store(ActivitybarPart.HOME_BAR_VISIBILITY_PREFERENCE, value, StorageScope.GLOBAL);
|
||||
this.storageService.store(HomeActivityActionViewItem.HOME_BAR_VISIBILITY_PREFERENCE, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private get accountsVisibilityPreference(): boolean {
|
||||
return this.storageService.getBoolean(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, StorageScope.GLOBAL, true);
|
||||
return this.storageService.getBoolean(AccountsActivityActionViewItem.ACCOUNTS_VISIBILITY_PREFERENCE_KEY, StorageScope.GLOBAL, true);
|
||||
}
|
||||
|
||||
private set accountsVisibilityPreference(value: boolean) {
|
||||
this.storageService.store(ACCOUNTS_VISIBILITY_PREFERENCE_KEY, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private migrateFromOldCachedViewContainersValue(): void {
|
||||
const value = this.storageService.get('workbench.activity.pinnedViewlets', StorageScope.GLOBAL);
|
||||
if (value !== undefined) {
|
||||
const storedStates: Array<string | ICachedViewContainer> = JSON.parse(value);
|
||||
const cachedViewContainers = storedStates.map(c => {
|
||||
const serialized: ICachedViewContainer = 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;
|
||||
});
|
||||
this.storeCachedViewContainersState(cachedViewContainers);
|
||||
this.storageService.remove('workbench.activity.pinnedViewlets', StorageScope.GLOBAL);
|
||||
}
|
||||
this.storageService.store(AccountsActivityActionViewItem.ACCOUNTS_VISIBILITY_PREFERENCE_KEY, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
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;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
<<<<<<< HEAD
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -59,6 +60,8 @@
|
||||
/* NOTE@coder: Hide since it doesn't seem to do anything when used with
|
||||
code-server except open the VS Code repository. */
|
||||
display: none !important;
|
||||
=======
|
||||
>>>>>>> e4a830e9b7ca039c7c70697786d29f5b6679d775
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content > .home-bar > .home-bar-icon-badge {
|
||||
@@ -92,10 +95,6 @@
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench .activitybar > .content > .composite-bar-excess {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/** Menu Bar */
|
||||
|
||||
.monaco-workbench .activitybar .menubar {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { Composite, CompositeRegistry } from 'vs/workbench/browser/composite';
|
||||
import { IComposite } from 'vs/workbench/common/composite';
|
||||
import { CompositeProgressIndicator } from 'vs/workbench/services/progress/browser/progressIndicator';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
@@ -199,7 +199,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
// Store in preferences
|
||||
const id = this.activeComposite.getId();
|
||||
if (id !== this.defaultCompositeId) {
|
||||
this.storageService.store(this.activeCompositeSettingsKey, id, StorageScope.WORKSPACE);
|
||||
this.storageService.store(this.activeCompositeSettingsKey, id, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
} else {
|
||||
this.storageService.remove(this.activeCompositeSettingsKey, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IDialogHandler, IDialogResult, IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { IDialogsModel, IDialogViewItem } from 'vs/workbench/common/dialogs';
|
||||
import { BrowserDialogHandler } from 'vs/workbench/browser/parts/dialogs/dialogHandler';
|
||||
import { DialogService } from 'vs/workbench/services/dialogs/common/dialogService';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class DialogHandlerContribution extends Disposable implements IWorkbenchContribution {
|
||||
private impl: IDialogHandler;
|
||||
|
||||
private model: IDialogsModel;
|
||||
private currentDialog: IDialogViewItem | undefined;
|
||||
|
||||
constructor(
|
||||
@IDialogService private dialogService: IDialogService,
|
||||
@ILogService logService: ILogService,
|
||||
@ILayoutService layoutService: ILayoutService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IProductService productService: IProductService,
|
||||
@IClipboardService clipboardService: IClipboardService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.impl = new BrowserDialogHandler(logService, layoutService, themeService, keybindingService, productService, clipboardService);
|
||||
|
||||
this.model = (this.dialogService as DialogService).model;
|
||||
|
||||
this._register(this.model.onDidShowDialog(() => {
|
||||
if (!this.currentDialog) {
|
||||
this.processDialogs();
|
||||
}
|
||||
}));
|
||||
|
||||
this.processDialogs();
|
||||
}
|
||||
|
||||
private async processDialogs(): Promise<void> {
|
||||
while (this.model.dialogs.length) {
|
||||
this.currentDialog = this.model.dialogs[0];
|
||||
|
||||
let result: IDialogResult | undefined = undefined;
|
||||
if (this.currentDialog.args.confirmArgs) {
|
||||
const args = this.currentDialog.args.confirmArgs;
|
||||
result = await this.impl.confirm(args.confirmation);
|
||||
} else if (this.currentDialog.args.inputArgs) {
|
||||
const args = this.currentDialog.args.inputArgs;
|
||||
result = await this.impl.input(args.severity, args.message, args.buttons, args.inputs, args.options);
|
||||
} else if (this.currentDialog.args.showArgs) {
|
||||
const args = this.currentDialog.args.showArgs;
|
||||
result = await this.impl.show(args.severity, args.message, args.buttons, args.options);
|
||||
} else {
|
||||
await this.impl.about();
|
||||
}
|
||||
|
||||
this.currentDialog.close(result);
|
||||
this.currentDialog = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(DialogHandlerContribution, LifecyclePhase.Starting);
|
||||
@@ -0,0 +1,144 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDialogOptions, IConfirmation, IConfirmationResult, DialogType, IShowResult, IInputResult, ICheckbox, IInput, IDialogHandler } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { Dialog, IDialogResult } from 'vs/base/browser/ui/dialog/dialog';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachDialogStyler } from 'vs/platform/theme/common/styler';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { EventHelper } from 'vs/base/browser/dom';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
|
||||
export class BrowserDialogHandler implements IDialogHandler {
|
||||
|
||||
private static readonly ALLOWABLE_COMMANDS = [
|
||||
'copy',
|
||||
'cut',
|
||||
'editor.action.selectAll',
|
||||
'editor.action.clipboardCopyAction',
|
||||
'editor.action.clipboardCutAction',
|
||||
'editor.action.clipboardPasteAction'
|
||||
];
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILayoutService private readonly layoutService: ILayoutService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IClipboardService private readonly clipboardService: IClipboardService
|
||||
) { }
|
||||
|
||||
async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
|
||||
this.logService.trace('DialogService#confirm', confirmation.message);
|
||||
|
||||
const buttons: string[] = [];
|
||||
if (confirmation.primaryButton) {
|
||||
buttons.push(confirmation.primaryButton);
|
||||
} else {
|
||||
buttons.push(nls.localize({ key: 'yesButton', comment: ['&& denotes a mnemonic'] }, "&&Yes"));
|
||||
}
|
||||
|
||||
if (confirmation.secondaryButton) {
|
||||
buttons.push(confirmation.secondaryButton);
|
||||
} else if (typeof confirmation.secondaryButton === 'undefined') {
|
||||
buttons.push(nls.localize('cancelButton', "Cancel"));
|
||||
}
|
||||
|
||||
const result = await this.doShow(confirmation.type, confirmation.message, buttons, confirmation.detail, 1, confirmation.checkbox);
|
||||
|
||||
return { confirmed: result.button === 0, checkboxChecked: result.checkboxChecked };
|
||||
}
|
||||
|
||||
private getDialogType(severity: Severity): DialogType {
|
||||
return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none';
|
||||
}
|
||||
|
||||
async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise<IShowResult> {
|
||||
this.logService.trace('DialogService#show', message);
|
||||
|
||||
const result = await this.doShow(this.getDialogType(severity), message, buttons, options?.detail, options?.cancelId, options?.checkbox);
|
||||
|
||||
return {
|
||||
choice: result.button,
|
||||
checkboxChecked: result.checkboxChecked
|
||||
};
|
||||
}
|
||||
|
||||
private async doShow(type: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending' | undefined, message: string, buttons: string[], detail?: string, cancelId?: number, checkbox?: ICheckbox, inputs?: IInput[]): Promise<IDialogResult> {
|
||||
const dialogDisposables = new DisposableStore();
|
||||
const dialog = new Dialog(
|
||||
this.layoutService.container,
|
||||
message,
|
||||
buttons,
|
||||
{
|
||||
detail,
|
||||
cancelId,
|
||||
type,
|
||||
keyEventProcessor: (event: StandardKeyboardEvent) => {
|
||||
const resolved = this.keybindingService.softDispatch(event, this.layoutService.container);
|
||||
if (resolved && resolved.commandId) {
|
||||
if (BrowserDialogHandler.ALLOWABLE_COMMANDS.indexOf(resolved.commandId) === -1) {
|
||||
EventHelper.stop(event, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
checkboxLabel: checkbox?.label,
|
||||
checkboxChecked: checkbox?.checked,
|
||||
inputs
|
||||
});
|
||||
|
||||
dialogDisposables.add(dialog);
|
||||
dialogDisposables.add(attachDialogStyler(dialog, this.themeService));
|
||||
|
||||
const result = await dialog.show();
|
||||
dialogDisposables.dispose();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async input(severity: Severity, message: string, buttons: string[], inputs: IInput[], options?: IDialogOptions): Promise<IInputResult> {
|
||||
this.logService.trace('DialogService#input', message);
|
||||
|
||||
const result = await this.doShow(this.getDialogType(severity), message, buttons, options?.detail, options?.cancelId, options?.checkbox, inputs);
|
||||
|
||||
return {
|
||||
choice: result.button,
|
||||
checkboxChecked: result.checkboxChecked,
|
||||
values: result.values
|
||||
};
|
||||
}
|
||||
|
||||
async about(): Promise<void> {
|
||||
const detailString = (useAgo: boolean): string => {
|
||||
return nls.localize('aboutDetail',
|
||||
"code-server: v{4}\n VS Code: v{0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
this.productService.version || 'Unknown',
|
||||
this.productService.commit || 'Unknown',
|
||||
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
|
||||
navigator.userAgent,
|
||||
this.productService.codeServerVersion || 'Unknown',
|
||||
);
|
||||
};
|
||||
|
||||
const detail = detailString(true);
|
||||
const detailToCopy = detailString(false);
|
||||
|
||||
|
||||
const { choice } = await this.show(Severity.Info, this.productService.nameLong, [nls.localize('copy', "Copy"), nls.localize('ok', "OK")], { detail, cancelId: 1 });
|
||||
|
||||
if (choice === 0) {
|
||||
this.clipboardService.writeText(detailToCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import { dispose, IDisposable, Disposable, DisposableStore } from 'vs/base/commo
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { assertIsDefined, assertAllDefined } from 'vs/base/common/types';
|
||||
import { BinarySize } from 'vs/platform/files/common/files';
|
||||
import { ByteSize } from 'vs/platform/files/common/files';
|
||||
|
||||
export interface IOpenCallbacks {
|
||||
openInternal: (input: EditorInput, options: EditorOptions | undefined) => Promise<void>;
|
||||
@@ -182,7 +182,7 @@ interface ResourceViewerDelegate {
|
||||
|
||||
class ResourceViewer {
|
||||
|
||||
private static readonly MAX_OPEN_INTERNAL_SIZE = BinarySize.MB * 200; // max size until we offer an action to open internally
|
||||
private static readonly MAX_OPEN_INTERNAL_SIZE = ByteSize.MB * 200; // max size until we offer an action to open internally
|
||||
|
||||
static show(
|
||||
descriptor: IResourceDescriptor,
|
||||
@@ -211,7 +211,7 @@ class FileTooLargeFileView {
|
||||
scrollbar: DomScrollableElement,
|
||||
delegate: ResourceViewerDelegate
|
||||
) {
|
||||
const size = BinarySize.formatSize(descriptorSize);
|
||||
const size = ByteSize.formatSize(descriptorSize);
|
||||
delegate.metadataClb(size);
|
||||
|
||||
clearNode(container);
|
||||
@@ -233,7 +233,7 @@ class FileSeemsBinaryFileView {
|
||||
scrollbar: DomScrollableElement,
|
||||
delegate: ResourceViewerDelegate
|
||||
) {
|
||||
delegate.metadataClb(typeof descriptor.size === 'number' ? BinarySize.formatSize(descriptor.size) : '');
|
||||
delegate.metadataClb(typeof descriptor.size === 'number' ? ByteSize.formatSize(descriptor.size) : '');
|
||||
|
||||
clearNode(container);
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ export class BreadcrumbsControl {
|
||||
if (element instanceof FileElement) {
|
||||
if (element.kind === FileKind.FILE) {
|
||||
// open file in any editor
|
||||
this._editorService.openEditor({ resource: element.uri, options: { pinned: pinned } }, group);
|
||||
this._editorService.openEditor({ resource: element.uri, options: { pinned } }, group);
|
||||
} else {
|
||||
// show next picker
|
||||
let items = this._widget.getItems();
|
||||
@@ -508,7 +508,8 @@ export class BreadcrumbsControl {
|
||||
resource: model.uri,
|
||||
options: {
|
||||
selection: Range.collapseToStart(element.symbol.selectionRange),
|
||||
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport
|
||||
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,
|
||||
pinned
|
||||
}
|
||||
}, withUndefinedAsNull(this._getActiveCodeEditor()), group === SIDE_GROUP);
|
||||
}
|
||||
@@ -753,13 +754,14 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
// open symbol in editor
|
||||
return editors.openEditor({
|
||||
resource: outlineElement.uri,
|
||||
options: { selection: Range.collapseToStart(element.symbol.selectionRange) }
|
||||
options: { selection: Range.collapseToStart(element.symbol.selectionRange), pinned: true }
|
||||
}, SIDE_GROUP);
|
||||
|
||||
} else if (element && URI.isUri(element.resource)) {
|
||||
// open file in editor
|
||||
return editors.openEditor({
|
||||
resource: element.resource,
|
||||
options: { pinned: true }
|
||||
}, SIDE_GROUP);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -99,7 +99,7 @@ export abstract class BreadcrumbsPicker {
|
||||
this._treeContainer = document.createElement('div');
|
||||
this._treeContainer.style.background = color ? color.toString() : '';
|
||||
this._treeContainer.style.paddingTop = '2px';
|
||||
this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getColorTheme().getColor(widgetShadow)}`;
|
||||
this._treeContainer.style.boxShadow = `0 0 8px 2px ${this._themeService.getColorTheme().getColor(widgetShadow)}`;
|
||||
this._domNode.appendChild(this._treeContainer);
|
||||
|
||||
this._layoutInfo = { maxHeight, width, arrowSize, arrowOffset, inputHeight: 0 };
|
||||
@@ -436,7 +436,6 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
|
||||
}
|
||||
|
||||
protected _getTargetFromEvent(element: any): any | undefined {
|
||||
// todo@joh
|
||||
if (element && !IWorkspaceFolder.isIWorkspaceFolder(element) && !(element as IFileStat).isDirectory) {
|
||||
return new FileElement((element as IFileStat).resource, FileKind.FILE);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/pl
|
||||
import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess, AllEditorsByAppearanceQuickAccess, AllEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
import { FileAccess } from 'vs/base/common/network';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
|
||||
// Register String Editor
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
|
||||
@@ -238,27 +240,27 @@ export abstract class AbstractSideBySideEditorInputFactory implements IEditorInp
|
||||
const secondaryInput = secondaryInputFactory.deserialize(instantiationService, deserialized.secondarySerialized);
|
||||
|
||||
if (primaryInput && secondaryInput) {
|
||||
return this.createEditorInput(deserialized.name, deserialized.description, secondaryInput, primaryInput);
|
||||
return this.createEditorInput(instantiationService, deserialized.name, deserialized.description, secondaryInput, primaryInput);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected abstract createEditorInput(name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput;
|
||||
protected abstract createEditorInput(instantiationService: IInstantiationService, name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput;
|
||||
}
|
||||
|
||||
class SideBySideEditorInputFactory extends AbstractSideBySideEditorInputFactory {
|
||||
|
||||
protected createEditorInput(name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput {
|
||||
protected createEditorInput(instantiationService: IInstantiationService, name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput {
|
||||
return new SideBySideEditorInput(name, description, secondaryInput, primaryInput);
|
||||
}
|
||||
}
|
||||
|
||||
class DiffEditorInputFactory extends AbstractSideBySideEditorInputFactory {
|
||||
|
||||
protected createEditorInput(name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput {
|
||||
return new DiffEditorInput(name, description, secondaryInput, primaryInput);
|
||||
protected createEditorInput(instantiationService: IInstantiationService, name: string, description: string | undefined, secondaryInput: EditorInput, primaryInput: EditorInput): EditorInput {
|
||||
return instantiationService.createInstance(DiffEditorInput, name, description, secondaryInput, primaryInput, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,6 +464,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.SHOW_EDITORS_IN_GROUP, title: nls.localize('showOpenedEditors', "Show Opened Editors") }, group: '3_open', order: 10 });
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, title: nls.localize('closeAll', "Close All") }, group: '5_close', order: 10 });
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_SAVED_EDITORS_COMMAND_ID, title: nls.localize('closeAllSaved', "Close Saved") }, group: '5_close', order: 20 });
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.TOGGLE_KEEP_EDITORS_COMMAND_ID, title: nls.localize('toggleKeepEditors', "Keep Editors Open"), toggled: ContextKeyExpr.not('config.workbench.editor.enablePreview') }, group: '7_settings', order: 10 });
|
||||
|
||||
interface IEditorToolItem { id: string; title: string; icon?: { dark?: URI; light?: URI; } | ThemeIcon; }
|
||||
|
||||
@@ -494,14 +497,14 @@ appendEditorToolItem(
|
||||
{
|
||||
id: SplitEditorAction.ID,
|
||||
title: nls.localize('splitEditorRight', "Split Editor Right"),
|
||||
icon: { id: 'codicon/split-horizontal' }
|
||||
icon: Codicon.splitHorizontal
|
||||
},
|
||||
ContextKeyExpr.not('splitEditorsVertically'),
|
||||
100000, // towards the end
|
||||
{
|
||||
id: editorCommands.SPLIT_EDITOR_DOWN,
|
||||
title: nls.localize('splitEditorDown', "Split Editor Down"),
|
||||
icon: { id: 'codicon/split-vertical' }
|
||||
icon: Codicon.splitVertical
|
||||
}
|
||||
);
|
||||
|
||||
@@ -509,14 +512,14 @@ appendEditorToolItem(
|
||||
{
|
||||
id: SplitEditorAction.ID,
|
||||
title: nls.localize('splitEditorDown', "Split Editor Down"),
|
||||
icon: { id: 'codicon/split-vertical' }
|
||||
icon: Codicon.splitVertical
|
||||
},
|
||||
ContextKeyExpr.has('splitEditorsVertically'),
|
||||
100000, // towards the end
|
||||
{
|
||||
id: editorCommands.SPLIT_EDITOR_RIGHT,
|
||||
title: nls.localize('splitEditorRight', "Split Editor Right"),
|
||||
icon: { id: 'codicon/split-horizontal' }
|
||||
icon: Codicon.splitHorizontal
|
||||
}
|
||||
);
|
||||
|
||||
@@ -525,14 +528,14 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
icon: { id: 'codicon/close' }
|
||||
icon: Codicon.close
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ActiveEditorDirtyContext.toNegated(), ActiveEditorStickyContext.toNegated()),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
title: nls.localize('closeAll', "Close All"),
|
||||
icon: { id: 'codicon/close-all' }
|
||||
icon: Codicon.closeAll
|
||||
}
|
||||
);
|
||||
|
||||
@@ -541,14 +544,14 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
icon: { id: 'codicon/close-dirty' }
|
||||
icon: Codicon.closeDirty
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ActiveEditorDirtyContext, ActiveEditorStickyContext.toNegated()),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
title: nls.localize('closeAll', "Close All"),
|
||||
icon: { id: 'codicon/close-all' }
|
||||
icon: Codicon.closeAll
|
||||
}
|
||||
);
|
||||
|
||||
@@ -557,14 +560,14 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.UNPIN_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('unpin', "Unpin"),
|
||||
icon: { id: 'codicon/pinned' }
|
||||
icon: Codicon.pinned
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ActiveEditorDirtyContext.toNegated(), ActiveEditorStickyContext),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
icon: { id: 'codicon/close' }
|
||||
icon: Codicon.close
|
||||
}
|
||||
);
|
||||
|
||||
@@ -573,23 +576,28 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.UNPIN_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('unpin', "Unpin"),
|
||||
icon: { id: 'codicon/pinned-dirty' }
|
||||
icon: Codicon.pinnedDirty
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ActiveEditorDirtyContext, ActiveEditorStickyContext),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
icon: { id: 'codicon/close' }
|
||||
icon: Codicon.close
|
||||
}
|
||||
);
|
||||
|
||||
const previousChangeIcon = registerIcon('diff-editor-previous-change', Codicon.arrowUp, nls.localize('previousChangeIcon', 'Icon for the previous change action in the diff editor.'));
|
||||
const nextChangeIcon = registerIcon('diff-editor-next-change', Codicon.arrowDown, nls.localize('nextChangeIcon', 'Icon for the next change action in the diff editor.'));
|
||||
const toggleWhitespace = registerIcon('diff-editor-toggle-whitespace', Codicon.whitespace, nls.localize('toggleWhitespace', 'Icon for the toggle whitespace action in the diff editor.'));
|
||||
|
||||
|
||||
// Diff Editor Title Menu: Previous Change
|
||||
appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.GOTO_PREVIOUS_CHANGE,
|
||||
title: nls.localize('navigate.prev.label', "Previous Change"),
|
||||
icon: { id: 'codicon/arrow-up' }
|
||||
icon: previousChangeIcon
|
||||
},
|
||||
TextCompareEditorActiveContext,
|
||||
10
|
||||
@@ -600,7 +608,7 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.GOTO_NEXT_CHANGE,
|
||||
title: nls.localize('navigate.next.label', "Next Change"),
|
||||
icon: { id: 'codicon/arrow-down' }
|
||||
icon: nextChangeIcon
|
||||
},
|
||||
TextCompareEditorActiveContext,
|
||||
11
|
||||
@@ -611,7 +619,7 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE,
|
||||
title: nls.localize('ignoreTrimWhitespace.label', "Ignore Leading/Trailing Whitespace Differences"),
|
||||
icon: { id: 'codicon/whitespace' }
|
||||
icon: toggleWhitespace
|
||||
},
|
||||
ContextKeyExpr.and(TextCompareEditorActiveContext, ContextKeyExpr.notEquals('config.diffEditor.ignoreTrimWhitespace', true)),
|
||||
20
|
||||
@@ -622,7 +630,7 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE,
|
||||
title: nls.localize('showTrimWhitespace.label', "Show Leading/Trailing Whitespace Differences"),
|
||||
icon: { id: 'codicon/whitespace~disabled' }
|
||||
icon: ThemeIcon.modify(toggleWhitespace, 'disabled')
|
||||
},
|
||||
ContextKeyExpr.and(TextCompareEditorActiveContext, ContextKeyExpr.notEquals('config.diffEditor.ignoreTrimWhitespace', false)),
|
||||
20
|
||||
|
||||
@@ -38,7 +38,8 @@ export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = {
|
||||
openSideBySideDirection: 'right',
|
||||
closeEmptyGroups: true,
|
||||
labelFormat: 'default',
|
||||
splitSizing: 'distribute'
|
||||
splitSizing: 'distribute',
|
||||
splitOnDragAndDrop: true
|
||||
};
|
||||
|
||||
export function impactsEditorPartOptions(event: IConfigurationChangeEvent): boolean {
|
||||
@@ -64,12 +65,12 @@ export interface IEditorOpeningEvent extends IEditorIdentifier {
|
||||
/**
|
||||
* The options used when opening the editor.
|
||||
*/
|
||||
options?: IEditorOptions;
|
||||
readonly options?: IEditorOptions;
|
||||
|
||||
/**
|
||||
* Context indicates how the editor open event is initialized.
|
||||
*/
|
||||
context?: OpenEditorContext;
|
||||
readonly context?: OpenEditorContext;
|
||||
|
||||
/**
|
||||
* Allows to prevent the opening of an editor by providing a callback
|
||||
|
||||
@@ -7,22 +7,26 @@ import * as nls from 'vs/nls';
|
||||
import { isObject, isString, isUndefined, isNumber, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { TextCompareEditorVisibleContext, EditorInput, IEditorIdentifier, IEditorCommandsContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, CloseDirection, IEditorInput, IVisibleEditorPane, ActiveEditorStickyContext, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { TextCompareEditorVisibleContext, EditorInput, IEditorIdentifier, IEditorCommandsContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, CloseDirection, IEditorInput, IVisibleEditorPane, ActiveEditorStickyContext, EditorsOrder, viewColumnToEditorGroup, EditorGroupColumn } from 'vs/workbench/common/editor';
|
||||
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { TextDiffEditor } from 'vs/workbench/browser/parts/editor/textDiffEditor';
|
||||
import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IListService, IOpenEvent } from 'vs/platform/list/browser/listService';
|
||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { distinct, coalesce } from 'vs/base/common/arrays';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupDirection, GroupLocation, GroupsOrder, preferredSideBySideGroupDirection, EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
|
||||
|
||||
export const CLOSE_SAVED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors';
|
||||
export const CLOSE_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeEditorsInGroup';
|
||||
@@ -36,6 +40,7 @@ export const CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeOt
|
||||
export const MOVE_ACTIVE_EDITOR_COMMAND_ID = 'moveActiveEditor';
|
||||
export const LAYOUT_EDITOR_GROUPS_COMMAND_ID = 'layoutEditorGroups';
|
||||
export const KEEP_EDITOR_COMMAND_ID = 'workbench.action.keepEditor';
|
||||
export const TOGGLE_KEEP_EDITORS_COMMAND_ID = 'workbench.action.toggleKeepEditors';
|
||||
export const SHOW_EDITORS_IN_GROUP = 'workbench.action.showEditorsInGroup';
|
||||
|
||||
export const PIN_EDITOR_COMMAND_ID = 'workbench.action.pinEditor';
|
||||
@@ -44,6 +49,9 @@ export const UNPIN_EDITOR_COMMAND_ID = 'workbench.action.unpinEditor';
|
||||
export const TOGGLE_DIFF_SIDE_BY_SIDE = 'toggle.diff.renderSideBySide';
|
||||
export const GOTO_NEXT_CHANGE = 'workbench.action.compareEditor.nextChange';
|
||||
export const GOTO_PREVIOUS_CHANGE = 'workbench.action.compareEditor.previousChange';
|
||||
export const DIFF_FOCUS_PRIMARY_SIDE = 'workbench.action.compareEditor.focusPrimarySide';
|
||||
export const DIFF_FOCUS_SECONDARY_SIDE = 'workbench.action.compareEditor.focusSecondarySide';
|
||||
export const DIFF_FOCUS_OTHER_SIDE = 'workbench.action.compareEditor.focusOtherSide';
|
||||
export const TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE = 'toggle.diff.ignoreTrimWhitespace';
|
||||
|
||||
export const SPLIT_EDITOR_UP = 'workbench.action.splitEditorUp';
|
||||
@@ -58,6 +66,10 @@ export const FOCUS_BELOW_GROUP_WITHOUT_WRAP_COMMAND_ID = 'workbench.action.focus
|
||||
|
||||
export const OPEN_EDITOR_AT_INDEX_COMMAND_ID = 'workbench.action.openEditorAtIndex';
|
||||
|
||||
export const API_OPEN_EDITOR_COMMAND_ID = '_workbench.open';
|
||||
export const API_OPEN_DIFF_EDITOR_COMMAND_ID = '_workbench.diff';
|
||||
export const API_OPEN_WITH_EDITOR_COMMAND_ID = '_workbench.openWith';
|
||||
|
||||
export interface ActiveEditorMoveArguments {
|
||||
to: 'first' | 'last' | 'left' | 'right' | 'up' | 'down' | 'center' | 'position' | 'previous' | 'next';
|
||||
by: 'tab' | 'group';
|
||||
@@ -227,13 +239,45 @@ function moveActiveEditorToGroup(args: ActiveEditorMoveArguments, control: IVisi
|
||||
}
|
||||
|
||||
function registerEditorGroupsLayoutCommand(): void {
|
||||
CommandsRegistry.registerCommand(LAYOUT_EDITOR_GROUPS_COMMAND_ID, (accessor: ServicesAccessor, args: EditorGroupLayout) => {
|
||||
if (!args || typeof args !== 'object') {
|
||||
|
||||
function applyEditorLayout(accessor: ServicesAccessor, layout: EditorGroupLayout): void {
|
||||
if (!layout || typeof layout !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
editorGroupService.applyLayout(args);
|
||||
editorGroupService.applyLayout(layout);
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand(LAYOUT_EDITOR_GROUPS_COMMAND_ID, (accessor: ServicesAccessor, args: EditorGroupLayout) => {
|
||||
applyEditorLayout(accessor, args);
|
||||
});
|
||||
|
||||
// API Command
|
||||
CommandsRegistry.registerCommand({
|
||||
id: 'vscode.setEditorLayout',
|
||||
handler: (accessor: ServicesAccessor, args: EditorGroupLayout) => applyEditorLayout(accessor, args),
|
||||
description: {
|
||||
description: 'Set Editor Layout',
|
||||
args: [{
|
||||
name: 'args',
|
||||
schema: {
|
||||
'type': 'object',
|
||||
'required': ['groups'],
|
||||
'properties': {
|
||||
'orientation': {
|
||||
'type': 'number',
|
||||
'default': 0,
|
||||
'enum': [0, 1]
|
||||
},
|
||||
'groups': {
|
||||
'$ref': '#/definitions/editorGroupsSchema',
|
||||
'default': [{}, {}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -265,30 +309,68 @@ function registerDiffEditorCommands(): void {
|
||||
handler: accessor => navigateInDiffEditor(accessor, false)
|
||||
});
|
||||
|
||||
function navigateInDiffEditor(accessor: ServicesAccessor, next: boolean): void {
|
||||
function getActiveTextDiffEditor(accessor: ServicesAccessor): TextDiffEditor | undefined {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const candidates = [editorService.activeEditorPane, ...editorService.visibleEditorPanes].filter(editor => editor instanceof TextDiffEditor);
|
||||
|
||||
if (candidates.length > 0) {
|
||||
const navigator = (<TextDiffEditor>candidates[0]).getDiffNavigator();
|
||||
for (const editor of [editorService.activeEditorPane, ...editorService.visibleEditorPanes]) {
|
||||
if (editor instanceof TextDiffEditor) {
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function navigateInDiffEditor(accessor: ServicesAccessor, next: boolean): void {
|
||||
const activeTextDiffEditor = getActiveTextDiffEditor(accessor);
|
||||
|
||||
if (activeTextDiffEditor) {
|
||||
const navigator = activeTextDiffEditor.getDiffNavigator();
|
||||
if (navigator) {
|
||||
next ? navigator.next() : navigator.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum FocusTextDiffEditorMode {
|
||||
Original,
|
||||
Modified,
|
||||
Toggle
|
||||
}
|
||||
|
||||
function focusInDiffEditor(accessor: ServicesAccessor, mode: FocusTextDiffEditorMode): void {
|
||||
const activeTextDiffEditor = getActiveTextDiffEditor(accessor);
|
||||
|
||||
if (activeTextDiffEditor) {
|
||||
switch (mode) {
|
||||
case FocusTextDiffEditorMode.Original:
|
||||
activeTextDiffEditor.getControl()?.getOriginalEditor().focus();
|
||||
break;
|
||||
case FocusTextDiffEditorMode.Modified:
|
||||
activeTextDiffEditor.getControl()?.getModifiedEditor().focus();
|
||||
break;
|
||||
case FocusTextDiffEditorMode.Toggle:
|
||||
if (activeTextDiffEditor.getControl()?.getModifiedEditor().hasWidgetFocus()) {
|
||||
return focusInDiffEditor(accessor, FocusTextDiffEditorMode.Original);
|
||||
} else {
|
||||
return focusInDiffEditor(accessor, FocusTextDiffEditorMode.Modified);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDiffSideBySide(accessor: ServicesAccessor): void {
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
|
||||
const newValue = !configurationService.getValue<boolean>('diffEditor.renderSideBySide');
|
||||
configurationService.updateValue('diffEditor.renderSideBySide', newValue, ConfigurationTarget.USER);
|
||||
configurationService.updateValue('diffEditor.renderSideBySide', newValue);
|
||||
}
|
||||
|
||||
function toggleDiffIgnoreTrimWhitespace(accessor: ServicesAccessor): void {
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
|
||||
const newValue = !configurationService.getValue<boolean>('diffEditor.ignoreTrimWhitespace');
|
||||
configurationService.updateValue('diffEditor.ignoreTrimWhitespace', newValue, ConfigurationTarget.USER);
|
||||
configurationService.updateValue('diffEditor.ignoreTrimWhitespace', newValue);
|
||||
}
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
@@ -299,6 +381,30 @@ function registerDiffEditorCommands(): void {
|
||||
handler: accessor => toggleDiffSideBySide(accessor)
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: DIFF_FOCUS_PRIMARY_SIDE,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: accessor => focusInDiffEditor(accessor, FocusTextDiffEditorMode.Modified)
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: DIFF_FOCUS_SECONDARY_SIDE,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: accessor => focusInDiffEditor(accessor, FocusTextDiffEditorMode.Original)
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: DIFF_FOCUS_OTHER_SIDE,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: accessor => focusInDiffEditor(accessor, FocusTextDiffEditorMode.Toggle)
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: TOGGLE_DIFF_SIDE_BY_SIDE,
|
||||
@@ -320,6 +426,88 @@ function registerDiffEditorCommands(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function registerOpenEditorAPICommands(): void {
|
||||
|
||||
function mixinContext(context: IOpenEvent<unknown> | undefined, options: ITextEditorOptions | undefined, column: EditorGroupColumn | undefined): [ITextEditorOptions | undefined, EditorGroupColumn | undefined] {
|
||||
if (!context) {
|
||||
return [options, column];
|
||||
}
|
||||
|
||||
return [
|
||||
{ ...context.editorOptions, ...(options ?? Object.create(null)) },
|
||||
context.sideBySide ? SIDE_GROUP : column
|
||||
];
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand(API_OPEN_EDITOR_COMMAND_ID, async function (accessor: ServicesAccessor, resourceArg: UriComponents, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], label?: string, context?: IOpenEvent<unknown>) {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
const openerService = accessor.get(IOpenerService);
|
||||
|
||||
const resource = URI.revive(resourceArg);
|
||||
const [columnArg, optionsArg] = columnAndOptions ?? [];
|
||||
|
||||
// use editor options or editor view column as a hint to use the editor service for opening
|
||||
if (optionsArg || typeof columnArg === 'number') {
|
||||
const [options, column] = mixinContext(context, optionsArg, columnArg);
|
||||
|
||||
await editorService.openEditor({ resource, options, label }, viewColumnToEditorGroup(editorGroupService, column));
|
||||
}
|
||||
|
||||
// do not allow to execute commands from here
|
||||
else if (resource.scheme === 'command') {
|
||||
return;
|
||||
}
|
||||
|
||||
// finally, delegate to opener service
|
||||
else {
|
||||
await openerService.open(resource, { openToSide: context?.sideBySide, editorOptions: context?.editorOptions });
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand(API_OPEN_DIFF_EDITOR_COMMAND_ID, async function (accessor: ServicesAccessor, leftResource: UriComponents, rightResource: UriComponents, label?: string, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], context?: IOpenEvent<unknown>) {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
|
||||
const [columnArg, optionsArg] = columnAndOptions ?? [];
|
||||
const [options, column] = mixinContext(context, optionsArg, columnArg);
|
||||
|
||||
await editorService.openEditor({
|
||||
leftResource: URI.revive(leftResource),
|
||||
rightResource: URI.revive(rightResource),
|
||||
label,
|
||||
options
|
||||
}, viewColumnToEditorGroup(editorGroupService, column));
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand(API_OPEN_WITH_EDITOR_COMMAND_ID, (accessor: ServicesAccessor, resource: UriComponents, id: string, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?]) => {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editorGroupsService = accessor.get(IEditorGroupsService);
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
const quickInputService = accessor.get(IQuickInputService);
|
||||
|
||||
const [columnArg, optionsArg] = columnAndOptions ?? [];
|
||||
let group: IEditorGroup | undefined = undefined;
|
||||
|
||||
if (columnArg === SIDE_GROUP) {
|
||||
const direction = preferredSideBySideGroupDirection(configurationService);
|
||||
|
||||
let neighbourGroup = editorGroupsService.findGroup({ direction });
|
||||
if (!neighbourGroup) {
|
||||
neighbourGroup = editorGroupsService.addGroup(editorGroupsService.activeGroup, direction);
|
||||
}
|
||||
group = neighbourGroup;
|
||||
} else {
|
||||
group = editorGroupsService.getGroup(viewColumnToEditorGroup(editorGroupsService, columnArg)) ?? editorGroupsService.activeGroup;
|
||||
}
|
||||
|
||||
const textOptions: ITextEditorOptions = optionsArg ? { ...optionsArg, override: false } : { override: false };
|
||||
|
||||
const input = editorService.createEditorInput({ resource: URI.revive(resource) });
|
||||
return openEditorWith(input, id, textOptions, group, editorService, configurationService, quickInputService);
|
||||
});
|
||||
}
|
||||
|
||||
function registerOpenEditorAtIndexCommands(): void {
|
||||
const openEditorAtIndex: ICommandHandler = (accessor: ServicesAccessor, editorIndex: number): void => {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
@@ -710,6 +898,31 @@ function registerOtherEditorCommands(): void {
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: TOGGLE_KEEP_EDITORS_COMMAND_ID,
|
||||
handler: accessor => {
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const openerService = accessor.get(IOpenerService);
|
||||
|
||||
// Update setting
|
||||
const currentSetting = configurationService.getValue<boolean>('workbench.editor.enablePreview');
|
||||
const newSetting = currentSetting === true ? false : true;
|
||||
configurationService.updateValue('workbench.editor.enablePreview', newSetting);
|
||||
|
||||
// Inform user
|
||||
notificationService.prompt(
|
||||
Severity.Info,
|
||||
newSetting ?
|
||||
nls.localize('enablePreview', "Preview editors have been enabled in settings.") :
|
||||
nls.localize('disablePreview', "Preview editors have been disabled in settings."),
|
||||
[{
|
||||
label: nls.localize('learnMode', "Learn More"), run: () => openerService.open('https://go.microsoft.com/fwlink/?linkid=2147473')
|
||||
}]
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: PIN_EDITOR_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
@@ -877,6 +1090,7 @@ export function setup(): void {
|
||||
registerActiveEditorMoveCommand();
|
||||
registerEditorGroupsLayoutCommand();
|
||||
registerDiffEditorCommands();
|
||||
registerOpenEditorAPICommands();
|
||||
registerOpenEditorAtIndexCommands();
|
||||
registerCloseEditorCommands();
|
||||
registerOtherEditorCommands();
|
||||
|
||||
@@ -12,7 +12,7 @@ import { IThemeService, Themable } from 'vs/platform/theme/common/themeService';
|
||||
import { activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IEditorIdentifier, EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { isMacintosh, isWeb } from 'vs/base/common/platform';
|
||||
import { GroupDirection, MergeGroupMode, OpenEditorContext } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { GroupDirection, IEditorGroupsService, MergeGroupMode, OpenEditorContext } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
@@ -25,6 +25,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { assertIsDefined, assertAllDefined } from 'vs/base/common/types';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ByteSize } from 'vs/platform/files/common/files';
|
||||
|
||||
interface IDropOperation {
|
||||
splitDirection?: GroupDirection;
|
||||
@@ -34,7 +35,7 @@ class DropOverlay extends Themable {
|
||||
|
||||
private static readonly OVERLAY_ID = 'monaco-workbench-editor-drop-overlay';
|
||||
|
||||
private static readonly MAX_FILE_UPLOAD_SIZE = 100 * 1024 * 1024; // 100mb
|
||||
private static readonly MAX_FILE_UPLOAD_SIZE = 100 * ByteSize.MB;
|
||||
|
||||
private container: HTMLElement | undefined;
|
||||
private overlay: HTMLElement | undefined;
|
||||
@@ -54,7 +55,8 @@ class DropOverlay extends Themable {
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -143,8 +145,14 @@ class DropOverlay extends Themable {
|
||||
}
|
||||
}
|
||||
|
||||
// Position overlay
|
||||
this.positionOverlay(e.offsetX, e.offsetY, isDraggingGroup);
|
||||
// Position overlay and conditionally enable or disable
|
||||
// editor group splitting support based on setting and
|
||||
// keymodifiers used.
|
||||
let splitOnDragAndDrop = !!this.editorGroupService.partOptions.splitOnDragAndDrop;
|
||||
if (this.isToggleSplitOperation(e)) {
|
||||
splitOnDragAndDrop = !splitOnDragAndDrop;
|
||||
}
|
||||
this.positionOverlay(e.offsetX, e.offsetY, isDraggingGroup, splitOnDragAndDrop);
|
||||
|
||||
// Make sure to stop any running cleanup scheduler to remove the overlay
|
||||
if (this.cleanupOverlayScheduler.isScheduled()) {
|
||||
@@ -319,7 +327,7 @@ class DropOverlay extends Themable {
|
||||
// Try to come up with a good file path for the untitled
|
||||
// editor by asking the file dialog service for the default
|
||||
let proposedFilePath: URI | undefined = undefined;
|
||||
const defaultFilePath = this.fileDialogService.defaultFilePath();
|
||||
const defaultFilePath = await this.fileDialogService.defaultFilePath();
|
||||
if (defaultFilePath) {
|
||||
proposedFilePath = joinPath(defaultFilePath, name);
|
||||
}
|
||||
@@ -362,24 +370,33 @@ class DropOverlay extends Themable {
|
||||
return (e.ctrlKey && !isMacintosh) || (e.altKey && isMacintosh);
|
||||
}
|
||||
|
||||
private positionOverlay(mousePosX: number, mousePosY: number, isDraggingGroup: boolean): void {
|
||||
private isToggleSplitOperation(e: DragEvent): boolean {
|
||||
return (e.altKey && !isMacintosh) || (e.shiftKey && isMacintosh);
|
||||
}
|
||||
|
||||
private positionOverlay(mousePosX: number, mousePosY: number, isDraggingGroup: boolean, enableSplitting: boolean): void {
|
||||
const preferSplitVertically = this.accessor.partOptions.openSideBySideDirection === 'right';
|
||||
|
||||
const editorControlWidth = this.groupView.element.clientWidth;
|
||||
const editorControlHeight = this.groupView.element.clientHeight - this.getOverlayOffsetHeight();
|
||||
|
||||
let edgeWidthThresholdFactor: number;
|
||||
if (isDraggingGroup) {
|
||||
edgeWidthThresholdFactor = preferSplitVertically ? 0.3 : 0.1; // give larger threshold when dragging group depending on preferred split direction
|
||||
} else {
|
||||
edgeWidthThresholdFactor = 0.1; // 10% threshold to split if dragging editors
|
||||
}
|
||||
|
||||
let edgeHeightThresholdFactor: number;
|
||||
if (isDraggingGroup) {
|
||||
edgeHeightThresholdFactor = preferSplitVertically ? 0.1 : 0.3; // give larger threshold when dragging group depending on preferred split direction
|
||||
if (enableSplitting) {
|
||||
if (isDraggingGroup) {
|
||||
edgeWidthThresholdFactor = preferSplitVertically ? 0.3 : 0.1; // give larger threshold when dragging group depending on preferred split direction
|
||||
} else {
|
||||
edgeWidthThresholdFactor = 0.1; // 10% threshold to split if dragging editors
|
||||
}
|
||||
|
||||
if (isDraggingGroup) {
|
||||
edgeHeightThresholdFactor = preferSplitVertically ? 0.1 : 0.3; // give larger threshold when dragging group depending on preferred split direction
|
||||
} else {
|
||||
edgeHeightThresholdFactor = 0.1; // 10% threshold to split if dragging editors
|
||||
}
|
||||
} else {
|
||||
edgeHeightThresholdFactor = 0.1; // 10% threshold to split if dragging editors
|
||||
edgeWidthThresholdFactor = 0;
|
||||
edgeHeightThresholdFactor = 0;
|
||||
}
|
||||
|
||||
const edgeWidthThreshold = editorControlWidth * edgeWidthThresholdFactor;
|
||||
|
||||
@@ -1742,28 +1742,17 @@ class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
private override: (() => Promise<IEditorPane | undefined>) | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
private _group: GroupIdentifier,
|
||||
private _editor: EditorInput,
|
||||
public readonly groupId: GroupIdentifier,
|
||||
public readonly editor: EditorInput,
|
||||
private _options: EditorOptions | undefined,
|
||||
private _context: OpenEditorContext | undefined
|
||||
public readonly context: OpenEditorContext | undefined
|
||||
) {
|
||||
}
|
||||
|
||||
get groupId(): GroupIdentifier {
|
||||
return this._group;
|
||||
}
|
||||
|
||||
get editor(): EditorInput {
|
||||
return this._editor;
|
||||
}
|
||||
|
||||
get options(): EditorOptions | undefined {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
get context(): OpenEditorContext | undefined {
|
||||
return this._context;
|
||||
}
|
||||
|
||||
prevent(callback: () => Promise<IEditorPane | undefined>): void {
|
||||
this.override = callback;
|
||||
@@ -1775,9 +1764,9 @@ class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
}
|
||||
|
||||
export interface EditorReplacement {
|
||||
editor: EditorInput;
|
||||
replacement: EditorInput;
|
||||
options?: EditorOptions;
|
||||
readonly editor: EditorInput;
|
||||
readonly replacement: EditorInput;
|
||||
readonly options?: EditorOptions;
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector, environment) => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IEditorGroup, IEditorGroupsService, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { LRUCache, Touch } from 'vs/base/common/map';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -156,7 +156,7 @@ export abstract class EditorPane extends Composite implements IEditorPane {
|
||||
|
||||
let editorMemento = EditorPane.EDITOR_MEMENTOS.get(mementoKey);
|
||||
if (!editorMemento) {
|
||||
editorMemento = new EditorMemento(this.getId(), key, this.getMemento(StorageScope.WORKSPACE), limit, editorGroupService);
|
||||
editorMemento = new EditorMemento(this.getId(), key, this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE), limit, editorGroupService);
|
||||
EditorPane.EDITOR_MEMENTOS.set(mementoKey, editorMemento);
|
||||
}
|
||||
|
||||
@@ -220,18 +220,7 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
|
||||
// Automatically clear when editor input gets disposed if any
|
||||
if (resourceOrEditor instanceof EditorInput) {
|
||||
const editor = resourceOrEditor;
|
||||
|
||||
if (!this.editorDisposables) {
|
||||
this.editorDisposables = new Map<EditorInput, IDisposable>();
|
||||
}
|
||||
|
||||
if (!this.editorDisposables.has(editor)) {
|
||||
this.editorDisposables.set(editor, Event.once(resourceOrEditor.onDispose)(() => {
|
||||
this.clearEditorState(resource);
|
||||
this.editorDisposables?.delete(editor);
|
||||
}));
|
||||
}
|
||||
this.clearEditorStateOnDispose(resource, resourceOrEditor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +229,7 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
loadEditorState(group: IEditorGroup, resourceOrEditor: URI | EditorInput, fallbackToOtherGroupState?: boolean): T | undefined {
|
||||
const resource = this.doGetResource(resourceOrEditor);
|
||||
if (!resource || !group) {
|
||||
return undefined; // we are not in a good state to load any state for a resource
|
||||
return; // we are not in a good state to load any state for a resource
|
||||
}
|
||||
|
||||
const cache = this.doLoad();
|
||||
@@ -261,12 +250,16 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
clearEditorState(resource: URI, group?: IEditorGroup): void;
|
||||
clearEditorState(editor: EditorInput, group?: IEditorGroup): void;
|
||||
clearEditorState(resourceOrEditor: URI | EditorInput, group?: IEditorGroup): void {
|
||||
if (resourceOrEditor instanceof EditorInput) {
|
||||
this.editorDisposables?.delete(resourceOrEditor);
|
||||
}
|
||||
|
||||
const resource = this.doGetResource(resourceOrEditor);
|
||||
if (resource) {
|
||||
const cache = this.doLoad();
|
||||
@@ -286,6 +279,19 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
}
|
||||
}
|
||||
|
||||
clearEditorStateOnDispose(resource: URI, editor: EditorInput): void {
|
||||
if (!this.editorDisposables) {
|
||||
this.editorDisposables = new Map<EditorInput, IDisposable>();
|
||||
}
|
||||
|
||||
if (!this.editorDisposables.has(editor)) {
|
||||
this.editorDisposables.set(editor, Event.once(editor.onDispose)(() => {
|
||||
this.clearEditorState(resource);
|
||||
this.editorDisposables?.delete(editor);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
moveEditorState(source: URI, target: URI, comparer: IExtUri): void {
|
||||
const cache = this.doLoad();
|
||||
|
||||
@@ -342,7 +348,7 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
saveState(): void {
|
||||
const cache = this.doLoad();
|
||||
|
||||
// Cleanup once during shutdown
|
||||
// Cleanup once during session
|
||||
if (!this.cleanedUp) {
|
||||
this.cleanUp();
|
||||
this.cleanedUp = true;
|
||||
|
||||
@@ -19,7 +19,7 @@ import { IEditorGroupsAccessor, IEditorGroupView, getEditorPartOptions, impactsE
|
||||
import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { EditorDropTarget, IEditorDropTargetDelegate } from 'vs/workbench/browser/parts/editor/editorDropTarget';
|
||||
import { IEditorDropService } from 'vs/workbench/services/editor/browser/editorDropService';
|
||||
@@ -148,8 +148,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
this.gridWidgetView = new GridWidgetView<IEditorGroupView>();
|
||||
|
||||
this.workspaceMemento = this.getMemento(StorageScope.WORKSPACE);
|
||||
this.globalMemento = this.getMemento(StorageScope.GLOBAL);
|
||||
this.workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE);
|
||||
this.globalMemento = this.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
|
||||
this._whenRestored = new Promise(resolve => (this.whenRestoredResolve = resolve));
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/editorstatus';
|
||||
import * as nls from 'vs/nls';
|
||||
import { runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { format, compare } from 'vs/base/common/strings';
|
||||
import { format, compare, splitLines } from 'vs/base/common/strings';
|
||||
import { extname, basename, isEqual } from 'vs/base/common/resources';
|
||||
import { areFunctions, withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -346,12 +346,12 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
[{
|
||||
label: nls.localize('screenReaderDetectedExplanation.answerYes', "Yes"),
|
||||
run: () => {
|
||||
this.configurationService.updateValue('editor.accessibilitySupport', 'on', ConfigurationTarget.USER);
|
||||
this.configurationService.updateValue('editor.accessibilitySupport', 'on');
|
||||
}
|
||||
}, {
|
||||
label: nls.localize('screenReaderDetectedExplanation.answerNo', "No"),
|
||||
run: () => {
|
||||
this.configurationService.updateValue('editor.accessibilitySupport', 'off', ConfigurationTarget.USER);
|
||||
this.configurationService.updateValue('editor.accessibilitySupport', 'off');
|
||||
}
|
||||
}],
|
||||
{ sticky: true }
|
||||
@@ -918,7 +918,7 @@ class ShowCurrentMarkerInStatusbarContribution extends Disposable {
|
||||
this.currentMarker = this.getMarker();
|
||||
if (this.hasToUpdateStatus(previousMarker, this.currentMarker)) {
|
||||
if (this.currentMarker) {
|
||||
const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0];
|
||||
const line = splitLines(this.currentMarker.message)[0];
|
||||
const text = `${this.getType(this.currentMarker)} ${line}`;
|
||||
if (!this.statusBarEntryAccessor.value) {
|
||||
this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text: '', ariaLabel: '' }, 'statusbar.currentProblem', nls.localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT);
|
||||
@@ -1046,12 +1046,19 @@ export class ChangeModeAction extends Action {
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ITextFileService private readonly textFileService: ITextFileService
|
||||
@ITextFileService private readonly textFileService: ITextFileService,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
const activeEditorPane = this.editorService.activeEditorPane as unknown as { isNotebookEditor?: boolean } | undefined;
|
||||
if (activeEditorPane?.isNotebookEditor) {
|
||||
// it's inside notebook editor
|
||||
return this.commandService.executeCommand('notebook.cell.changeLanguage');
|
||||
}
|
||||
|
||||
const activeTextEditorControl = getCodeEditor(this.editorService.activeTextEditorControl);
|
||||
if (!activeTextEditorControl) {
|
||||
await this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]);
|
||||
@@ -1143,7 +1150,7 @@ export class ChangeModeAction extends Action {
|
||||
|
||||
// User decided to configure settings for current language
|
||||
if (pick === configureModeSettings) {
|
||||
this.preferencesService.openGlobalSettings(true, { editSetting: `[${withUndefinedAsNull(currentModeId)}]` });
|
||||
this.preferencesService.openGlobalSettings(true, { revealSetting: { key: `[${withUndefinedAsNull(currentModeId)}]`, edit: true } });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ export class FloatingClickWidget extends Widget implements IOverlayWidget {
|
||||
super();
|
||||
|
||||
this._domNode = $('.floating-click-widget');
|
||||
this._domNode.style.padding = '10px';
|
||||
this._domNode.style.cursor = 'pointer';
|
||||
|
||||
if (keyBindingAction) {
|
||||
const keybinding = keybindingService.lookupKeybinding(keyBindingAction);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { IEditorInput, IEditorInputFactoryRegistry, IEditorIdentifier, GroupIdentifier, Extensions, IEditorPartOptionsChangeEvent, EditorsOrder, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
@@ -339,7 +339,7 @@ export class EditorsObserver extends Disposable {
|
||||
if (this.mostRecentEditorsMap.isEmpty()) {
|
||||
this.storageService.remove(EditorsObserver.STORAGE_KEY, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.storageService.store(EditorsObserver.STORAGE_KEY, JSON.stringify(this.serialize()), StorageScope.WORKSPACE);
|
||||
this.storageService.store(EditorsObserver.STORAGE_KEY, JSON.stringify(this.serialize()), StorageScope.WORKSPACE, StorageTarget.MACHINE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
/* todo@joh move somewhere else */
|
||||
/* breadcrumbs-picker-style */
|
||||
|
||||
.monaco-workbench .monaco-breadcrumbs-picker .arrow {
|
||||
position: absolute;
|
||||
|
||||
@@ -589,8 +589,8 @@ export class TabsTitleControl extends TitleControl {
|
||||
|
||||
const tabActionRunner = new EditorCommandsContextActionRunner({ groupId: this.group.id, editorIndex: index });
|
||||
|
||||
const tabActionBar = new ActionBar(tabActionsContainer, { ariaLabel: localize('ariaLabelTabActions', "Tab actions"), actionRunner: tabActionRunner, });
|
||||
tabActionBar.onDidBeforeRun(e => {
|
||||
const tabActionBar = new ActionBar(tabActionsContainer, { ariaLabel: localize('ariaLabelTabActions', "Tab actions"), actionRunner: tabActionRunner });
|
||||
tabActionBar.onBeforeRun(e => {
|
||||
if (e.action.id === this.closeEditorAction.id) {
|
||||
this.blockRevealActiveTabOnce();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { ScrollType, IDiffEditorViewState, IDiffEditorModel } from 'vs/editor/co
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -32,6 +31,7 @@ import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/edit
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { multibyteAwareBtoa } from 'vs/base/browser/dom';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
/**
|
||||
* The text editor that leverages the diff text editor for the editing experience.
|
||||
@@ -62,9 +62,28 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
@ITextResourceConfigurationService configurationService: ITextResourceConfigurationService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, editorService, editorGroupService);
|
||||
|
||||
// Listen to file system provider changes
|
||||
this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onDidFileSystemProviderChange(e.scheme)));
|
||||
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onDidFileSystemProviderChange(e.scheme)));
|
||||
}
|
||||
|
||||
private onDidFileSystemProviderChange(scheme: string): void {
|
||||
const control = this.getControl();
|
||||
const input = this.input;
|
||||
|
||||
if (control && input instanceof DiffEditorInput) {
|
||||
if (input.originalInput.resource?.scheme === scheme || input.modifiedInput.resource?.scheme === scheme) {
|
||||
control.updateOptions({
|
||||
readOnly: input.modifiedInput.isReadonly(),
|
||||
originalEditable: !input.originalInput.isReadonly()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected onWillCloseEditorInGroup(editor: IEditorInput): void {
|
||||
@@ -175,7 +194,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
const originalInput = input.originalInput;
|
||||
const modifiedInput = input.modifiedInput;
|
||||
|
||||
const binaryDiffInput = new DiffEditorInput(input.getName(), input.getDescription(), originalInput, modifiedInput, true);
|
||||
const binaryDiffInput = this.instantiationService.createInstance(DiffEditorInput, input.getName(), input.getDescription(), originalInput, modifiedInput, true);
|
||||
|
||||
// Forward binary flag to input if supported
|
||||
const fileEditorInputFactory = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).getFileEditorInputFactory();
|
||||
@@ -217,16 +236,17 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
|
||||
// Handle diff editor specially by merging in diffEditor configuration
|
||||
if (isObject(configuration.diffEditor)) {
|
||||
// User settings defines `diffEditor.codeLens`, but there is also `editor.codeLens`.
|
||||
// Due to the mixin, the two settings cannot be distinguished anymore.
|
||||
//
|
||||
// So we map `diffEditor.codeLens` to `diffEditor.originalCodeLens` and `diffEditor.modifiedCodeLens`.
|
||||
const diffEditorConfiguration = <IDiffEditorOptions>objects.deepClone(configuration.diffEditor);
|
||||
diffEditorConfiguration.originalCodeLens = diffEditorConfiguration.codeLens;
|
||||
diffEditorConfiguration.modifiedCodeLens = diffEditorConfiguration.codeLens;
|
||||
|
||||
// User settings defines `diffEditor.codeLens`, but here we rename that to `diffEditor.diffCodeLens` to avoid collisions with `editor.codeLens`.
|
||||
diffEditorConfiguration.diffCodeLens = diffEditorConfiguration.codeLens;
|
||||
delete diffEditorConfiguration.codeLens;
|
||||
|
||||
objects.mixin(editorConfiguration, diffEditorConfiguration);
|
||||
// User settings defines `diffEditor.wordWrap`, but here we rename that to `diffEditor.diffWordWrap` to avoid collisions with `editor.wordWrap`.
|
||||
diffEditorConfiguration.diffWordWrap = <'off' | 'on' | 'inherit' | undefined>diffEditorConfiguration.wordWrap;
|
||||
delete diffEditorConfiguration.wordWrap;
|
||||
|
||||
Object.assign(editorConfiguration, diffEditorConfiguration);
|
||||
}
|
||||
|
||||
return editorConfiguration;
|
||||
@@ -309,12 +329,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
||||
|
||||
// Otherwise save it
|
||||
else {
|
||||
super.saveTextEditorViewState(resource);
|
||||
|
||||
// Make sure to clean up when the input gets disposed
|
||||
Event.once(input.onDispose)(() => {
|
||||
super.clearTextEditorViewState([resource], this.group);
|
||||
});
|
||||
super.saveTextEditorViewState(resource, input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ export abstract class BaseTextEditor extends EditorPane implements ITextEditorPa
|
||||
@IEditorGroupsService protected editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, telemetryService, themeService, storageService);
|
||||
|
||||
this._instantiationService = instantiationService;
|
||||
|
||||
this.editorMemento = this.getEditorMemento<IEditorViewState>(editorGroupService, BaseTextEditor.TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY, 100);
|
||||
@@ -223,13 +224,27 @@ export abstract class BaseTextEditor extends EditorPane implements ITextEditorPa
|
||||
return this.editorControl;
|
||||
}
|
||||
|
||||
protected saveTextEditorViewState(resource: URI): void {
|
||||
getViewState(): IEditorViewState | undefined {
|
||||
const resource = this.input?.resource;
|
||||
if (resource) {
|
||||
return withNullAsUndefined(this.retrieveTextEditorViewState(resource));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
protected saveTextEditorViewState(resource: URI, cleanUpOnDispose?: IEditorInput): void {
|
||||
const editorViewState = this.retrieveTextEditorViewState(resource);
|
||||
if (!editorViewState || !this.group) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editorMemento.saveEditorState(this.group, resource, editorViewState);
|
||||
|
||||
if (cleanUpOnDispose) {
|
||||
this.editorMemento.clearEditorStateOnDispose(resource, cleanUpOnDispose);
|
||||
}
|
||||
}
|
||||
|
||||
protected shouldRestoreTextEditorViewState(editor: IEditorInput, context?: IEditorOpenContext): boolean {
|
||||
@@ -243,15 +258,6 @@ export abstract class BaseTextEditor extends EditorPane implements ITextEditorPa
|
||||
return true;
|
||||
}
|
||||
|
||||
getViewState(): IEditorViewState | undefined {
|
||||
const resource = this.input?.resource;
|
||||
if (resource) {
|
||||
return withNullAsUndefined(this.retrieveTextEditorViewState(resource));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected retrieveTextEditorViewState(resource: URI): IEditorViewState | null {
|
||||
const control = this.getControl();
|
||||
if (!isCodeEditor(control)) {
|
||||
@@ -284,9 +290,9 @@ export abstract class BaseTextEditor extends EditorPane implements ITextEditorPa
|
||||
}
|
||||
|
||||
protected clearTextEditorViewState(resources: URI[], group?: IEditorGroup): void {
|
||||
resources.forEach(resource => {
|
||||
for (const resource of resources) {
|
||||
this.editorMemento.clearEditorState(resource, group);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateEditorConfiguration(configuration?: IEditorConfiguration): void {
|
||||
|
||||
@@ -16,7 +16,6 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ScrollType, IEditor } from 'vs/editor/common/editorCommon';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -158,12 +157,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
|
||||
// Otherwise save it
|
||||
else {
|
||||
super.saveTextEditorViewState(resource);
|
||||
|
||||
// Make sure to clean up when the input gets disposed
|
||||
Event.once(input.onDispose)(() => {
|
||||
super.clearTextEditorViewState([resource]);
|
||||
});
|
||||
super.saveTextEditorViewState(resource, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,18 +105,27 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container > .monaco-button-dropdown,
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container > .monaco-button {
|
||||
margin: 4px 5px; /* allows button focus outline to be visible */
|
||||
}
|
||||
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container .monaco-button {
|
||||
outline-offset: 2px !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container .monaco-text-button {
|
||||
width: fit-content;
|
||||
width: -moz-fit-content;
|
||||
padding: 5px 10px;
|
||||
margin: 4px 5px; /* allows button focus outline to be visible */
|
||||
display: inline-block; /* to enable ellipsis in text overflow */
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container .monaco-text-button {
|
||||
display: inline-block; /* to enable ellipsis in text overflow */
|
||||
.monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-buttons-container .monaco-dropdown-button {
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
/** Notification: Progress */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
|
||||
.monaco-workbench > .notifications-toasts .notification-toast-container > .notification-toast {
|
||||
margin: 5px; /* enables separation and drop shadows around toasts */
|
||||
margin: 8px; /* enables separation and drop shadows around toasts */
|
||||
transform: translate3d(0px, 100%, 0px); /* move the notification 50px to the bottom (to prevent bleed through) */
|
||||
opacity: 0; /* fade the toast in */
|
||||
transition: transform 300ms ease-out, opacity 300ms ease-out;
|
||||
|
||||
@@ -12,14 +12,16 @@ 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';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
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);
|
||||
const clearIcon = registerIcon('notifications-clear', Codicon.close, localize('clearIcon', 'Icon for the clear action in notifications.'));
|
||||
const clearAllIcon = registerIcon('notifications-clear-all', Codicon.clearAll, localize('clearAllIcon', 'Icon for the clear all action in notifications.'));
|
||||
const hideIcon = registerIcon('notifications-hide', Codicon.chevronDown, localize('hideIcon', 'Icon for the hide action in notifications.'));
|
||||
const expandIcon = registerIcon('notifications-expand', Codicon.chevronUp, localize('expandIcon', 'Icon for the expand action in notifications.'));
|
||||
const collapseIcon = registerIcon('notifications-collapse', Codicon.chevronDown, localize('collapseIcon', 'Icon for the collapse action in notifications.'));
|
||||
const configureIcon = registerIcon('notifications-configure', Codicon.gear, localize('configureIcon', 'Icon for the configure action in notifications.'));
|
||||
|
||||
export class ClearNotificationAction extends Action {
|
||||
|
||||
@@ -31,7 +33,7 @@ export class ClearNotificationAction extends Action {
|
||||
label: string,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, clearIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(clearIcon));
|
||||
}
|
||||
|
||||
async run(notification: INotificationViewItem): Promise<void> {
|
||||
@@ -49,7 +51,7 @@ export class ClearAllNotificationsAction extends Action {
|
||||
label: string,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, clearAllIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(clearAllIcon));
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
@@ -67,7 +69,7 @@ export class HideNotificationsCenterAction extends Action {
|
||||
label: string,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, hideIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(hideIcon));
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
@@ -85,7 +87,7 @@ export class ExpandNotificationAction extends Action {
|
||||
label: string,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, expandIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(expandIcon));
|
||||
}
|
||||
|
||||
async run(notification: INotificationViewItem): Promise<void> {
|
||||
@@ -103,7 +105,7 @@ export class CollapseNotificationAction extends Action {
|
||||
label: string,
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, collapseIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(collapseIcon));
|
||||
}
|
||||
|
||||
async run(notification: INotificationViewItem): Promise<void> {
|
||||
@@ -121,7 +123,7 @@ export class ConfigureNotificationAction extends Action {
|
||||
label: string,
|
||||
public readonly configurationActions: ReadonlyArray<IAction>
|
||||
) {
|
||||
super(id, label, configureIcon.classNames);
|
||||
super(id, label, ThemeIcon.asClassName(configureIcon));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ export class NotificationsCenter extends Themable implements INotificationsCente
|
||||
protected updateStyles(): void {
|
||||
if (this.notificationsCenterContainer && this.notificationsCenterHeader) {
|
||||
const widgetShadowColor = this.getColor(widgetShadow);
|
||||
this.notificationsCenterContainer.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : '';
|
||||
this.notificationsCenterContainer.style.boxShadow = widgetShadowColor ? `0 0 8px 2px ${widgetShadowColor}` : '';
|
||||
|
||||
const borderColor = this.getColor(NOTIFICATIONS_CENTER_BORDER);
|
||||
this.notificationsCenterContainer.style.border = borderColor ? `1px solid ${borderColor}` : '';
|
||||
|
||||
@@ -15,20 +15,20 @@ import { IListService, WorkbenchList } from 'vs/platform/list/browser/listServic
|
||||
// Center
|
||||
export const SHOW_NOTIFICATIONS_CENTER = 'notifications.showList';
|
||||
export const HIDE_NOTIFICATIONS_CENTER = 'notifications.hideList';
|
||||
export const TOGGLE_NOTIFICATIONS_CENTER = 'notifications.toggleList';
|
||||
const TOGGLE_NOTIFICATIONS_CENTER = 'notifications.toggleList';
|
||||
|
||||
// Toasts
|
||||
export const HIDE_NOTIFICATION_TOAST = 'notifications.hideToasts';
|
||||
export const FOCUS_NOTIFICATION_TOAST = 'notifications.focusToasts';
|
||||
export const FOCUS_NEXT_NOTIFICATION_TOAST = 'notifications.focusNextToast';
|
||||
export const FOCUS_PREVIOUS_NOTIFICATION_TOAST = 'notifications.focusPreviousToast';
|
||||
export const FOCUS_FIRST_NOTIFICATION_TOAST = 'notifications.focusFirstToast';
|
||||
export const FOCUS_LAST_NOTIFICATION_TOAST = 'notifications.focusLastToast';
|
||||
const HIDE_NOTIFICATION_TOAST = 'notifications.hideToasts';
|
||||
const FOCUS_NOTIFICATION_TOAST = 'notifications.focusToasts';
|
||||
const FOCUS_NEXT_NOTIFICATION_TOAST = 'notifications.focusNextToast';
|
||||
const FOCUS_PREVIOUS_NOTIFICATION_TOAST = 'notifications.focusPreviousToast';
|
||||
const FOCUS_FIRST_NOTIFICATION_TOAST = 'notifications.focusFirstToast';
|
||||
const FOCUS_LAST_NOTIFICATION_TOAST = 'notifications.focusLastToast';
|
||||
|
||||
// Notification
|
||||
export const COLLAPSE_NOTIFICATION = 'notification.collapse';
|
||||
export const EXPAND_NOTIFICATION = 'notification.expand';
|
||||
export const TOGGLE_NOTIFICATION = 'notification.toggle';
|
||||
const TOGGLE_NOTIFICATION = 'notification.toggle';
|
||||
export const CLEAR_NOTIFICATION = 'notification.clear';
|
||||
export const CLEAR_ALL_NOTIFICATIONS = 'notifications.clearAll';
|
||||
|
||||
@@ -159,12 +159,20 @@ export function registerNotificationCommands(center: INotificationsCenterControl
|
||||
});
|
||||
|
||||
// Hide Toasts
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
CommandsRegistry.registerCommand(HIDE_NOTIFICATION_TOAST, accessor => toasts.hide());
|
||||
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: HIDE_NOTIFICATION_TOAST,
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
weight: KeybindingWeight.WorkbenchContrib - 50, // lower when not focused (e.g. let editor suggest win over this command)
|
||||
when: NotificationsToastsVisibleContext,
|
||||
primary: KeyCode.Escape,
|
||||
handler: accessor => toasts.hide()
|
||||
primary: KeyCode.Escape
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: HIDE_NOTIFICATION_TOAST,
|
||||
weight: KeybindingWeight.WorkbenchContrib + 100, // higher when focused
|
||||
when: ContextKeyExpr.and(NotificationsToastsVisibleContext, NotificationFocusedContext),
|
||||
primary: KeyCode.Escape
|
||||
});
|
||||
|
||||
// Focus Toasts
|
||||
|
||||
@@ -482,7 +482,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
|
||||
toast.style.background = backgroundColor ? backgroundColor : '';
|
||||
|
||||
const widgetShadowColor = this.getColor(widgetShadow);
|
||||
toast.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : '';
|
||||
toast.style.boxShadow = widgetShadowColor ? `0 0 8px 2px ${widgetShadowColor}` : '';
|
||||
|
||||
const borderColor = this.getColor(NOTIFICATIONS_TOAST_BORDER);
|
||||
toast.style.border = borderColor ? `1px solid ${borderColor}` : '';
|
||||
|
||||
@@ -8,11 +8,11 @@ import { clearNode, addDisposableListener, EventType, EventHelper, $ } from 'vs/
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ButtonGroup } from 'vs/base/browser/ui/button/button';
|
||||
import { ButtonBar } from 'vs/base/browser/ui/button/button';
|
||||
import { attachButtonStyler, attachProgressBarStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { ActionRunner, ActionWithMenuAction, IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { dispose, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -285,7 +285,8 @@ export class NotificationTemplateRenderer extends Disposable {
|
||||
@IOpenerService private readonly openerService: IOpenerService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -441,27 +442,40 @@ export class NotificationTemplateRenderer extends Disposable {
|
||||
|
||||
const primaryActions = notification.actions ? notification.actions.primary : undefined;
|
||||
if (notification.expanded && isNonEmptyArray(primaryActions)) {
|
||||
const buttonGroup = new ButtonGroup(this.template.buttonsContainer, primaryActions.length, { title: true /* assign titles to buttons in case they overflow */ });
|
||||
buttonGroup.buttons.forEach((button, index) => {
|
||||
const action = primaryActions[index];
|
||||
button.label = action.label;
|
||||
|
||||
this.inputDisposables.add(button.onDidClick(e => {
|
||||
EventHelper.stop(e, true);
|
||||
|
||||
const that = this;
|
||||
const actionRunner: IActionRunner = new class extends ActionRunner {
|
||||
protected async runAction(action: IAction): Promise<void> {
|
||||
// Run action
|
||||
this.actionRunner.run(action, notification);
|
||||
that.actionRunner.run(action, notification);
|
||||
|
||||
// Hide notification (unless explicitly prevented)
|
||||
if (!(action instanceof ChoiceAction) || !action.keepOpen) {
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
}();
|
||||
const buttonToolbar = this.inputDisposables.add(new ButtonBar(this.template.buttonsContainer));
|
||||
for (const action of primaryActions) {
|
||||
const buttonOptions = { title: true, /* assign titles to buttons in case they overflow */ };
|
||||
const dropdownActions = action instanceof ChoiceAction ? action.menu
|
||||
: action instanceof ActionWithMenuAction ? action.actions : undefined;
|
||||
const button = this.inputDisposables.add(
|
||||
dropdownActions
|
||||
? buttonToolbar.addButtonWithDropdown({
|
||||
...buttonOptions,
|
||||
contextMenuProvider: this.contextMenuService,
|
||||
actions: dropdownActions,
|
||||
actionRunner
|
||||
})
|
||||
: buttonToolbar.addButton(buttonOptions));
|
||||
button.label = action.label;
|
||||
this.inputDisposables.add(button.onDidClick(e => {
|
||||
EventHelper.stop(e, true);
|
||||
actionRunner.run(action);
|
||||
}));
|
||||
|
||||
this.inputDisposables.add(attachButtonStyler(button, this.themeService));
|
||||
});
|
||||
|
||||
this.inputDisposables.add(buttonGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,10 +84,6 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel > .composite.title > .composite-bar-excess {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel > .composite.title> .panel-switcher-container > .monaco-action-bar {
|
||||
line-height: 27px; /* matches panel titles in settings */
|
||||
height: 35px;
|
||||
|
||||
@@ -18,11 +18,13 @@ 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';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const maximizeIcon = registerIcon('panel-maximize', Codicon.chevronUp);
|
||||
const restoreIcon = registerIcon('panel-restore', Codicon.chevronDown);
|
||||
const closeIcon = registerIcon('panel-close', Codicon.close);
|
||||
const maximizeIcon = registerIcon('panel-maximize', Codicon.chevronUp, nls.localize('maximizeIcon', 'Icon to maximize a panel.'));
|
||||
const restoreIcon = registerIcon('panel-restore', Codicon.chevronDown, nls.localize('restoreIcon', 'Icon to restore a panel.'));
|
||||
const closeIcon = registerIcon('panel-close', Codicon.close, nls.localize('closeIcon', 'Icon to close a panel.'));
|
||||
|
||||
export class ClosePanelAction extends Action {
|
||||
|
||||
@@ -34,7 +36,7 @@ export class ClosePanelAction extends Action {
|
||||
name: string,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
|
||||
) {
|
||||
super(id, name, closeIcon.classNames);
|
||||
super(id, name, ThemeIcon.asClassName(closeIcon));
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
@@ -106,11 +108,11 @@ export class ToggleMaximizedPanelAction extends Action {
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@IEditorGroupsService editorGroupsService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label, layoutService.isPanelMaximized() ? restoreIcon.classNames : maximizeIcon.classNames);
|
||||
super(id, label, layoutService.isPanelMaximized() ? ThemeIcon.asClassName(restoreIcon) : ThemeIcon.asClassName(maximizeIcon));
|
||||
|
||||
this.toDispose.add(editorGroupsService.onDidLayout(() => {
|
||||
const maximized = this.layoutService.isPanelMaximized();
|
||||
this.class = maximized ? restoreIcon.classNames : maximizeIcon.classNames;
|
||||
this.class = maximized ? ThemeIcon.asClassName(restoreIcon) : ThemeIcon.asClassName(maximizeIcon);
|
||||
this.label = maximized ? ToggleMaximizedPanelAction.RESTORE_LABEL : ToggleMaximizedPanelAction.MAXIMIZE_LABEL;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { CompositePart, ICompositeTitleLabel } from 'vs/workbench/browser/parts/
|
||||
import { Panel, PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
|
||||
import { IPanelService, IPanelIdentifier } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IWorkbenchLayoutService, Parts, Position } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -37,7 +37,6 @@ import { ViewContainer, IViewDescriptorService, IViewContainerModel, ViewContain
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ViewMenuActions, ViewContainerMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
|
||||
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Before2D, CompositeDragAndDropObserver, ICompositeDragAndDrop, toggleDropEffect } from 'vs/workbench/browser/dnd';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
|
||||
@@ -118,7 +117,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
|
||||
) {
|
||||
super(
|
||||
notificationService,
|
||||
@@ -140,7 +138,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
);
|
||||
|
||||
this.panelRegistry = Registry.as<PanelRegistry>(PanelExtensions.Panels);
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: PanelPart.PINNED_PANELS, version: 1 });
|
||||
|
||||
this.dndHandler = new CompositeDragAndDrop(this.viewDescriptorService, ViewContainerLocation.Panel,
|
||||
(id: string, focus?: boolean) => (this.openPanel(id, focus) as Promise<IPaneComposite | undefined>).then(panel => panel || null),
|
||||
@@ -338,7 +335,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedPanels(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
}
|
||||
@@ -670,7 +667,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
return this.toolBar.getItemsWidth();
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(e: IStorageValueChangeEvent): void {
|
||||
if (e.key === PanelPart.PINNED_PANELS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedPanelsValue !== this.getStoredCachedPanelsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedPanelsValue = undefined;
|
||||
@@ -760,7 +757,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
private setStoredCachedViewletsValue(value: string): void {
|
||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||
@@ -792,7 +789,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
private setStoredPlaceholderViewContainersValue(value: string): void {
|
||||
this.storageService.store(PanelPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.WORKSPACE);
|
||||
this.storageService.store(PanelPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.WORKSPACE, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
private getViewContainer(panelId: string): ViewContainer | undefined {
|
||||
|
||||
@@ -23,7 +23,7 @@ import { isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { EventHelper, createStyleSheet, addDisposableListener, EventType, hide, show, isAncestor, appendChildren } from 'vs/base/browser/dom';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
@@ -32,7 +32,6 @@ import { ToggleStatusbarVisibilityAction } from 'vs/workbench/browser/actions/la
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Command } from 'vs/editor/common/modes';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
@@ -102,10 +101,10 @@ class StatusbarViewModel extends Disposable {
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
this._register(this.storageService.onDidChangeValue(e => this.onDidStorageValueChange(e)));
|
||||
}
|
||||
|
||||
private onDidStorageChange(event: IWorkspaceStorageChangeEvent): void {
|
||||
private onDidStorageValueChange(event: IStorageValueChangeEvent): void {
|
||||
if (event.key === StatusbarViewModel.HIDDEN_ENTRIES_KEY && event.scope === StorageScope.GLOBAL) {
|
||||
|
||||
// Keep current hidden entries
|
||||
@@ -275,7 +274,7 @@ class StatusbarViewModel extends Disposable {
|
||||
|
||||
private saveState(): void {
|
||||
if (this.hidden.size > 0) {
|
||||
this.storageService.store(StatusbarViewModel.HIDDEN_ENTRIES_KEY, JSON.stringify(Array.from(this.hidden.values())), StorageScope.GLOBAL);
|
||||
this.storageService.store(StatusbarViewModel.HIDDEN_ENTRIES_KEY, JSON.stringify(Array.from(this.hidden.values())), StorageScope.GLOBAL, StorageTarget.USER);
|
||||
} else {
|
||||
this.storageService.remove(StatusbarViewModel.HIDDEN_ENTRIES_KEY, StorageScope.GLOBAL);
|
||||
}
|
||||
@@ -405,12 +404,9 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
|
||||
) {
|
||||
super(Parts.STATUSBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: StatusbarViewModel.HIDDEN_ENTRIES_KEY, version: 1 });
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/actions';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { isMacintosh, isWeb, isIOS } from 'vs/base/common/platform';
|
||||
import { isMacintosh, isWeb, isIOS, isNative } from 'vs/base/common/platform';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@@ -21,7 +21,7 @@ import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SEL
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IUpdateService, StateType } from 'vs/platform/update/common/update';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
@@ -122,7 +122,7 @@ export abstract class MenubarControl extends Disposable {
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e)));
|
||||
|
||||
// Listen to update service
|
||||
this.updateService.onStateChange(() => this.updateMenubar());
|
||||
this.updateService.onStateChange(() => this.onUpdateStateChange());
|
||||
|
||||
// Listen for changes in recently opened menu
|
||||
this._register(this.workspacesService.onRecentlyOpenedChange(() => { this.onRecentlyOpenedChange(); }));
|
||||
@@ -148,6 +148,14 @@ export abstract class MenubarControl extends Disposable {
|
||||
return label;
|
||||
}
|
||||
|
||||
protected onUpdateStateChange(): void {
|
||||
this.updateMenubar();
|
||||
}
|
||||
|
||||
protected onUpdateKeybindings(): void {
|
||||
this.updateMenubar();
|
||||
}
|
||||
|
||||
protected getOpenRecentActions(): (Separator | IAction & { uri: URI })[] {
|
||||
if (!this.recentlyOpened) {
|
||||
return [];
|
||||
@@ -191,13 +199,27 @@ export abstract class MenubarControl extends Disposable {
|
||||
if (event.affectsConfiguration('editor.accessibilitySupport')) {
|
||||
this.notifyUserOfCustomMenubarAccessibility();
|
||||
}
|
||||
|
||||
// Since we try not update when hidden, we should
|
||||
// try to update the recently opened list on visibility changes
|
||||
if (event.affectsConfiguration('window.menuBarVisibility')) {
|
||||
this.onRecentlyOpenedChange();
|
||||
}
|
||||
}
|
||||
|
||||
private onRecentlyOpenedChange(): void {
|
||||
this.workspacesService.getRecentlyOpened().then(recentlyOpened => {
|
||||
this.recentlyOpened = recentlyOpened;
|
||||
this.updateMenubar();
|
||||
});
|
||||
private get menubarHidden(): boolean {
|
||||
return isMacintosh && isNative ? false : getMenuBarVisibility(this.configurationService) === 'hidden';
|
||||
}
|
||||
|
||||
protected onRecentlyOpenedChange(): void {
|
||||
|
||||
// Do not update recently opened when the menubar is hidden #108712
|
||||
if (!this.menubarHidden) {
|
||||
this.workspacesService.getRecentlyOpened().then(recentlyOpened => {
|
||||
this.recentlyOpened = recentlyOpened;
|
||||
this.updateMenubar();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private createOpenRecentMenuAction(recent: IRecent): IAction & { uri: URI } {
|
||||
@@ -241,7 +263,7 @@ export abstract class MenubarControl extends Disposable {
|
||||
}
|
||||
|
||||
const hasBeenNotified = this.storageService.getBoolean('menubar/accessibleMenubarNotified', StorageScope.GLOBAL, false);
|
||||
const usingCustomMenubar = getTitleBarStyle(this.configurationService, this.environmentService) === 'custom';
|
||||
const usingCustomMenubar = getTitleBarStyle(this.configurationService) === 'custom';
|
||||
|
||||
if (hasBeenNotified || usingCustomMenubar || !this.accessibilityService.isScreenReaderOptimized()) {
|
||||
return;
|
||||
@@ -257,7 +279,7 @@ export abstract class MenubarControl extends Disposable {
|
||||
}
|
||||
]);
|
||||
|
||||
this.storageService.store('menubar/accessibleMenubarNotified', true, StorageScope.GLOBAL);
|
||||
this.storageService.store('menubar/accessibleMenubarNotified', true, StorageScope.GLOBAL, StorageTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,6 +288,7 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
private container: HTMLElement | undefined;
|
||||
private alwaysOnMnemonics: boolean = false;
|
||||
private focusInsideMenubar: boolean = false;
|
||||
private visible: boolean = true;
|
||||
|
||||
private readonly _onVisibilityChange: Emitter<boolean>;
|
||||
private readonly _onFocusStateChange: Emitter<boolean>;
|
||||
@@ -475,7 +498,7 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
}
|
||||
|
||||
private get currentMenubarVisibility(): MenuBarVisibility {
|
||||
return getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
return getMenuBarVisibility(this.configurationService);
|
||||
}
|
||||
|
||||
private get currentDisableMenuBarAltFocus(): boolean {
|
||||
@@ -530,6 +553,12 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
return currentSidebarLocation === 'right' ? Direction.Left : Direction.Right;
|
||||
}
|
||||
|
||||
private onDidVisibilityChange(visible: boolean): void {
|
||||
this.visible = visible;
|
||||
this.onRecentlyOpenedChange();
|
||||
this._onVisibilityChange.fire(visible);
|
||||
}
|
||||
|
||||
private setupCustomMenubar(firstTime: boolean): void {
|
||||
// If there is no container, we cannot setup the menubar
|
||||
if (!this.container) {
|
||||
@@ -554,7 +583,7 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this.menubar.onVisibilityChange(e => this._onVisibilityChange.fire(e)));
|
||||
this._register(this.menubar.onVisibilityChange(e => this.onDidVisibilityChange(e)));
|
||||
|
||||
// Before we focus the menubar, stop updates to it so that focus-related context keys will work
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_IN, () => {
|
||||
@@ -645,29 +674,15 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
visibility: this.currentMenubarVisibility,
|
||||
getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id),
|
||||
alwaysOnMnemonics: this.alwaysOnMnemonics,
|
||||
compactMode: this.currentCompactMenuMode,
|
||||
getCompactMenuActions: () => {
|
||||
if (!isWeb) {
|
||||
return []; // only for web
|
||||
}
|
||||
|
||||
const webNavigationActions: IAction[] = [];
|
||||
const webNavigationMenu = this.menuService.createMenu(MenuId.MenubarWebNavigationMenu, this.contextKeyService);
|
||||
for (const groups of webNavigationMenu.getActions()) {
|
||||
const [, actions] = groups;
|
||||
for (const action of actions) {
|
||||
action.label = mnemonicMenuLabel(this.calculateActionLabel(action));
|
||||
webNavigationActions.push(action);
|
||||
}
|
||||
}
|
||||
webNavigationMenu.dispose();
|
||||
|
||||
return webNavigationActions;
|
||||
}
|
||||
compactMode: this.currentCompactMenuMode
|
||||
};
|
||||
}
|
||||
|
||||
protected onDidChangeWindowFocus(hasFocus: boolean): void {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onDidChangeWindowFocus(hasFocus);
|
||||
|
||||
if (this.container) {
|
||||
@@ -682,6 +697,30 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
}
|
||||
}
|
||||
|
||||
protected onUpdateStateChange(): void {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onUpdateStateChange();
|
||||
}
|
||||
|
||||
protected onRecentlyOpenedChange(): void {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onRecentlyOpenedChange();
|
||||
}
|
||||
|
||||
protected onUpdateKeybindings(): void {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.onUpdateKeybindings();
|
||||
}
|
||||
|
||||
protected registerListeners(): void {
|
||||
super.registerListeners();
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
readonly minimumWidth: number = 0;
|
||||
readonly maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||
get minimumHeight(): number { return isMacintosh && !isWeb ? 22 / getZoomFactor() : (30 / (this.currentMenubarVisibility === 'hidden' ? getZoomFactor() : 1)); }
|
||||
get maximumHeight(): number { return isMacintosh && !isWeb ? 22 / getZoomFactor() : (30 / (this.currentMenubarVisibility === 'hidden' ? getZoomFactor() : 1)); }
|
||||
get minimumHeight(): number { return 30 / (this.currentMenubarVisibility === 'hidden' ? getZoomFactor() : 1); }
|
||||
get maximumHeight(): number { return this.minimumHeight; }
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -100,7 +100,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
this.contextMenu = this._register(menuService.createMenu(MenuId.TitleBarContext, contextKeyService));
|
||||
|
||||
this.titleBarStyle = getTitleBarStyle(this.configurationService, this.environmentService);
|
||||
this.titleBarStyle = getTitleBarStyle(this.configurationService);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
@@ -461,13 +461,13 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
|
||||
protected get currentMenubarVisibility(): MenuBarVisibility {
|
||||
return getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
return getMenuBarVisibility(this.configurationService);
|
||||
}
|
||||
|
||||
updateLayout(dimension: Dimension): void {
|
||||
this.lastLayoutDimensions = dimension;
|
||||
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
if (getTitleBarStyle(this.configurationService) === 'custom') {
|
||||
// Only prevent zooming behavior on macOS or when the menubar is not visible
|
||||
if ((!isWeb && isMacintosh) || this.currentMenubarVisibility === 'hidden') {
|
||||
this.title.style.zoom = `${1 / getZoomFactor()}`;
|
||||
|
||||
174
lib/vscode/src/vs/workbench/browser/parts/views/media/views.css
Normal file
174
lib/vscode/src/vs/workbench/browser/parts/views/media/views.css
Normal file
@@ -0,0 +1,174 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* File icons in trees */
|
||||
|
||||
.file-icon-themable-tree.align-icons-and-twisties .monaco-tl-twistie:not(.force-twistie):not(.collapsible),
|
||||
.file-icon-themable-tree .align-icon-with-twisty .monaco-tl-twistie:not(.force-twistie):not(.collapsible),
|
||||
.file-icon-themable-tree.hide-arrows .monaco-tl-twistie:not(.force-twistie),
|
||||
.file-icon-themable-tree .monaco-tl-twistie.force-no-twistie {
|
||||
background-image: none !important;
|
||||
width: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .message {
|
||||
display: flex;
|
||||
padding: 4px 12px 4px 18px;
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .message p {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .message ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .message.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .customview-tree {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view .customview-tree.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body > .welcome-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body:not(.welcome) > .welcome-view,
|
||||
.monaco-workbench .pane > .pane-body.welcome > :not(.welcome-view) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body > .welcome-view .monaco-button {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body.wide > .welcome-view .monaco-button {
|
||||
margin-left: inherit;
|
||||
max-width: 260px;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body .welcome-view-content {
|
||||
padding: 0 20px 0 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-workbench .pane > .pane-body .welcome-view-content > * {
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list-row .monaco-tl-contents.align-icon-with-twisty::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list-row .monaco-tl-contents:not(.align-icon-with-twisty)::before {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row {
|
||||
padding-right: 12px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item {
|
||||
display: flex;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
flex: 1;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .monaco-inputbox {
|
||||
line-height: normal;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel {
|
||||
flex: 1;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon {
|
||||
background-size: 16px;
|
||||
background-position: left center;
|
||||
background-repeat: no-repeat;
|
||||
padding-right: 6px;
|
||||
width: 16px;
|
||||
height: 22px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.codicon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row.selected .custom-view-tree-node-item > .custom-view-tree-node-item-icon.codicon {
|
||||
color: currentColor !important;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel .monaco-icon-label-container > .monaco-icon-name-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel::after {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row .custom-view-tree-node-item .actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .monaco-list-row:hover .custom-view-tree-node-item .actions,
|
||||
.customview-tree .monaco-list .monaco-list-row.selected .custom-view-tree-node-item .actions,
|
||||
.customview-tree .monaco-list .monaco-list-row.focused .custom-view-tree-node-item .actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .custom-view-tree-node-item .actions .action-label {
|
||||
width: 16px;
|
||||
height: 100%;
|
||||
background-size: 16px;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .custom-view-tree-node-item .actions .action-label.codicon {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.customview-tree .monaco-list .custom-view-tree-node-item .actions .action-label.codicon::before {
|
||||
vertical-align: middle;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,15 +18,15 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService, Themable } from 'vs/platform/theme/common/themeService';
|
||||
import { IThemeService, Themable, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { PaneView, IPaneViewOptions, IPaneOptions, Pane, IPaneStyles } from 'vs/base/browser/ui/splitview/paneview';
|
||||
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, 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 { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewPaneContainer, IViewsRegistry, IViewContentDescriptor, IAddedViewDescriptorRef, IViewDescriptorRef, IViewContainerModel, defaultViewIcon } from 'vs/workbench/common/views';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { assertIsDefined, isString } from 'vs/base/common/types';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -50,6 +50,8 @@ import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export interface IPaneColors extends IColorMapping {
|
||||
dropBackground?: ColorIdentifier;
|
||||
@@ -70,6 +72,9 @@ type WelcomeActionClassification = {
|
||||
uri: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
};
|
||||
|
||||
const viewPaneContainerExpandedIcon = registerIcon('view-pane-container-expanded', Codicon.chevronDown, nls.localize('viewPaneContainerExpandedIcon', 'Icon for an expanded view pane container.'));
|
||||
const viewPaneContainerCollapsedIcon = registerIcon('view-pane-container-collapsed', Codicon.chevronRight, nls.localize('viewPaneContainerCollapsedIcon', 'Icon for a collapsed view pane container.'));
|
||||
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry);
|
||||
|
||||
interface IItem {
|
||||
@@ -263,7 +268,10 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
if (changed) {
|
||||
this._onDidChangeBodyVisibility.fire(expanded);
|
||||
}
|
||||
|
||||
if (this.twistiesContainer) {
|
||||
this.twistiesContainer.classList.remove(...ThemeIcon.asClassNameArray(this.getTwistyIcon(!expanded)));
|
||||
this.twistiesContainer.classList.add(...ThemeIcon.asClassNameArray(this.getTwistyIcon(expanded)));
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -288,7 +296,7 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
protected renderHeader(container: HTMLElement): void {
|
||||
this.headerContainer = container;
|
||||
|
||||
this.renderTwisties(container);
|
||||
this.twistiesContainer = append(container, $(ThemeIcon.asCSSSelector(this.getTwistyIcon(this.isExpanded()))));
|
||||
|
||||
this.renderHeaderTitle(container, this.title);
|
||||
|
||||
@@ -316,8 +324,8 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
this.updateActionsVisibility();
|
||||
}
|
||||
|
||||
protected renderTwisties(container: HTMLElement): void {
|
||||
this.twistiesContainer = append(container, $('.twisties.codicon.codicon-chevron-right'));
|
||||
protected getTwistyIcon(expanded: boolean): ThemeIcon {
|
||||
return expanded ? viewPaneContainerExpandedIcon : viewPaneContainerCollapsedIcon;
|
||||
}
|
||||
|
||||
style(styles: IPaneStyles): void {
|
||||
@@ -338,8 +346,8 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
}
|
||||
}
|
||||
|
||||
private getIcon(): string | URI {
|
||||
return this.viewDescriptorService.getViewDescriptorById(this.id)?.containerIcon || 'codicon-window';
|
||||
private getIcon(): ThemeIcon | URI {
|
||||
return this.viewDescriptorService.getViewDescriptorById(this.id)?.containerIcon || defaultViewIcon;
|
||||
}
|
||||
|
||||
protected renderHeaderTitle(container: HTMLElement, title: string): void {
|
||||
@@ -357,9 +365,8 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
-webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%;
|
||||
-webkit-mask-size: 16px;
|
||||
`);
|
||||
} else if (isString(icon)) {
|
||||
this.iconContainer.classList.add('codicon');
|
||||
cssClass = icon;
|
||||
} else if (ThemeIcon.isThemeIcon(icon)) {
|
||||
cssClass = ThemeIcon.asClassName(icon);
|
||||
}
|
||||
|
||||
if (cssClass) {
|
||||
@@ -556,9 +563,7 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
this.bodyContainer.classList.add('welcome');
|
||||
this.viewWelcomeContainer.innerText = '';
|
||||
|
||||
let buttonIndex = 0;
|
||||
|
||||
for (const { content, preconditions } of contents) {
|
||||
for (const { content, precondition } of contents) {
|
||||
const lines = content.split('\n');
|
||||
|
||||
for (let line of lines) {
|
||||
@@ -581,21 +586,15 @@ export abstract class ViewPane extends Pane implements IView {
|
||||
disposables.add(button);
|
||||
disposables.add(attachButtonStyler(button, this.themeService));
|
||||
|
||||
if (preconditions) {
|
||||
const precondition = preconditions[buttonIndex];
|
||||
if (precondition) {
|
||||
const updateEnablement = () => button.enabled = this.contextKeyService.contextMatchesRules(precondition);
|
||||
updateEnablement();
|
||||
|
||||
if (precondition) {
|
||||
const updateEnablement = () => button.enabled = this.contextKeyService.contextMatchesRules(precondition);
|
||||
updateEnablement();
|
||||
|
||||
const keys = new Set();
|
||||
precondition.keys().forEach(key => keys.add(key));
|
||||
const onDidChangeContext = Event.filter(this.contextKeyService.onDidChangeContext, e => e.affectsSome(keys));
|
||||
onDidChangeContext(updateEnablement, null, disposables);
|
||||
}
|
||||
const keys = new Set();
|
||||
precondition.keys().forEach(key => keys.add(key));
|
||||
const onDidChangeContext = Event.filter(this.contextKeyService.onDidChangeContext, e => e.affectsSome(keys));
|
||||
onDidChangeContext(updateEnablement, null, disposables);
|
||||
}
|
||||
|
||||
buttonIndex++;
|
||||
} else {
|
||||
const p = append(this.viewWelcomeContainer, $('p'));
|
||||
|
||||
@@ -1319,7 +1318,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
|
||||
saveState(): void {
|
||||
this.panes.forEach((view) => view.saveState());
|
||||
this.storageService.store(this.visibleViewsStorageId, this.length, StorageScope.WORKSPACE);
|
||||
this.storageService.store(this.visibleViewsStorageId, this.length, StorageScope.WORKSPACE, StorageTarget.USER);
|
||||
}
|
||||
|
||||
private onContextMenu(event: StandardMouseEvent, viewDescriptor: IViewDescriptor): void {
|
||||
|
||||
@@ -60,6 +60,8 @@ import { localize } from 'vs/nls';
|
||||
import { CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
|
||||
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
|
||||
|
||||
class BrowserMain extends Disposable {
|
||||
|
||||
@@ -201,9 +203,13 @@ class BrowserMain extends Disposable {
|
||||
serviceCollection.set(IFileService, fileService);
|
||||
await this.registerFileSystemProviders(environmentService, fileService, remoteAgentService, logService, logsPath);
|
||||
|
||||
// IURIIdentityService
|
||||
const uriIdentityService = new UriIdentityService(fileService);
|
||||
serviceCollection.set(IUriIdentityService, uriIdentityService);
|
||||
|
||||
// Long running services (workspace, config, storage)
|
||||
const [configurationService, storageService] = await Promise.all([
|
||||
this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => {
|
||||
this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, uriIdentityService, logService).then(service => {
|
||||
|
||||
// Workspace
|
||||
serviceCollection.set(IWorkspaceContextService, service);
|
||||
@@ -333,8 +339,8 @@ class BrowserMain extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise<WorkspaceService> {
|
||||
const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, environmentService, fileService, remoteAgentService, logService);
|
||||
private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, uriIdentityService: IUriIdentityService, logService: ILogService): Promise<WorkspaceService> {
|
||||
const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, environmentService, fileService, remoteAgentService, uriIdentityService, logService);
|
||||
|
||||
try {
|
||||
await workspaceService.initialize(payload);
|
||||
|
||||
@@ -108,6 +108,11 @@ import { isStandalone } from 'vs/base/browser/browser';
|
||||
],
|
||||
'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'splitSizing' }, "Controls the sizing of editor groups when splitting them.")
|
||||
},
|
||||
'workbench.editor.splitOnDragAndDrop': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': nls.localize('splitOnDragAndDrop', "Controls if editor groups can be split from drag and drop operations by dropping an editor or file on the edges of the editor area.")
|
||||
},
|
||||
'workbench.editor.focusRecentEditorAfterClose': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('focusRecentEditorAfterClose', "Controls whether tabs are closed in most recently used order or from left to right."),
|
||||
@@ -120,13 +125,13 @@ import { isStandalone } from 'vs/base/browser/browser';
|
||||
},
|
||||
'workbench.editor.enablePreview': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('enablePreview', "Controls whether opened editors show as preview. Preview editors are reused until they are explicitly set to be kept open (e.g. via double click or editing) and show up with an italic font style."),
|
||||
'description': nls.localize('enablePreview', "Controls whether opened editors show as preview. Preview editors do not keep open and are reused until explicitly set to be kept open (e.g. via double click or editing) and show up with an italic font style."),
|
||||
'default': true
|
||||
},
|
||||
'workbench.editor.enablePreviewFromQuickOpen': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('enablePreviewFromQuickOpen', "Controls whether editors opened from Quick Open show as preview. Preview editors are reused until they are explicitly set to be kept open (e.g. via double click or editing)."),
|
||||
'default': true
|
||||
'description': nls.localize('enablePreviewFromQuickOpen', "Controls whether editors opened from Quick Open show as preview. Preview editors do not keep open and are reused until explicitly set to be kept open (e.g. via double click or editing)."),
|
||||
'default': false
|
||||
},
|
||||
'workbench.editor.closeOnFileDelete': {
|
||||
'type': 'boolean',
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr
|
||||
import { IEditorInputFactoryRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
|
||||
import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions';
|
||||
import { Position, Parts, IWorkbenchLayoutService, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IStorageService, WillSaveStateReason, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, WillSaveStateReason, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
@@ -297,7 +297,7 @@ export class Workbench extends Layout {
|
||||
// local storage and not global storage because it would not make
|
||||
// much sense to synchronize to other machines.
|
||||
if (isNative) {
|
||||
storageService.store('editorFontInfo', serializedFontInfoRaw, StorageScope.GLOBAL);
|
||||
storageService.store('editorFontInfo', serializedFontInfoRaw, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
} else {
|
||||
window.localStorage.setItem('vscode.editorFontInfo', serializedFontInfoRaw);
|
||||
}
|
||||
@@ -415,8 +415,7 @@ export class Workbench extends Layout {
|
||||
mark('didStartWorkbench');
|
||||
|
||||
// Perf reporting (devtools)
|
||||
performance.mark('workbench-end');
|
||||
performance.measure('perf: workbench create & restore', 'workbench-start', 'workbench-end');
|
||||
performance.measure('perf: workbench create & restore', 'didLoadWorkbenchMain', 'didStartWorkbench');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user