mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 18:22:34 -05:00
Merge from vscode 79a1f5a5ca0c6c53db617aa1fa5a2396d2caebe2
This commit is contained in:
@@ -5,28 +5,10 @@
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
export class ToggleDevToolsAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.toggleDevTools';
|
||||
static readonly LABEL = nls.localize('toggleDevTools', "Toggle Developer Tools");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IElectronService private readonly electronService: IElectronService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return this.electronService.toggleDevTools();
|
||||
}
|
||||
}
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
|
||||
export class ToggleSharedProcessAction extends Action {
|
||||
|
||||
@@ -46,21 +28,7 @@ export class ToggleSharedProcessAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfigureRuntimeArgumentsAction extends Action {
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
|
||||
static readonly ID = 'workbench.action.configureRuntimeArguments';
|
||||
static readonly LABEL = nls.localize('configureRuntimeArguments', "Configure Runtime Arguments");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IEditorService private readonly editorService: IEditorService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
await this.editorService.openEditor({ resource: this.environmentService.argvResource });
|
||||
}
|
||||
}
|
||||
const developerCategory = nls.localize('developer', "Developer");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleSharedProcessAction), 'Developer: Toggle Shared Process', developerCategory);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench .quick-input-list .quick-input-list-entry.has-actions:hover .quick-input-list-entry-action-bar .action-label.dirty-window::before {
|
||||
content: "\ea76"; /* Close icon flips between black dot and "X" for dirty windows */
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/actions';
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { webFrame } from 'electron';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IQuickInputService, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export class CloseCurrentWindowAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.closeWindow';
|
||||
static readonly LABEL = nls.localize('closeWindow', "Close Window");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IElectronService private readonly electronService: IElectronService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.electronService.closeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseZoomAction extends Action {
|
||||
|
||||
private static readonly SETTING_KEY = 'window.zoomLevel';
|
||||
|
||||
private static readonly MAX_ZOOM_LEVEL = 9;
|
||||
private static readonly MIN_ZOOM_LEVEL = -8;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
protected async setConfiguredZoomLevel(level: number): Promise<void> {
|
||||
level = Math.round(level); // when reaching smallest zoom, prevent fractional zoom levels
|
||||
|
||||
if (level > BaseZoomAction.MAX_ZOOM_LEVEL || level < BaseZoomAction.MIN_ZOOM_LEVEL) {
|
||||
return; // https://github.com/microsoft/vscode/issues/48357
|
||||
}
|
||||
|
||||
const applyZoom = () => {
|
||||
webFrame.setZoomLevel(level);
|
||||
browser.setZoomFactor(webFrame.getZoomFactor());
|
||||
// See https://github.com/Microsoft/vscode/issues/26151
|
||||
// Cannot be trusted because the webFrame might take some time
|
||||
// until it really applies the new zoom level
|
||||
browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false);
|
||||
};
|
||||
|
||||
await this.configurationService.updateValue(BaseZoomAction.SETTING_KEY, level);
|
||||
|
||||
applyZoom();
|
||||
}
|
||||
}
|
||||
|
||||
export class ZoomInAction extends BaseZoomAction {
|
||||
|
||||
static readonly ID = 'workbench.action.zoomIn';
|
||||
static readonly LABEL = nls.localize('zoomIn', "Zoom In");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label, configurationService);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.setConfiguredZoomLevel(webFrame.getZoomLevel() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
export class ZoomOutAction extends BaseZoomAction {
|
||||
|
||||
static readonly ID = 'workbench.action.zoomOut';
|
||||
static readonly LABEL = nls.localize('zoomOut', "Zoom Out");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label, configurationService);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.setConfiguredZoomLevel(webFrame.getZoomLevel() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
export class ZoomResetAction extends BaseZoomAction {
|
||||
|
||||
static readonly ID = 'workbench.action.zoomReset';
|
||||
static readonly LABEL = nls.localize('zoomReset', "Reset Zoom");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label, configurationService);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.setConfiguredZoomLevel(0);
|
||||
}
|
||||
}
|
||||
|
||||
export class ReloadWindowWithExtensionsDisabledAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.reloadWindowWithExtensionsDisabled';
|
||||
static readonly LABEL = nls.localize('reloadWindowWithExtensionsDisabled', "Reload With Extensions Disabled");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IElectronService private readonly electronService: IElectronService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
async run(): Promise<boolean> {
|
||||
await this.electronService.reload({ disableExtensions: true });
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseSwitchWindow extends Action {
|
||||
|
||||
private readonly closeWindowAction: IQuickInputButton = {
|
||||
iconClass: Codicon.removeClose.classNames,
|
||||
tooltip: nls.localize('close', "Close Window")
|
||||
};
|
||||
|
||||
private readonly closeDirtyWindowAction: IQuickInputButton = {
|
||||
iconClass: 'dirty-window ' + Codicon.closeDirty,
|
||||
tooltip: nls.localize('close', "Close Window"),
|
||||
alwaysVisible: true
|
||||
};
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
private readonly environmentService: INativeWorkbenchEnvironmentService,
|
||||
private readonly quickInputService: IQuickInputService,
|
||||
private readonly keybindingService: IKeybindingService,
|
||||
private readonly modelService: IModelService,
|
||||
private readonly modeService: IModeService,
|
||||
private readonly electronService: IElectronService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
protected abstract isQuickNavigate(): boolean;
|
||||
|
||||
async run(): Promise<void> {
|
||||
const currentWindowId = this.environmentService.configuration.windowId;
|
||||
|
||||
const windows = await this.electronService.getWindows();
|
||||
const placeHolder = nls.localize('switchWindowPlaceHolder', "Select a window to switch to");
|
||||
const picks = windows.map(win => {
|
||||
const resource = win.filename ? URI.file(win.filename) : win.folderUri ? win.folderUri : win.workspace ? win.workspace.configPath : undefined;
|
||||
const fileKind = win.filename ? FileKind.FILE : win.workspace ? FileKind.ROOT_FOLDER : win.folderUri ? FileKind.FOLDER : FileKind.FILE;
|
||||
return {
|
||||
payload: win.id,
|
||||
label: win.title,
|
||||
ariaLabel: win.dirty ? nls.localize('windowDirtyAriaLabel', "{0}, dirty window", win.title) : win.title,
|
||||
iconClasses: getIconClasses(this.modelService, this.modeService, resource, fileKind),
|
||||
description: (currentWindowId === win.id) ? nls.localize('current', "Current Window") : undefined,
|
||||
buttons: currentWindowId !== win.id ? win.dirty ? [this.closeDirtyWindowAction] : [this.closeWindowAction] : undefined
|
||||
};
|
||||
});
|
||||
const autoFocusIndex = (picks.indexOf(picks.filter(pick => pick.payload === currentWindowId)[0]) + 1) % picks.length;
|
||||
|
||||
const pick = await this.quickInputService.pick(picks, {
|
||||
contextKey: 'inWindowsPicker',
|
||||
activeItem: picks[autoFocusIndex],
|
||||
placeHolder,
|
||||
quickNavigate: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : undefined,
|
||||
onDidTriggerItemButton: async context => {
|
||||
await this.electronService.closeWindowById(context.item.payload);
|
||||
context.removeItem();
|
||||
}
|
||||
});
|
||||
|
||||
if (pick) {
|
||||
this.electronService.focusWindow({ windowId: pick.payload });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchWindow extends BaseSwitchWindow {
|
||||
|
||||
static readonly ID = 'workbench.action.switchWindow';
|
||||
static readonly LABEL = nls.localize('switchWindow', "Switch Window...");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IModelService modelService: IModelService,
|
||||
@IModeService modeService: IModeService,
|
||||
@IElectronService electronService: IElectronService
|
||||
) {
|
||||
super(id, label, environmentService, quickInputService, keybindingService, modelService, modeService, electronService);
|
||||
}
|
||||
|
||||
protected isQuickNavigate(): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class QuickSwitchWindow extends BaseSwitchWindow {
|
||||
|
||||
static readonly ID = 'workbench.action.quickSwitchWindow';
|
||||
static readonly LABEL = nls.localize('quickSwitchWindow', "Quick Switch Window...");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IModelService modelService: IModelService,
|
||||
@IModeService modeService: IModeService,
|
||||
@IElectronService electronService: IElectronService
|
||||
) {
|
||||
super(id, label, environmentService, quickInputService, keybindingService, modelService, modeService, electronService);
|
||||
}
|
||||
|
||||
protected isQuickNavigate(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export const NewWindowTabHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).newWindowTab();
|
||||
};
|
||||
|
||||
export const ShowPreviousWindowTabHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).showPreviousWindowTab();
|
||||
};
|
||||
|
||||
export const ShowNextWindowTabHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).showNextWindowTab();
|
||||
};
|
||||
|
||||
export const MoveWindowTabToNewWindowHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).moveWindowTabToNewWindow();
|
||||
};
|
||||
|
||||
export const MergeWindowTabsHandlerHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).mergeAllWindowTabs();
|
||||
};
|
||||
|
||||
export const ToggleWindowTabsBarHandler: ICommandHandler = function (accessor: ServicesAccessor) {
|
||||
return accessor.get(IElectronService).toggleWindowTabsBar();
|
||||
};
|
||||
@@ -1,372 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as os from 'os';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
|
||||
import { ToggleSharedProcessAction, ToggleDevToolsAction, ConfigureRuntimeArgumentsAction } from 'vs/workbench/electron-browser/actions/developerActions';
|
||||
import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IsMacContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
|
||||
// eslint-disable-next-line code-import-patterns
|
||||
import { InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; // {{SQL CARBON EDIT}} add import
|
||||
|
||||
// Actions
|
||||
(function registerActions(): void {
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
|
||||
// Actions: Zoom
|
||||
(function registerZoomActions(): void {
|
||||
const viewCategory = nls.localize('view', "View");
|
||||
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ZoomInAction, { primary: KeyMod.CtrlCmd | KeyCode.US_EQUAL, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_EQUAL, KeyMod.CtrlCmd | KeyCode.NUMPAD_ADD] }), 'View: Zoom In', viewCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ZoomOutAction, { primary: KeyMod.CtrlCmd | KeyCode.US_MINUS, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_MINUS, KeyMod.CtrlCmd | KeyCode.NUMPAD_SUBTRACT], linux: { primary: KeyMod.CtrlCmd | KeyCode.US_MINUS, secondary: [KeyMod.CtrlCmd | KeyCode.NUMPAD_SUBTRACT] } }), 'View: Zoom Out', viewCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ZoomResetAction, { primary: KeyMod.CtrlCmd | KeyCode.NUMPAD_0 }), 'View: Reset Zoom', viewCategory);
|
||||
})();
|
||||
|
||||
// Actions: Window
|
||||
(function registerWindowActions(): void {
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseCurrentWindowAction, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_W }), 'Close Window');
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(SwitchWindow, { primary: 0, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_W } }), 'Switch Window...');
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(QuickSwitchWindow), 'Quick Switch Window...');
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CloseCurrentWindowAction.ID, // close the window when the last editor is closed by reusing the same keybinding
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: ContextKeyExpr.and(NoEditorsVisibleContext, SingleEditorGroupsContext),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_W,
|
||||
handler: accessor => {
|
||||
const electronService = accessor.get(IElectronService);
|
||||
electronService.closeWindow();
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'workbench.action.quit',
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
handler(accessor: ServicesAccessor) {
|
||||
const electronService = accessor.get(IElectronService);
|
||||
electronService.quit();
|
||||
},
|
||||
when: undefined,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_Q },
|
||||
linux: { primary: KeyMod.CtrlCmd | KeyCode.KEY_Q }
|
||||
});
|
||||
})();
|
||||
|
||||
// Actions: macOS Native Tabs
|
||||
(function registerMacOSNativeTabsActions(): void {
|
||||
if (isMacintosh) {
|
||||
[
|
||||
{ handler: NewWindowTabHandler, id: 'workbench.action.newWindowTab', title: { value: nls.localize('newTab', "New Window Tab"), original: 'New Window Tab' } },
|
||||
{ handler: ShowPreviousWindowTabHandler, id: 'workbench.action.showPreviousWindowTab', title: { value: nls.localize('showPreviousTab', "Show Previous Window Tab"), original: 'Show Previous Window Tab' } },
|
||||
{ handler: ShowNextWindowTabHandler, id: 'workbench.action.showNextWindowTab', title: { value: nls.localize('showNextWindowTab', "Show Next Window Tab"), original: 'Show Next Window Tab' } },
|
||||
{ handler: MoveWindowTabToNewWindowHandler, id: 'workbench.action.moveWindowTabToNewWindow', title: { value: nls.localize('moveWindowTabToNewWindow', "Move Window Tab to New Window"), original: 'Move Window Tab to New Window' } },
|
||||
{ handler: MergeWindowTabsHandlerHandler, id: 'workbench.action.mergeAllWindowTabs', title: { value: nls.localize('mergeAllWindowTabs', "Merge All Windows"), original: 'Merge All Windows' } },
|
||||
{ handler: ToggleWindowTabsBarHandler, id: 'workbench.action.toggleWindowTabsBar', title: { value: nls.localize('toggleWindowTabsBar', "Toggle Window Tabs Bar"), original: 'Toggle Window Tabs Bar' } }
|
||||
].forEach(command => {
|
||||
CommandsRegistry.registerCommand(command.id, command.handler);
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command,
|
||||
when: ContextKeyExpr.equals('config.window.nativeTabs', true)
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// Actions: Developer
|
||||
(function registerDeveloperActions(): void {
|
||||
const developerCategory = nls.localize('developer', "Developer");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleSharedProcessAction), 'Developer: Toggle Shared Process', developerCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReloadWindowWithExtensionsDisabledAction), 'Developer: Reload With Extensions Disabled', developerCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleDevToolsAction), 'Developer: Toggle Developer Tools', developerCategory);
|
||||
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: ToggleDevToolsAction.ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
when: undefined, // {{SQL CARBON EDIT}} allow this toggle in all circumstances
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_I }
|
||||
});
|
||||
})();
|
||||
|
||||
// Actions: Runtime Arguments
|
||||
(function registerRuntimeArgumentsAction(): void {
|
||||
const preferencesCategory = nls.localize('preferences', "Preferences");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ConfigureRuntimeArgumentsAction), 'Preferences: Configure Runtime Arguments', preferencesCategory);
|
||||
})();
|
||||
})();
|
||||
|
||||
// Menu
|
||||
(function registerMenu(): void {
|
||||
if (InstallVSIXAction.AVAILABLE) {
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { // {{SQL CARBON EDIT}} - Add install VSIX menu item
|
||||
group: '5.1_installExtension',
|
||||
command: {
|
||||
id: InstallVSIXAction.ID,
|
||||
title: nls.localize({ key: 'miinstallVsix', comment: ['&& denotes a mnemonic'] }, "Install Extension from VSIX Package")
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
group: '6_close',
|
||||
command: {
|
||||
id: CloseCurrentWindowAction.ID,
|
||||
title: nls.localize({ key: 'miCloseWindow', comment: ['&& denotes a mnemonic'] }, "Clos&&e Window")
|
||||
},
|
||||
order: 4
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
group: 'z_Exit',
|
||||
command: {
|
||||
id: 'workbench.action.quit',
|
||||
title: nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")
|
||||
},
|
||||
order: 1,
|
||||
when: IsMacContext.toNegated()
|
||||
});
|
||||
|
||||
// Zoom
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
group: '3_zoom',
|
||||
command: {
|
||||
id: ZoomInAction.ID,
|
||||
title: nls.localize({ key: 'miZoomIn', comment: ['&& denotes a mnemonic'] }, "&&Zoom In")
|
||||
},
|
||||
order: 1
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
group: '3_zoom',
|
||||
command: {
|
||||
id: ZoomOutAction.ID,
|
||||
title: nls.localize({ key: 'miZoomOut', comment: ['&& denotes a mnemonic'] }, "&&Zoom Out")
|
||||
},
|
||||
order: 2
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
group: '3_zoom',
|
||||
command: {
|
||||
id: ZoomResetAction.ID,
|
||||
title: nls.localize({ key: 'miZoomReset', comment: ['&& denotes a mnemonic'] }, "&&Reset Zoom")
|
||||
},
|
||||
order: 3
|
||||
});
|
||||
|
||||
if (!!product.reportIssueUrl) {
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
|
||||
group: '3_feedback',
|
||||
command: {
|
||||
id: 'workbench.action.openIssueReporter',
|
||||
title: nls.localize({ key: 'miReportIssue', comment: ['&& denotes a mnemonic', 'Translate this to "Report Issue in English" in all languages please!'] }, "Report &&Issue")
|
||||
},
|
||||
order: 3
|
||||
});
|
||||
}
|
||||
|
||||
// Tools
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
|
||||
group: '5_tools',
|
||||
command: {
|
||||
id: ToggleDevToolsAction.ID,
|
||||
title: nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools")
|
||||
},
|
||||
order: 1
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
|
||||
group: '5_tools',
|
||||
command: {
|
||||
id: 'workbench.action.openProcessExplorer',
|
||||
title: nls.localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")
|
||||
},
|
||||
order: 2
|
||||
});
|
||||
})();
|
||||
|
||||
// Configuration
|
||||
(function registerConfiguration(): void {
|
||||
const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
||||
|
||||
// Window
|
||||
registry.registerConfiguration({
|
||||
'id': 'window',
|
||||
'order': 8,
|
||||
'title': nls.localize('windowConfigurationTitle', "Window"),
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'window.openWithoutArgumentsInNewWindow': {
|
||||
'type': 'string',
|
||||
'enum': ['on', 'off'],
|
||||
'enumDescriptions': [
|
||||
nls.localize('window.openWithoutArgumentsInNewWindow.on', "Open a new empty window."),
|
||||
nls.localize('window.openWithoutArgumentsInNewWindow.off', "Focus the last active running instance.")
|
||||
],
|
||||
'default': isMacintosh ? 'off' : 'on',
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'markdownDescription': nls.localize('openWithoutArgumentsInNewWindow', "Controls whether a new empty window should open when starting a second instance without arguments or if the last running instance should get focus.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).")
|
||||
},
|
||||
'window.restoreWindows': {
|
||||
'type': 'string',
|
||||
'enum': ['all', 'folders', 'one', 'none'],
|
||||
'enumDescriptions': [
|
||||
nls.localize('window.reopenFolders.all', "Reopen all windows."),
|
||||
nls.localize('window.reopenFolders.folders', "Reopen all folders. Empty workspaces will not be restored."),
|
||||
nls.localize('window.reopenFolders.one', "Reopen the last active window."),
|
||||
nls.localize('window.reopenFolders.none', "Never reopen a window. Always start with an empty one.")
|
||||
],
|
||||
'default': 'all',
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('restoreWindows', "Controls how windows are being reopened after a restart.")
|
||||
},
|
||||
'window.restoreFullscreen': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('restoreFullscreen', "Controls whether a window should restore to full screen mode if it was exited in full screen mode.")
|
||||
},
|
||||
'window.zoomLevel': {
|
||||
'type': 'number',
|
||||
'default': 0,
|
||||
'description': nls.localize('zoomLevel', "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.")
|
||||
},
|
||||
'window.newWindowDimensions': {
|
||||
'type': 'string',
|
||||
'enum': ['default', 'inherit', 'offset', 'maximized', 'fullscreen'],
|
||||
'enumDescriptions': [
|
||||
nls.localize('window.newWindowDimensions.default', "Open new windows in the center of the screen."),
|
||||
nls.localize('window.newWindowDimensions.inherit', "Open new windows with same dimension as last active one."),
|
||||
nls.localize('window.newWindowDimensions.offset', "Open new windows with same dimension as last active one with an offset position."),
|
||||
nls.localize('window.newWindowDimensions.maximized', "Open new windows maximized."),
|
||||
nls.localize('window.newWindowDimensions.fullscreen', "Open new windows in full screen mode.")
|
||||
],
|
||||
'default': 'default',
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('newWindowDimensions', "Controls the dimensions of opening a new window when at least one window is already opened. Note that this setting does not have an impact on the first window that is opened. The first window will always restore the size and location as you left it before closing.")
|
||||
},
|
||||
'window.closeWhenEmpty': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'description': nls.localize('closeWhenEmpty', "Controls whether closing the last editor should also close the window. This setting only applies for windows that do not show folders.")
|
||||
},
|
||||
'window.autoDetectHighContrast': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': nls.localize('autoDetectHighContrast', "If enabled, will automatically change to high contrast theme if Windows is using a high contrast theme, and to dark theme when switching away from a Windows high contrast theme."),
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'included': isWindows
|
||||
},
|
||||
'window.doubleClickIconToClose': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'markdownDescription': nls.localize('window.doubleClickIconToClose', "If enabled, double clicking the application icon in the title bar will close the window and the window cannot be dragged by the icon. This setting only has an effect when `#window.titleBarStyle#` is set to `custom`.")
|
||||
},
|
||||
'window.titleBarStyle': {
|
||||
'type': 'string',
|
||||
'enum': ['native', 'custom'],
|
||||
'default': isLinux ? 'native' : 'custom',
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('titleBarStyle', "Adjust the appearance of the window title bar. On Linux and Windows, this setting also affects the application and context menu appearances. Changes require a full restart to apply.")
|
||||
},
|
||||
'window.nativeTabs': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('window.nativeTabs', "Enables macOS Sierra window tabs. Note that changes require a full restart to apply and that native tabs will disable a custom title bar style if configured."),
|
||||
'included': isMacintosh && parseFloat(os.release()) >= 17 // Minimum: macOS Sierra (10.13.x = darwin 17.x)
|
||||
},
|
||||
'window.nativeFullScreen': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': nls.localize('window.nativeFullScreen', "Controls if native full-screen should be used on macOS. Disable this option to prevent macOS from creating a new space when going full-screen."),
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'included': isMacintosh
|
||||
},
|
||||
'window.clickThroughInactive': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'description': nls.localize('window.clickThroughInactive', "If enabled, clicking on an inactive window will both activate the window and trigger the element under the mouse if it is clickable. If disabled, clicking anywhere on an inactive window will activate it only and a second click is required on the element."),
|
||||
'included': isMacintosh
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Telemetry
|
||||
registry.registerConfiguration({
|
||||
'id': 'telemetry',
|
||||
'order': 110,
|
||||
title: nls.localize('telemetryConfigurationTitle', "Telemetry"),
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'telemetry.enableCrashReporter': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('telemetry.enableCrashReporting', "Enable crash reports to be sent to a Microsoft online service. \nThis option requires restart to take effect."),
|
||||
'default': true,
|
||||
'tags': ['usesOnlineServices']
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// JSON Schemas
|
||||
(function registerJSONSchemas(): void {
|
||||
const argvDefinitionFileSchemaId = 'vscode://schemas/argv';
|
||||
const jsonRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||
const schema: IJSONSchema = {
|
||||
id: argvDefinitionFileSchemaId,
|
||||
allowComments: true,
|
||||
allowTrailingCommas: true,
|
||||
description: 'VSCode static command line definition file',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
locale: {
|
||||
type: 'string',
|
||||
description: nls.localize('argv.locale', 'The display Language to use. Picking a different language requires the associated language pack to be installed.')
|
||||
},
|
||||
'disable-hardware-acceleration': {
|
||||
type: 'boolean',
|
||||
description: nls.localize('argv.disableHardwareAcceleration', 'Disables hardware acceleration. ONLY change this option if you encounter graphic issues.')
|
||||
},
|
||||
'disable-color-correct-rendering': {
|
||||
type: 'boolean',
|
||||
description: nls.localize('argv.disableColorCorrectRendering', 'Resolves issues around color profile selection. ONLY change this option if you encounter graphic issues.')
|
||||
},
|
||||
'force-color-profile': {
|
||||
type: 'string',
|
||||
markdownDescription: nls.localize('argv.forceColorProfile', 'Allows to override the color profile to use. If you experience colors appear badly, try to set this to `srgb` and restart.')
|
||||
}
|
||||
}
|
||||
};
|
||||
if (isLinux) {
|
||||
schema.properties!['force-renderer-accessibility'] = {
|
||||
type: 'boolean',
|
||||
description: nls.localize('argv.force-renderer-accessibility', 'Forces the renderer to be accessible. ONLY change this if you are using a screen reader on Linux. On other platforms the renderer will automatically be accessible. This flag is automatically set if you have editor.accessibilitySupport: on.'),
|
||||
};
|
||||
}
|
||||
|
||||
jsonRegistry.registerSchema(argvDefinitionFileSchemaId, schema);
|
||||
})();
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as gracefulFs from 'graceful-fs';
|
||||
import { webFrame } from 'electron';
|
||||
import { webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { importEntries, mark } from 'vs/base/common/performance';
|
||||
import { Workbench } from 'vs/workbench/browser/workbench';
|
||||
import { NativeWindow } from 'vs/workbench/electron-browser/window';
|
||||
@@ -30,7 +30,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver';
|
||||
import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService';
|
||||
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
|
||||
@@ -49,6 +49,7 @@ import product from 'vs/platform/product/common/product';
|
||||
import { NativeResourceIdentityService } from 'vs/platform/resource/node/resourceIdentityServiceImpl';
|
||||
import { IResourceIdentityService } from 'vs/platform/resource/common/resourceIdentityService';
|
||||
import { DesktopLogService } from 'vs/workbench/services/log/electron-browser/logService';
|
||||
import { IElectronService, ElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
|
||||
class DesktopMain extends Disposable {
|
||||
|
||||
@@ -191,14 +192,19 @@ class DesktopMain extends Disposable {
|
||||
const signService = new SignService();
|
||||
serviceCollection.set(ISignService, signService);
|
||||
|
||||
// Remote Agent
|
||||
const remoteAgentService = this._register(new RemoteAgentService(this.environmentService, remoteAuthorityResolverService, signService, logService));
|
||||
serviceCollection.set(IRemoteAgentService, remoteAgentService);
|
||||
|
||||
// Electron
|
||||
const electronService = new ElectronService(this.configuration.windowId, mainProcessService) as IElectronService;
|
||||
serviceCollection.set(IElectronService, electronService);
|
||||
|
||||
// Files
|
||||
const fileService = this._register(new FileService(logService));
|
||||
serviceCollection.set(IFileService, fileService);
|
||||
|
||||
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService));
|
||||
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService, electronService));
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
// User Data Provider
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { IMenuService } from 'vs/platform/actions/common/actions';
|
||||
import { TitlebarPart as BrowserTitleBarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
export class TitlebarPart extends BrowserTitleBarPart {
|
||||
private appIcon: HTMLElement | undefined;
|
||||
private windowControls: HTMLElement | undefined;
|
||||
private maxRestoreControl: HTMLElement | undefined;
|
||||
private dragRegion: HTMLElement | undefined;
|
||||
private resizer: HTMLElement | undefined;
|
||||
|
||||
constructor(
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService protected readonly configurationService: IConfigurationService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IHostService hostService: IHostService,
|
||||
@IProductService productService: IProductService,
|
||||
@IElectronService private readonly electronService: IElectronService
|
||||
) {
|
||||
super(contextMenuService, configurationService, editorService, environmentService, contextService, instantiationService, themeService, labelService, storageService, layoutService, menuService, contextKeyService, hostService, productService);
|
||||
}
|
||||
|
||||
private onUpdateAppIconDragBehavior() {
|
||||
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
|
||||
if (setting && this.appIcon) {
|
||||
(this.appIcon.style as any)['-webkit-app-region'] = 'no-drag';
|
||||
} else if (this.appIcon) {
|
||||
(this.appIcon.style as any)['-webkit-app-region'] = 'drag';
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeMaximized(maximized: boolean) {
|
||||
if (this.maxRestoreControl) {
|
||||
if (maximized) {
|
||||
DOM.removeClasses(this.maxRestoreControl, Codicon.chromeMaximize.classNames);
|
||||
DOM.addClasses(this.maxRestoreControl, Codicon.chromeRestore.classNames);
|
||||
} else {
|
||||
DOM.removeClasses(this.maxRestoreControl, Codicon.chromeRestore.classNames);
|
||||
DOM.addClasses(this.maxRestoreControl, Codicon.chromeMaximize.classNames);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.resizer) {
|
||||
if (maximized) {
|
||||
DOM.hide(this.resizer);
|
||||
} else {
|
||||
DOM.show(this.resizer);
|
||||
}
|
||||
}
|
||||
|
||||
this.adjustTitleMarginToCenter();
|
||||
}
|
||||
|
||||
private onMenubarFocusChanged(focused: boolean) {
|
||||
if ((isWindows || isLinux) && this.currentMenubarVisibility !== 'compact' && this.dragRegion) {
|
||||
if (focused) {
|
||||
DOM.hide(this.dragRegion);
|
||||
} else {
|
||||
DOM.show(this.dragRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected onMenubarVisibilityChanged(visible: boolean) {
|
||||
// Hide title when toggling menu bar
|
||||
if ((isWindows || isLinux) && this.currentMenubarVisibility === 'toggle' && visible) {
|
||||
// Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor
|
||||
if (this.dragRegion) {
|
||||
DOM.hide(this.dragRegion);
|
||||
setTimeout(() => DOM.show(this.dragRegion!), 50);
|
||||
}
|
||||
}
|
||||
|
||||
super.onMenubarVisibilityChanged(visible);
|
||||
}
|
||||
|
||||
protected onConfigurationChanged(event: IConfigurationChangeEvent): void {
|
||||
|
||||
super.onConfigurationChanged(event);
|
||||
|
||||
if (event.affectsConfiguration('window.doubleClickIconToClose')) {
|
||||
if (this.appIcon) {
|
||||
this.onUpdateAppIconDragBehavior();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected adjustTitleMarginToCenter(): void {
|
||||
if (this.customMenubar && this.menubar) {
|
||||
const leftMarker = (this.appIcon ? this.appIcon.clientWidth : 0) + this.menubar.clientWidth + 10;
|
||||
const rightMarker = this.element.clientWidth - (this.windowControls ? this.windowControls.clientWidth : 0) - 10;
|
||||
|
||||
// Not enough space to center the titlebar within window,
|
||||
// Center between menu and window controls
|
||||
if (leftMarker > (this.element.clientWidth - this.title.clientWidth) / 2 ||
|
||||
rightMarker < (this.element.clientWidth + this.title.clientWidth) / 2) {
|
||||
this.title.style.position = '';
|
||||
this.title.style.left = '';
|
||||
this.title.style.transform = '';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.title.style.position = 'absolute';
|
||||
this.title.style.left = '50%';
|
||||
this.title.style.transform = 'translate(-50%, 0)';
|
||||
}
|
||||
|
||||
protected installMenubar(): void {
|
||||
super.installMenubar();
|
||||
|
||||
if (this.menubar) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.customMenubar) {
|
||||
this._register(this.customMenubar.onFocusStateChange(e => this.onMenubarFocusChanged(e)));
|
||||
}
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
const ret = super.createContentArea(parent);
|
||||
|
||||
// App Icon (Native Windows/Linux)
|
||||
if (!isMacintosh) {
|
||||
this.appIcon = DOM.prepend(this.element, DOM.$('div.window-appicon'));
|
||||
this.onUpdateAppIconDragBehavior();
|
||||
|
||||
this._register(DOM.addDisposableListener(this.appIcon, DOM.EventType.DBLCLICK, (e => {
|
||||
this.electronService.closeWindow();
|
||||
})));
|
||||
}
|
||||
|
||||
// Draggable region that we can manipulate for #52522
|
||||
this.dragRegion = DOM.prepend(this.element, DOM.$('div.titlebar-drag-region'));
|
||||
|
||||
// Window Controls (Native Windows/Linux)
|
||||
if (!isMacintosh) {
|
||||
this.windowControls = DOM.append(this.element, DOM.$('div.window-controls-container'));
|
||||
|
||||
// Minimize
|
||||
const minimizeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-minimize' + Codicon.chromeMinimize.cssSelector));
|
||||
this._register(DOM.addDisposableListener(minimizeIcon, DOM.EventType.CLICK, e => {
|
||||
this.electronService.minimizeWindow();
|
||||
}));
|
||||
|
||||
// Restore
|
||||
this.maxRestoreControl = DOM.append(this.windowControls, DOM.$('div.window-icon.window-max-restore'));
|
||||
this._register(DOM.addDisposableListener(this.maxRestoreControl, DOM.EventType.CLICK, async e => {
|
||||
const maximized = await this.electronService.isMaximized();
|
||||
if (maximized) {
|
||||
return this.electronService.unmaximizeWindow();
|
||||
}
|
||||
|
||||
return this.electronService.maximizeWindow();
|
||||
}));
|
||||
|
||||
// Close
|
||||
const closeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-close' + Codicon.chromeClose.cssSelector));
|
||||
this._register(DOM.addDisposableListener(closeIcon, DOM.EventType.CLICK, e => {
|
||||
this.electronService.closeWindow();
|
||||
}));
|
||||
|
||||
// Resizer
|
||||
this.resizer = DOM.append(this.element, DOM.$('div.resizer'));
|
||||
|
||||
this._register(this.layoutService.onMaximizeChange(maximized => this.onDidChangeMaximized(maximized)));
|
||||
this.onDidChangeMaximized(this.layoutService.isWindowMaximized());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
updateLayout(dimension: DOM.Dimension): void {
|
||||
this.lastLayoutDimensions = dimension;
|
||||
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
// Only prevent zooming behavior on macOS or when the menubar is not visible
|
||||
if (isMacintosh || this.currentMenubarVisibility === 'hidden') {
|
||||
this.title.style.zoom = `${1 / browser.getZoomFactor()}`;
|
||||
if (isWindows || isLinux) {
|
||||
if (this.appIcon) {
|
||||
this.appIcon.style.zoom = `${1 / browser.getZoomFactor()}`;
|
||||
}
|
||||
|
||||
if (this.windowControls) {
|
||||
this.windowControls.style.zoom = `${1 / browser.getZoomFactor()}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.title.style.zoom = '';
|
||||
if (isWindows || isLinux) {
|
||||
if (this.appIcon) {
|
||||
this.appIcon.style.zoom = '';
|
||||
}
|
||||
|
||||
if (this.windowControls) {
|
||||
this.windowControls.style.zoom = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOM.runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter());
|
||||
|
||||
if (this.customMenubar) {
|
||||
const menubarDimension = new DOM.Dimension(0, dimension.height);
|
||||
this.customMenubar.layout(menubarDimension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,46 +14,46 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { toResource, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors } from 'vs/workbench/common/editor';
|
||||
import { IEditorService, IResourceEditorInputType } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ITelemetryService, crashReporterIdStorageKey } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IWindowSettings, IOpenFileRequest, IWindowsConfiguration, getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
import { IRunActionInWindowRequest, IRunKeybindingInWindowRequest, IAddFoldersRequest, INativeOpenFileRequest } from 'vs/platform/windows/node/window';
|
||||
import { IWindowSettings, IOpenFileRequest, IWindowsConfiguration, getTitleBarStyle, IAddFoldersRequest } from 'vs/platform/windows/common/windows';
|
||||
import { IRunActionInWindowRequest, IRunKeybindingInWindowRequest, INativeOpenFileRequest } from 'vs/platform/windows/node/window';
|
||||
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
|
||||
import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService';
|
||||
import { ipcRenderer as ipc, webFrame, crashReporter, CrashReporterStartOptions, Event as IpcEvent } from 'electron';
|
||||
import { CrashReporterStartOptions } from 'vs/base/parts/sandbox/common/electronTypes';
|
||||
import { crashReporter, ipcRenderer, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
|
||||
import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction, SubmenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IWorkspaceFolderCreationData, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity';
|
||||
import { isRootUser, isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { MenubarControl } from '../browser/parts/titlebar/menubarControl';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IUpdateService } from 'vs/platform/update/common/update';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IPreferencesService } from '../services/preferences/common/preferences';
|
||||
import { IMenubarService, IMenubarData, IMenubarMenu, IMenubarKeybinding, IMenubarMenuItemSubmenu, IMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/node/menubar';
|
||||
import { IMenubarData, IMenubarMenu, IMenubarKeybinding, IMenubarMenuItemSubmenu, IMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenubarService } from 'vs/platform/menubar/electron-sandbox/menubar';
|
||||
import { withNullAsUndefined, assertIsDefined } from 'vs/base/common/types';
|
||||
import { IOpenerService, OpenOptions } from 'vs/platform/opener/common/opener';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { posix, dirname } from 'vs/base/common/path';
|
||||
import { getBaseLabel } from 'vs/base/common/labels';
|
||||
import { ITunnelService, extractLocalHostUriMetaDataForPortMapping } from 'vs/platform/remote/common/tunnel';
|
||||
@@ -83,7 +83,7 @@ export class NativeWindow extends Disposable {
|
||||
private isDocumentedEdited = false;
|
||||
|
||||
constructor(
|
||||
@IEditorService private readonly editorService: EditorServiceImpl,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ITitleService private readonly titleService: ITitleService,
|
||||
@IWorkbenchThemeService protected themeService: IWorkbenchThemeService,
|
||||
@@ -127,7 +127,7 @@ export class NativeWindow extends Disposable {
|
||||
});
|
||||
|
||||
// Support runAction event
|
||||
ipc.on('vscode:runAction', async (event: IpcEvent, request: IRunActionInWindowRequest) => {
|
||||
ipcRenderer.on('vscode:runAction', async (event: unknown, request: IRunActionInWindowRequest) => {
|
||||
const args: unknown[] = request.args || [];
|
||||
|
||||
// If we run an action from the touchbar, we fill in the currently active resource
|
||||
@@ -158,47 +158,47 @@ export class NativeWindow extends Disposable {
|
||||
});
|
||||
|
||||
// Support runKeybinding event
|
||||
ipc.on('vscode:runKeybinding', (event: IpcEvent, request: IRunKeybindingInWindowRequest) => {
|
||||
ipcRenderer.on('vscode:runKeybinding', (event: unknown, request: IRunKeybindingInWindowRequest) => {
|
||||
if (document.activeElement) {
|
||||
this.keybindingService.dispatchByUserSettingsLabel(request.userSettingsLabel, document.activeElement);
|
||||
}
|
||||
});
|
||||
|
||||
// Error reporting from main
|
||||
ipc.on('vscode:reportError', (event: IpcEvent, error: string) => {
|
||||
ipcRenderer.on('vscode:reportError', (event: unknown, error: string) => {
|
||||
if (error) {
|
||||
errors.onUnexpectedError(JSON.parse(error));
|
||||
}
|
||||
});
|
||||
|
||||
// Support openFiles event for existing and new files
|
||||
ipc.on('vscode:openFiles', (event: IpcEvent, request: IOpenFileRequest) => this.onOpenFiles(request));
|
||||
ipcRenderer.on('vscode:openFiles', (event: unknown, request: IOpenFileRequest) => this.onOpenFiles(request));
|
||||
|
||||
// Support addFolders event if we have a workspace opened
|
||||
ipc.on('vscode:addFolders', (event: IpcEvent, request: IAddFoldersRequest) => this.onAddFoldersRequest(request));
|
||||
ipcRenderer.on('vscode:addFolders', (event: unknown, request: IAddFoldersRequest) => this.onAddFoldersRequest(request));
|
||||
|
||||
// Message support
|
||||
ipc.on('vscode:showInfoMessage', (event: IpcEvent, message: string) => {
|
||||
ipcRenderer.on('vscode:showInfoMessage', (event: unknown, message: string) => {
|
||||
this.notificationService.info(message);
|
||||
});
|
||||
|
||||
ipc.on('vscode:displayChanged', (event: IpcEvent) => {
|
||||
ipcRenderer.on('vscode:displayChanged', () => {
|
||||
clearAllFontInfos();
|
||||
});
|
||||
|
||||
// Fullscreen Events
|
||||
ipc.on('vscode:enterFullScreen', async () => {
|
||||
ipcRenderer.on('vscode:enterFullScreen', async () => {
|
||||
await this.lifecycleService.when(LifecyclePhase.Ready);
|
||||
browser.setFullscreen(true);
|
||||
});
|
||||
|
||||
ipc.on('vscode:leaveFullScreen', async () => {
|
||||
ipcRenderer.on('vscode:leaveFullScreen', async () => {
|
||||
await this.lifecycleService.when(LifecyclePhase.Ready);
|
||||
browser.setFullscreen(false);
|
||||
});
|
||||
|
||||
// High Contrast Events
|
||||
ipc.on('vscode:enterHighContrast', async () => {
|
||||
ipcRenderer.on('vscode:enterHighContrast', async () => {
|
||||
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
|
||||
if (windowConfig?.autoDetectHighContrast) {
|
||||
await this.lifecycleService.when(LifecyclePhase.Ready);
|
||||
@@ -206,7 +206,7 @@ export class NativeWindow extends Disposable {
|
||||
}
|
||||
});
|
||||
|
||||
ipc.on('vscode:leaveHighContrast', async () => {
|
||||
ipcRenderer.on('vscode:leaveHighContrast', async () => {
|
||||
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
|
||||
if (windowConfig?.autoDetectHighContrast) {
|
||||
await this.lifecycleService.when(LifecyclePhase.Ready);
|
||||
@@ -215,12 +215,12 @@ export class NativeWindow extends Disposable {
|
||||
});
|
||||
|
||||
// keyboard layout changed event
|
||||
ipc.on('vscode:keyboardLayoutChanged', () => {
|
||||
ipcRenderer.on('vscode:keyboardLayoutChanged', () => {
|
||||
KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged();
|
||||
});
|
||||
|
||||
// accessibility support changed event
|
||||
ipc.on('vscode:accessibilitySupportChanged', (event: IpcEvent, accessibilitySupportEnabled: boolean) => {
|
||||
ipcRenderer.on('vscode:accessibilitySupportChanged', (event: unknown, accessibilitySupportEnabled: boolean) => {
|
||||
this.accessibilityService.setAccessibilitySupport(accessibilitySupportEnabled ? AccessibilitySupport.Enabled : AccessibilitySupport.Disabled);
|
||||
});
|
||||
|
||||
@@ -240,10 +240,7 @@ export class NativeWindow extends Disposable {
|
||||
// Listen to editor closing (if we run with --wait)
|
||||
const filesToWait = this.environmentService.configuration.filesToWait;
|
||||
if (filesToWait) {
|
||||
const waitMarkerFile = filesToWait.waitMarkerFileUri;
|
||||
const resourcesToWaitFor = coalesce(filesToWait.paths.map(p => p.fileUri));
|
||||
|
||||
this._register(this.trackClosedWaitFiles(waitMarkerFile, resourcesToWaitFor));
|
||||
this.trackClosedWaitFiles(filesToWait.waitMarkerFileUri, coalesce(filesToWait.paths.map(path => path.fileUri)));
|
||||
}
|
||||
|
||||
// macOS OS integration
|
||||
@@ -284,8 +281,8 @@ export class NativeWindow extends Disposable {
|
||||
|
||||
// Detect minimize / maximize
|
||||
this._register(Event.any(
|
||||
Event.map(Event.filter(this.electronService.onWindowMaximize, id => id === this.environmentService.configuration.windowId), () => true),
|
||||
Event.map(Event.filter(this.electronService.onWindowUnmaximize, id => id === this.environmentService.configuration.windowId), () => false)
|
||||
Event.map(Event.filter(this.electronService.onWindowMaximize, id => id === this.electronService.windowId), () => true),
|
||||
Event.map(Event.filter(this.electronService.onWindowUnmaximize, id => id === this.electronService.windowId), () => false)
|
||||
)(e => this.onDidChangeMaximized(e)));
|
||||
|
||||
this.onDidChangeMaximized(this.environmentService.configuration.maximized ?? false);
|
||||
@@ -399,7 +396,7 @@ export class NativeWindow extends Disposable {
|
||||
this.setupOpenHandlers();
|
||||
|
||||
// Emit event when vscode is ready
|
||||
this.lifecycleService.when(LifecyclePhase.Ready).then(() => ipc.send('vscode:workbenchReady', this.environmentService.configuration.windowId));
|
||||
this.lifecycleService.when(LifecyclePhase.Ready).then(() => ipcRenderer.send('vscode:workbenchReady', this.electronService.windowId));
|
||||
|
||||
// Integrity warning
|
||||
this.integrityService.isPure().then(res => this.titleService.updateProperties({ isPure: res.isPure }));
|
||||
@@ -430,16 +427,16 @@ export class NativeWindow extends Disposable {
|
||||
const companyName = product.crashReporter?.companyName || 'Microsoft';
|
||||
const productName = product.crashReporter?.productName || product.nameShort;
|
||||
|
||||
// With appCenter enabled, crashes will be uploaded
|
||||
if (product.appCenter) {
|
||||
this.setupCrashReporter(companyName, productName, product.appCenter, undefined);
|
||||
}
|
||||
|
||||
// With a provided crash reporter directory, crashes
|
||||
// will be stored only locally in that folder
|
||||
else if (this.environmentService.crashReporterDirectory) {
|
||||
if (this.environmentService.crashReporterDirectory) {
|
||||
this.setupCrashReporter(companyName, productName, undefined, this.environmentService.crashReporterDirectory);
|
||||
}
|
||||
|
||||
// With appCenter enabled, crashes will be uploaded
|
||||
else if (product.appCenter) {
|
||||
this.setupCrashReporter(companyName, productName, product.appCenter, undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,7 +588,7 @@ export class NativeWindow extends Disposable {
|
||||
private onAddFoldersRequest(request: IAddFoldersRequest): void {
|
||||
|
||||
// Buffer all pending requests
|
||||
this.pendingFoldersToAdd.push(...request.foldersToAdd.map(f => URI.revive(f)));
|
||||
this.pendingFoldersToAdd.push(...request.foldersToAdd.map(folder => URI.revive(folder)));
|
||||
|
||||
// Delay the adding of folders a bit to buffer in case more requests are coming
|
||||
if (!this.addFoldersScheduler.isScheduled()) {
|
||||
@@ -631,65 +628,17 @@ export class NativeWindow extends Disposable {
|
||||
// In wait mode, listen to changes to the editors and wait until the files
|
||||
// are closed that the user wants to wait for. When this happens we delete
|
||||
// the wait marker file to signal to the outside that editing is done.
|
||||
const waitMarkerFile = URI.revive(request.filesToWait.waitMarkerFileUri);
|
||||
const resourcesToWaitFor = coalesce(request.filesToWait.paths.map(p => URI.revive(p.fileUri)));
|
||||
this.trackClosedWaitFiles(waitMarkerFile, resourcesToWaitFor);
|
||||
this.trackClosedWaitFiles(URI.revive(request.filesToWait.waitMarkerFileUri), coalesce(request.filesToWait.paths.map(p => URI.revive(p.fileUri))));
|
||||
}
|
||||
}
|
||||
|
||||
private trackClosedWaitFiles(waitMarkerFile: URI, resourcesToWaitFor: URI[]): IDisposable {
|
||||
let remainingResourcesToWaitFor = resourcesToWaitFor.slice(0);
|
||||
private async trackClosedWaitFiles(waitMarkerFile: URI, resourcesToWaitFor: URI[]): Promise<void> {
|
||||
|
||||
// In wait mode, listen to changes to the editors and wait until the files
|
||||
// are closed that the user wants to wait for. When this happens we delete
|
||||
// the wait marker file to signal to the outside that editing is done.
|
||||
const listener = this.editorService.onDidCloseEditor(async event => {
|
||||
const detailsResource = toResource(event.editor, { supportSideBySide: SideBySideEditor.DETAILS });
|
||||
const masterResource = toResource(event.editor, { supportSideBySide: SideBySideEditor.MASTER });
|
||||
// Wait for the resources to be closed in the editor...
|
||||
await this.editorService.whenClosed(resourcesToWaitFor, { waitForSaved: true });
|
||||
|
||||
// Remove from resources to wait for based on the
|
||||
// resources from editors that got closed
|
||||
remainingResourcesToWaitFor = remainingResourcesToWaitFor.filter(resourceToWaitFor => {
|
||||
if (isEqual(resourceToWaitFor, masterResource) || isEqual(resourceToWaitFor, detailsResource)) {
|
||||
return false; // remove - the closing editor matches this resource
|
||||
}
|
||||
|
||||
return true; // keep - not yet closed
|
||||
});
|
||||
|
||||
if (remainingResourcesToWaitFor.length === 0) {
|
||||
// If auto save is configured with the default delay (1s) it is possible
|
||||
// to close the editor while the save still continues in the background. As such
|
||||
// we have to also check if the files to wait for are dirty and if so wait
|
||||
// for them to get saved before deleting the wait marker file.
|
||||
const dirtyFilesToWait = resourcesToWaitFor.filter(resourceToWaitFor => this.workingCopyService.isDirty(resourceToWaitFor));
|
||||
if (dirtyFilesToWait.length > 0) {
|
||||
await Promise.all(dirtyFilesToWait.map(async dirtyFileToWait => await this.joinResourceSaved(dirtyFileToWait)));
|
||||
}
|
||||
|
||||
listener.dispose();
|
||||
await this.fileService.del(waitMarkerFile);
|
||||
}
|
||||
});
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
private joinResourceSaved(resource: URI): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (!this.workingCopyService.isDirty(resource)) {
|
||||
return resolve(); // return early if resource is not dirty
|
||||
}
|
||||
|
||||
// Otherwise resolve promise when resource is saved
|
||||
const listener = this.workingCopyService.onDidChangeDirty(workingCopy => {
|
||||
if (!workingCopy.isDirty() && isEqual(resource, workingCopy.resource)) {
|
||||
listener.dispose();
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
// ...before deleting the wait marker file
|
||||
await this.fileService.del(waitMarkerFile);
|
||||
}
|
||||
|
||||
private async openResources(resources: Array<IResourceEditorInput | IUntitledTextResourceEditorInput>, diffMode: boolean): Promise<unknown> {
|
||||
@@ -726,6 +675,7 @@ class NativeMenubarControl extends MenubarControl {
|
||||
@IAccessibilityService accessibilityService: IAccessibilityService,
|
||||
@IMenubarService private readonly menubarService: IMenubarService,
|
||||
@IHostService hostService: IHostService,
|
||||
@IElectronService private readonly electronService: IElectronService
|
||||
) {
|
||||
super(
|
||||
menuService,
|
||||
@@ -774,7 +724,7 @@ class NativeMenubarControl extends MenubarControl {
|
||||
// Send menus to main process to be rendered by Electron
|
||||
const menubarData = { menus: {}, keybindings: {} };
|
||||
if (this.getMenubarMenus(menubarData)) {
|
||||
this.menubarService.updateMenubar(this.environmentService.configuration.windowId, menubarData);
|
||||
this.menubarService.updateMenubar(this.electronService.windowId, menubarData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user