mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 11:08:31 -05:00
Merge vscode 1.67 (#20883)
* Fix initial build breaks from 1.67 merge (#2514) * Update yarn lock files * Update build scripts * Fix tsconfig * Build breaks * WIP * Update yarn lock files * Misc breaks * Updates to package.json * Breaks * Update yarn * Fix breaks * Breaks * Build breaks * Breaks * Breaks * Breaks * Breaks * Breaks * Missing file * Breaks * Breaks * Breaks * Breaks * Breaks * Fix several runtime breaks (#2515) * Missing files * Runtime breaks * Fix proxy ordering issue * Remove commented code * Fix breaks with opening query editor * Fix post merge break * Updates related to setup build and other breaks (#2516) * Fix bundle build issues * Update distro * Fix distro merge and update build JS files * Disable pipeline steps * Remove stats call * Update license name * Make new RPM dependencies a warning * Fix extension manager version checks * Update JS file * Fix a few runtime breaks * Fixes * Fix runtime issues * Fix build breaks * Update notebook tests (part 1) * Fix broken tests * Linting errors * Fix hygiene * Disable lint rules * Bump distro * Turn off smoke tests * Disable integration tests * Remove failing "activate" test * Remove failed test assertion * Disable other broken test * Disable query history tests * Disable extension unit tests * Disable failing tasks
This commit is contained in:
@@ -1,316 +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 { PerformanceMark } from 'vs/base/common/performance';
|
||||
import { isLinux, isMacintosh, isNative, isWeb } from 'vs/base/common/platform';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ISandboxConfiguration } from 'vs/base/parts/sandbox/common/sandboxTypes';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { LogLevel } from 'vs/platform/log/common/log';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export const WindowMinimumSize = {
|
||||
WIDTH: 400,
|
||||
WIDTH_WITH_VERTICAL_PANEL: 600,
|
||||
HEIGHT: 270
|
||||
};
|
||||
|
||||
export interface IBaseOpenWindowsOptions {
|
||||
|
||||
/**
|
||||
* Whether to reuse the window or open a new one.
|
||||
*/
|
||||
readonly forceReuseWindow?: boolean;
|
||||
|
||||
/**
|
||||
* The remote authority to use when windows are opened with either
|
||||
* - no workspace (empty window)
|
||||
* - a workspace that is neither `file://` nor `vscode-remote://`
|
||||
* Use 'null' for a local window.
|
||||
* If not set, defaults to the remote authority of the current window.
|
||||
*/
|
||||
readonly remoteAuthority?: string | null;
|
||||
}
|
||||
|
||||
export interface IOpenWindowOptions extends IBaseOpenWindowsOptions {
|
||||
readonly forceNewWindow?: boolean;
|
||||
readonly preferNewWindow?: boolean;
|
||||
|
||||
readonly noRecentEntry?: boolean;
|
||||
|
||||
readonly addMode?: boolean;
|
||||
|
||||
readonly diffMode?: boolean;
|
||||
readonly gotoLineMode?: boolean;
|
||||
|
||||
readonly waitMarkerFileURI?: URI;
|
||||
}
|
||||
|
||||
export interface IAddFoldersRequest {
|
||||
readonly foldersToAdd: UriComponents[];
|
||||
}
|
||||
|
||||
export interface IOpenedWindow {
|
||||
readonly id: number;
|
||||
readonly workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier;
|
||||
readonly title: string;
|
||||
readonly filename?: string;
|
||||
readonly dirty: boolean;
|
||||
}
|
||||
|
||||
export interface IOpenEmptyWindowOptions extends IBaseOpenWindowsOptions { }
|
||||
|
||||
export type IWindowOpenable = IWorkspaceToOpen | IFolderToOpen | IFileToOpen;
|
||||
|
||||
export interface IBaseWindowOpenable {
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface IWorkspaceToOpen extends IBaseWindowOpenable {
|
||||
readonly workspaceUri: URI;
|
||||
}
|
||||
|
||||
export interface IFolderToOpen extends IBaseWindowOpenable {
|
||||
readonly folderUri: URI;
|
||||
}
|
||||
|
||||
export interface IFileToOpen extends IBaseWindowOpenable {
|
||||
readonly fileUri: URI;
|
||||
}
|
||||
|
||||
export function isWorkspaceToOpen(uriToOpen: IWindowOpenable): uriToOpen is IWorkspaceToOpen {
|
||||
return !!(uriToOpen as IWorkspaceToOpen).workspaceUri;
|
||||
}
|
||||
|
||||
export function isFolderToOpen(uriToOpen: IWindowOpenable): uriToOpen is IFolderToOpen {
|
||||
return !!(uriToOpen as IFolderToOpen).folderUri;
|
||||
}
|
||||
|
||||
export function isFileToOpen(uriToOpen: IWindowOpenable): uriToOpen is IFileToOpen {
|
||||
return !!(uriToOpen as IFileToOpen).fileUri;
|
||||
}
|
||||
|
||||
export type MenuBarVisibility = 'classic' | 'visible' | 'toggle' | 'hidden' | 'compact';
|
||||
|
||||
export function getMenuBarVisibility(configurationService: IConfigurationService): MenuBarVisibility {
|
||||
const titleBarStyle = getTitleBarStyle(configurationService);
|
||||
const menuBarVisibility = configurationService.getValue<MenuBarVisibility | 'default'>('window.menuBarVisibility');
|
||||
|
||||
if (menuBarVisibility === 'default' || (titleBarStyle === 'native' && menuBarVisibility === 'compact') || (isMacintosh && isNative)) {
|
||||
return 'classic';
|
||||
} else {
|
||||
return menuBarVisibility;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IWindowsConfiguration {
|
||||
readonly window: IWindowSettings;
|
||||
}
|
||||
|
||||
export interface IWindowSettings {
|
||||
readonly openFilesInNewWindow: 'on' | 'off' | 'default';
|
||||
readonly openFoldersInNewWindow: 'on' | 'off' | 'default';
|
||||
readonly openWithoutArgumentsInNewWindow: 'on' | 'off';
|
||||
readonly restoreWindows: 'preserve' | 'all' | 'folders' | 'one' | 'none';
|
||||
readonly restoreFullscreen: boolean;
|
||||
readonly zoomLevel: number;
|
||||
readonly titleBarStyle: 'native' | 'custom';
|
||||
readonly autoDetectHighContrast: boolean;
|
||||
readonly menuBarVisibility: MenuBarVisibility;
|
||||
readonly newWindowDimensions: 'default' | 'inherit' | 'offset' | 'maximized' | 'fullscreen';
|
||||
readonly nativeTabs: boolean;
|
||||
readonly nativeFullScreen: boolean;
|
||||
readonly enableMenuBarMnemonics: boolean;
|
||||
readonly closeWhenEmpty: boolean;
|
||||
readonly clickThroughInactive: boolean;
|
||||
}
|
||||
|
||||
interface IWindowBorderColors {
|
||||
readonly 'window.activeBorder'?: string;
|
||||
readonly 'window.inactiveBorder'?: string;
|
||||
}
|
||||
|
||||
export function getTitleBarStyle(configurationService: IConfigurationService): 'native' | 'custom' {
|
||||
if (isWeb) {
|
||||
return 'custom';
|
||||
}
|
||||
|
||||
const configuration = configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
if (configuration) {
|
||||
const useNativeTabs = isMacintosh && configuration.nativeTabs === true;
|
||||
if (useNativeTabs) {
|
||||
return 'native'; // native tabs on sierra do not work with custom title style
|
||||
}
|
||||
|
||||
const useSimpleFullScreen = isMacintosh && configuration.nativeFullScreen === false;
|
||||
if (useSimpleFullScreen) {
|
||||
return 'native'; // simple fullscreen does not work well with custom title style (https://github.com/microsoft/vscode/issues/63291)
|
||||
}
|
||||
|
||||
const colorCustomizations = configurationService.getValue<IWindowBorderColors | undefined>('workbench.colorCustomizations');
|
||||
if (colorCustomizations?.['window.activeBorder'] || colorCustomizations?.['window.inactiveBorder']) {
|
||||
return 'custom'; // window border colors do not work with native title style
|
||||
}
|
||||
|
||||
const style = configuration.titleBarStyle;
|
||||
if (style === 'native' || style === 'custom') {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
return isLinux ? 'native' : 'custom'; // default to custom on all macOS and Windows
|
||||
}
|
||||
|
||||
export interface IPath extends IPathData {
|
||||
|
||||
// the file path to open within the instance
|
||||
fileUri?: URI;
|
||||
}
|
||||
|
||||
export interface IPathData {
|
||||
|
||||
// the file path to open within the instance
|
||||
readonly fileUri?: UriComponents;
|
||||
|
||||
/**
|
||||
* An optional selection to apply in the file
|
||||
*/
|
||||
readonly selection?: {
|
||||
readonly startLineNumber: number;
|
||||
readonly startColumn: number;
|
||||
readonly endLineNumber?: number;
|
||||
readonly endColumn?: number;
|
||||
}
|
||||
|
||||
// a hint that the file exists. if true, the
|
||||
// file exists, if false it does not. with
|
||||
// undefined the state is unknown.
|
||||
readonly exists?: boolean;
|
||||
|
||||
// Specifies if the file should be only be opened if it exists
|
||||
readonly openOnlyIfExists?: boolean;
|
||||
|
||||
// Specifies an optional id to override the editor used to edit the resource, e.g. custom editor.
|
||||
readonly editorOverrideId?: string;
|
||||
}
|
||||
|
||||
export interface IPathsToWaitFor extends IPathsToWaitForData {
|
||||
paths: IPath[];
|
||||
waitMarkerFileUri: URI;
|
||||
}
|
||||
|
||||
interface IPathsToWaitForData {
|
||||
readonly paths: IPathData[];
|
||||
readonly waitMarkerFileUri: UriComponents;
|
||||
}
|
||||
|
||||
export interface IOpenFileRequest {
|
||||
readonly filesToOpenOrCreate?: IPathData[];
|
||||
readonly filesToDiff?: IPathData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional context for the request on native only.
|
||||
*/
|
||||
export interface INativeOpenFileRequest extends IOpenFileRequest {
|
||||
readonly termProgram?: string;
|
||||
readonly filesToWait?: IPathsToWaitForData;
|
||||
}
|
||||
|
||||
export interface INativeRunActionInWindowRequest {
|
||||
readonly id: string;
|
||||
readonly from: 'menu' | 'touchbar' | 'mouse';
|
||||
readonly args?: any[];
|
||||
}
|
||||
|
||||
export interface INativeRunKeybindingInWindowRequest {
|
||||
readonly userSettingsLabel: string;
|
||||
}
|
||||
|
||||
export interface IColorScheme {
|
||||
readonly dark: boolean;
|
||||
readonly highContrast: boolean;
|
||||
}
|
||||
|
||||
export interface IWindowConfiguration {
|
||||
remoteAuthority?: string;
|
||||
|
||||
filesToOpenOrCreate?: IPath[];
|
||||
filesToDiff?: IPath[];
|
||||
}
|
||||
|
||||
export interface IOSConfiguration {
|
||||
readonly release: string;
|
||||
readonly hostname: string;
|
||||
}
|
||||
|
||||
export interface IPartsSplash {
|
||||
baseTheme: string;
|
||||
colorInfo: {
|
||||
background: string;
|
||||
foreground: string | undefined;
|
||||
editorBackground: string | undefined;
|
||||
titleBarBackground: string | undefined;
|
||||
activityBarBackground: string | undefined;
|
||||
sideBarBackground: string | undefined;
|
||||
statusBarBackground: string | undefined;
|
||||
statusBarNoFolderBackground: string | undefined;
|
||||
windowBorder: string | undefined;
|
||||
}
|
||||
layoutInfo: {
|
||||
sideBarSide: string;
|
||||
editorPartMinWidth: number;
|
||||
titleBarHeight: number;
|
||||
activityBarWidth: number;
|
||||
sideBarWidth: number;
|
||||
statusBarHeight: number;
|
||||
windowBorder: boolean;
|
||||
windowBorderRadius: string | undefined;
|
||||
} | undefined
|
||||
}
|
||||
|
||||
export interface INativeWindowConfiguration extends IWindowConfiguration, NativeParsedArgs, ISandboxConfiguration {
|
||||
mainPid: number;
|
||||
|
||||
machineId: string;
|
||||
|
||||
execPath: string;
|
||||
backupPath?: string;
|
||||
|
||||
homeDir: string;
|
||||
tmpDir: string;
|
||||
userDataDir: string;
|
||||
|
||||
partsSplash?: IPartsSplash;
|
||||
|
||||
workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier;
|
||||
|
||||
isInitialStartup?: boolean;
|
||||
logLevel: LogLevel;
|
||||
|
||||
fullscreen?: boolean;
|
||||
maximized?: boolean;
|
||||
accessibilitySupport?: boolean;
|
||||
colorScheme: IColorScheme;
|
||||
autoDetectHighContrast?: boolean;
|
||||
|
||||
legacyWatcher?: string; // TODO@bpasero remove me once watcher is settled
|
||||
experimentalSandboxedFileService?: boolean; // TODO@bpasero remove me once sandbox is settled
|
||||
|
||||
perfMarks: PerformanceMark[];
|
||||
|
||||
filesToWait?: IPathsToWaitFor;
|
||||
|
||||
os: IOSConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* According to Electron docs: `scale := 1.2 ^ level`.
|
||||
* https://github.com/electron/electron/blob/master/docs/api/web-contents.md#contentssetzoomlevellevel
|
||||
*/
|
||||
export function zoomLevelToZoomFactor(zoomLevel = 0): number {
|
||||
return Math.pow(1.2, zoomLevel);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, Display, Event, nativeImage, NativeImage, Rectangle, screen, SegmentedControlSegment, systemPreferences, TouchBar, TouchBarSegmentedControl, WebFrameMain } from 'electron';
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, Display, Event, nativeImage, NativeImage, Rectangle, screen, SegmentedControlSegment, systemPreferences, TouchBar, TouchBarSegmentedControl } from 'electron';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
@@ -16,27 +16,29 @@ import { getMarks, mark } from 'vs/base/common/performance';
|
||||
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { ISerializableCommandAction } from 'vs/platform/action/common/action';
|
||||
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
|
||||
import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protocol';
|
||||
import { IStorageMainService } from 'vs/platform/storage/electron-main/storageMainService';
|
||||
import { resolveMarketplaceHeaders } from 'vs/platform/externalServices/common/marketplace';
|
||||
import { IGlobalStorageMainService, IStorageMainService } from 'vs/platform/storage/electron-main/storageMainService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
|
||||
import { getMenuBarVisibility, getTitleBarStyle, IFolderToOpen, INativeWindowConfiguration, IWindowSettings, IWorkspaceToOpen, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
|
||||
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowsMainService, IWindowState, LoadReason, OpenContext, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { getMenuBarVisibility, getTitleBarStyle, IFolderToOpen, INativeWindowConfiguration, IWindowSettings, IWorkspaceToOpen, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/window/common/window';
|
||||
import { IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
|
||||
import { IWindowState, ICodeWindow, ILoadEvent, WindowMode, WindowError, LoadReason, defaultWindowState } from 'vs/platform/window/electron-main/window';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
export interface IWindowCreationOptions {
|
||||
state: IWindowState;
|
||||
@@ -56,22 +58,21 @@ interface ILoadOptions {
|
||||
const enum ReadyState {
|
||||
|
||||
/**
|
||||
* This window has not loaded any HTML yet
|
||||
* This window has not loaded anything yet
|
||||
* and this is the initial state of every
|
||||
* window.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* This window is loading HTML
|
||||
*/
|
||||
LOADING,
|
||||
|
||||
/**
|
||||
* This window is navigating to another HTML
|
||||
* This window is navigating, either for the
|
||||
* first time or subsequent times.
|
||||
*/
|
||||
NAVIGATING,
|
||||
|
||||
/**
|
||||
* This window is done loading HTML
|
||||
* This window has finished loading and is ready
|
||||
* to forward IPC requests to the web contents.
|
||||
*/
|
||||
READY
|
||||
}
|
||||
@@ -106,23 +107,23 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
private _lastFocusTime = -1;
|
||||
get lastFocusTime(): number { return this._lastFocusTime; }
|
||||
|
||||
get backupPath(): string | undefined { return this.currentConfig?.backupPath; }
|
||||
get backupPath(): string | undefined { return this._config?.backupPath; }
|
||||
|
||||
get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this.currentConfig?.workspace; }
|
||||
get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this._config?.workspace; }
|
||||
|
||||
get remoteAuthority(): string | undefined { return this.currentConfig?.remoteAuthority; }
|
||||
get remoteAuthority(): string | undefined { return this._config?.remoteAuthority; }
|
||||
|
||||
private currentConfig: INativeWindowConfiguration | undefined;
|
||||
get config(): INativeWindowConfiguration | undefined { return this.currentConfig; }
|
||||
private _config: INativeWindowConfiguration | undefined;
|
||||
get config(): INativeWindowConfiguration | undefined { return this._config; }
|
||||
|
||||
private hiddenTitleBarStyle: boolean | undefined;
|
||||
get hasHiddenTitleBarStyle(): boolean { return !!this.hiddenTitleBarStyle; }
|
||||
|
||||
get isExtensionDevelopmentHost(): boolean { return !!(this.currentConfig?.extensionDevelopmentPath); }
|
||||
get isExtensionDevelopmentHost(): boolean { return !!(this._config?.extensionDevelopmentPath); }
|
||||
|
||||
get isExtensionTestHost(): boolean { return !!(this.currentConfig?.extensionTestsPath); }
|
||||
get isExtensionTestHost(): boolean { return !!(this._config?.extensionTestsPath); }
|
||||
|
||||
get isExtensionDevelopmentTestFromCli(): boolean { return this.isExtensionDevelopmentHost && this.isExtensionTestHost && !this.currentConfig?.debugId; }
|
||||
get isExtensionDevelopmentTestFromCli(): boolean { return this.isExtensionDevelopmentHost && this.isExtensionTestHost && !this._config?.debugId; }
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -137,7 +138,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
private readonly touchBarGroups: TouchBarSegmentedControl[] = [];
|
||||
|
||||
private marketplaceHeadersPromise: Promise<object>;
|
||||
private currentHttpProxy: string | undefined = undefined;
|
||||
private currentNoProxy: string | undefined = undefined;
|
||||
|
||||
@@ -150,7 +150,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IStorageMainService storageMainService: IStorageMainService,
|
||||
@IGlobalStorageMainService private readonly globalStorageMainService: IGlobalStorageMainService,
|
||||
@IStorageMainService private readonly storageMainService: IStorageMainService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IThemeMainService private readonly themeMainService: IThemeMainService,
|
||||
@IWorkspacesManagementMainService private readonly workspacesManagementMainService: IWorkspacesManagementMainService,
|
||||
@@ -176,7 +177,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
const windowSettings = this.configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
|
||||
const options: BrowserWindowConstructorOptions = {
|
||||
const options: BrowserWindowConstructorOptions & { experimentalDarkMode: boolean } = {
|
||||
width: this.windowState.width,
|
||||
height: this.windowState.height,
|
||||
x: this.windowState.x,
|
||||
@@ -194,6 +195,9 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
spellcheck: false,
|
||||
nativeWindowOpen: true,
|
||||
zoomFactor: zoomLevelToZoomFactor(windowSettings?.zoomLevel),
|
||||
// Enable experimental css highlight api https://chromestatus.com/feature/5436441440026624
|
||||
// Refs https://github.com/microsoft/vscode/issues/140098
|
||||
enableBlinkFeatures: 'HighlightAPI',
|
||||
...this.environmentMainService.sandbox ?
|
||||
|
||||
// Sandbox
|
||||
@@ -206,7 +210,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
}
|
||||
},
|
||||
experimentalDarkMode: true
|
||||
};
|
||||
|
||||
// Apply icon to window
|
||||
@@ -242,6 +247,19 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
if (!isMacintosh) {
|
||||
options.frame = false;
|
||||
}
|
||||
|
||||
if (isWindows) {
|
||||
// This logic will not perfectly guess the right colors to use on initialization,
|
||||
// but prefer to keep things simple as it is temporary and not noticeable
|
||||
const titleBarColor = this.themeMainService.getWindowSplash()?.colorInfo.titleBarBackground ?? this.themeMainService.getBackgroundColor();
|
||||
const symbolColor = Color.fromHex(titleBarColor).isDarker() ? '#FFFFFF' : '#000000';
|
||||
|
||||
options.titleBarOverlay = {
|
||||
height: 29, // The smallest size of the title bar on windows accounting for the border on windows 11
|
||||
color: titleBarColor,
|
||||
symbolColor
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Create the browser window
|
||||
@@ -303,12 +321,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// macOS: touch bar support
|
||||
this.createTouchBar();
|
||||
|
||||
// Request handling
|
||||
this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.productService.version, this.productService, this.environmentMainService, this.configurationService, this.fileService, {
|
||||
get: key => storageMainService.globalStorage.get(key),
|
||||
store: (key, value) => storageMainService.globalStorage.set(key, value)
|
||||
});
|
||||
|
||||
// Eventing
|
||||
this.registerListeners();
|
||||
}
|
||||
@@ -371,6 +383,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
private readyState = ReadyState.NONE;
|
||||
|
||||
setReady(): void {
|
||||
this.logService.trace(`window#load: window reported ready (id: ${this._id})`);
|
||||
|
||||
this.readyState = ReadyState.READY;
|
||||
|
||||
// inform all waiting promises that we are ready now
|
||||
@@ -435,68 +449,12 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
this.dispose();
|
||||
});
|
||||
|
||||
// Block all SVG requests from unsupported origins
|
||||
const supportedSvgSchemes = new Set([Schemas.file, Schemas.vscodeFileResource, Schemas.vscodeRemoteResource, 'devtools']);
|
||||
|
||||
// But allow them if the are made from inside an webview
|
||||
const isSafeFrame = (requestFrame: WebFrameMain | undefined): boolean => {
|
||||
for (let frame: WebFrameMain | null | undefined = requestFrame; frame; frame = frame.parent) {
|
||||
if (frame.url.startsWith(`${Schemas.vscodeWebview}://`)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const isRequestFromSafeContext = (details: Electron.OnBeforeRequestListenerDetails | Electron.OnHeadersReceivedListenerDetails): boolean => {
|
||||
return details.resourceType === 'xhr' || isSafeFrame(details.frame);
|
||||
};
|
||||
|
||||
this._win.webContents.session.webRequest.onBeforeRequest((details, callback) => {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri.path.endsWith('.svg')) {
|
||||
const isSafeResourceUrl = supportedSvgSchemes.has(uri.scheme);
|
||||
if (!isSafeResourceUrl) {
|
||||
return callback({ cancel: !isRequestFromSafeContext(details) });
|
||||
}
|
||||
}
|
||||
|
||||
return callback({ cancel: false });
|
||||
});
|
||||
|
||||
// Configure SVG header content type properly
|
||||
// https://github.com/microsoft/vscode/issues/97564
|
||||
this._win.webContents.session.webRequest.onHeadersReceived((details, callback) => {
|
||||
const responseHeaders = details.responseHeaders as Record<string, (string) | (string[])>;
|
||||
const contentTypes = (responseHeaders['content-type'] || responseHeaders['Content-Type']);
|
||||
|
||||
if (contentTypes && Array.isArray(contentTypes)) {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri.path.endsWith('.svg')) {
|
||||
if (supportedSvgSchemes.has(uri.scheme)) {
|
||||
responseHeaders['Content-Type'] = ['image/svg+xml'];
|
||||
|
||||
return callback({ cancel: false, responseHeaders });
|
||||
}
|
||||
}
|
||||
|
||||
// remote extension schemes have the following format
|
||||
// http://127.0.0.1:<port>/vscode-remote-resource?path=
|
||||
if (!uri.path.includes(Schemas.vscodeRemoteResource) && contentTypes.some(contentType => contentType.toLowerCase().includes('image/svg'))) {
|
||||
return callback({ cancel: !isRequestFromSafeContext(details) });
|
||||
}
|
||||
}
|
||||
|
||||
return callback({ cancel: false });
|
||||
});
|
||||
|
||||
// Remember that we loaded
|
||||
this._win.webContents.on('did-finish-load', () => {
|
||||
this.readyState = ReadyState.LOADING;
|
||||
|
||||
// Associate properties from the load request if provided
|
||||
if (this.pendingLoadConfig) {
|
||||
this.currentConfig = this.pendingLoadConfig;
|
||||
this._config = this.pendingLoadConfig;
|
||||
|
||||
this.pendingLoadConfig = undefined;
|
||||
}
|
||||
@@ -509,16 +467,16 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
// Window (Un)Maximize
|
||||
this._win.on('maximize', (e: Event) => {
|
||||
if (this.currentConfig) {
|
||||
this.currentConfig.maximized = true;
|
||||
if (this._config) {
|
||||
this._config.maximized = true;
|
||||
}
|
||||
|
||||
app.emit('browser-window-maximize', e, this._win);
|
||||
});
|
||||
|
||||
this._win.on('unmaximize', (e: Event) => {
|
||||
if (this.currentConfig) {
|
||||
this.currentConfig.maximized = false;
|
||||
if (this._config) {
|
||||
this._config.maximized = false;
|
||||
}
|
||||
|
||||
app.emit('browser-window-unmaximize', e, this._win);
|
||||
@@ -542,16 +500,25 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// Inject headers when requests are incoming
|
||||
const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*'];
|
||||
this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, async (details, cb) => {
|
||||
const headers = await this.marketplaceHeadersPromise;
|
||||
const headers = await this.getMarketplaceHeaders();
|
||||
|
||||
cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) });
|
||||
});
|
||||
}
|
||||
|
||||
private marketplaceHeadersPromise: Promise<object> | undefined;
|
||||
private getMarketplaceHeaders(): Promise<object> {
|
||||
if (!this.marketplaceHeadersPromise) {
|
||||
this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.productService.version, this.productService, this.environmentMainService, this.configurationService, this.fileService, this.globalStorageMainService);
|
||||
}
|
||||
|
||||
return this.marketplaceHeadersPromise;
|
||||
}
|
||||
|
||||
private async onWindowError(error: WindowError.UNRESPONSIVE): Promise<void>;
|
||||
private async onWindowError(error: WindowError.CRASHED, details: { reason: string, exitCode: number }): Promise<void>;
|
||||
private async onWindowError(error: WindowError.LOAD, details: { reason: string, exitCode: number }): Promise<void>;
|
||||
private async onWindowError(type: WindowError, details?: { reason: string, exitCode: number }): Promise<void> {
|
||||
private async onWindowError(error: WindowError.CRASHED, details: { reason: string; exitCode: number }): Promise<void>;
|
||||
private async onWindowError(error: WindowError.LOAD, details: { reason: string; exitCode: number }): Promise<void>;
|
||||
private async onWindowError(type: WindowError, details?: { reason: string; exitCode: number }): Promise<void> {
|
||||
|
||||
switch (type) {
|
||||
case WindowError.CRASHED:
|
||||
@@ -567,9 +534,11 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
// Telemetry
|
||||
type WindowErrorClassification = {
|
||||
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
reason: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
code: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of window crash to understand the nature of the crash better.' };
|
||||
reason: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The reason of the window crash to understand the nature of the crash better.' };
|
||||
code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; omment: 'The exit code of the window process to understand the nature of the crash better' };
|
||||
owner: 'bpasero';
|
||||
comment: 'Provides insight into reasons the vscode window crashes.';
|
||||
};
|
||||
type WindowErrorEvent = {
|
||||
type: WindowError;
|
||||
@@ -591,6 +560,12 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we run smoke tests, we never want to show a blocking dialog
|
||||
if (this.environmentMainService.args['enable-smoke-test-driver']) {
|
||||
this.destroyWindow(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unresponsive
|
||||
if (type === WindowError.UNRESPONSIVE) {
|
||||
if (this.isExtensionDevelopmentHost || this.isExtensionTestHost || (this._win && this._win.webContents && this._win.webContents.isDevToolsOpened())) {
|
||||
@@ -616,13 +591,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
|
||||
noLink: true,
|
||||
defaultId: 0,
|
||||
cancelId: 1
|
||||
cancelId: 1,
|
||||
checkboxLabel: this._config?.workspace ? localize('doNotRestoreEditors', "Don't restore editors") : undefined
|
||||
}, this._win);
|
||||
|
||||
// Handle choice
|
||||
if (result.response !== 1 /* keep waiting */) {
|
||||
const reopen = result.response === 0;
|
||||
this.destroyWindow(reopen);
|
||||
this.destroyWindow(reopen, result.checkboxChecked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,18 +622,32 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
message,
|
||||
detail: localize('appCrashedDetail', "We are sorry for the inconvenience. You can reopen the window to continue where you left off."),
|
||||
noLink: true,
|
||||
defaultId: 0
|
||||
defaultId: 0,
|
||||
checkboxLabel: this._config?.workspace ? localize('doNotRestoreEditors', "Don't restore editors") : undefined
|
||||
}, this._win);
|
||||
|
||||
// Handle choice
|
||||
const reopen = result.response === 0;
|
||||
this.destroyWindow(reopen);
|
||||
this.destroyWindow(reopen, result.checkboxChecked);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private destroyWindow(reopen: boolean): void {
|
||||
private async destroyWindow(reopen: boolean, skipRestoreEditors: boolean): Promise<void> {
|
||||
const workspace = this._config?.workspace;
|
||||
|
||||
// check to discard editor state first
|
||||
if (skipRestoreEditors && workspace) {
|
||||
try {
|
||||
const workspaceStorage = this.storageMainService.workspaceStorage(workspace);
|
||||
await workspaceStorage.init();
|
||||
workspaceStorage.delete('memento/workbench.parts.editor');
|
||||
await workspaceStorage.close();
|
||||
} catch (error) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 'close' event will not be fired on destroy(), so signal crash via explicit event
|
||||
this._onDidDestroy.fire();
|
||||
@@ -666,15 +656,15 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
this._win?.destroy();
|
||||
|
||||
// ask the windows service to open a new fresh window if specified
|
||||
if (reopen && this.config) {
|
||||
if (reopen && this._config) {
|
||||
|
||||
// We have to reconstruct a openable from the current workspace
|
||||
let workspace: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
|
||||
let uriToOpen: IWorkspaceToOpen | IFolderToOpen | undefined = undefined;
|
||||
let forceEmpty = undefined;
|
||||
if (isSingleFolderWorkspaceIdentifier(this.openedWorkspace)) {
|
||||
workspace = { folderUri: this.openedWorkspace.uri };
|
||||
} else if (isWorkspaceIdentifier(this.openedWorkspace)) {
|
||||
workspace = { workspaceUri: this.openedWorkspace.configPath };
|
||||
if (isSingleFolderWorkspaceIdentifier(workspace)) {
|
||||
uriToOpen = { folderUri: workspace.uri };
|
||||
} else if (isWorkspaceIdentifier(workspace)) {
|
||||
uriToOpen = { workspaceUri: workspace.configPath };
|
||||
} else {
|
||||
forceEmpty = true;
|
||||
}
|
||||
@@ -682,14 +672,15 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// Delegate to windows service
|
||||
const [window] = this.windowsMainService.open({
|
||||
context: OpenContext.API,
|
||||
userEnv: this.config.userEnv,
|
||||
userEnv: this._config.userEnv,
|
||||
cli: {
|
||||
...this.environmentMainService.args,
|
||||
_: [] // we pass in the workspace to open explicitly via `urisToOpen`
|
||||
},
|
||||
urisToOpen: workspace ? [workspace] : undefined,
|
||||
urisToOpen: uriToOpen ? [uriToOpen] : undefined,
|
||||
forceEmpty,
|
||||
forceNewWindow: true
|
||||
forceNewWindow: true,
|
||||
remoteAuthority: this.remoteAuthority
|
||||
});
|
||||
window.focus();
|
||||
}
|
||||
@@ -699,8 +690,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
// Make sure to update our workspace config if we detect that it
|
||||
// was deleted
|
||||
if (this.openedWorkspace?.id === workspace.id && this.currentConfig) {
|
||||
this.currentConfig.workspace = undefined;
|
||||
if (this._config?.workspace?.id === workspace.id && this._config) {
|
||||
this._config.workspace = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,6 +732,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
}
|
||||
|
||||
load(configuration: INativeWindowConfiguration, options: ILoadOptions = Object.create(null)): void {
|
||||
this.logService.trace(`window#load: attempt to load window (id: ${this._id})`);
|
||||
|
||||
// Clear Document Edited if needed
|
||||
if (this.isDocumentEdited()) {
|
||||
@@ -765,7 +757,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// If this is the first time the window is loaded, we associate the paths
|
||||
// directly with the window because we assume the loading will just work
|
||||
if (this.readyState === ReadyState.NONE) {
|
||||
this.currentConfig = configuration;
|
||||
this._config = configuration;
|
||||
}
|
||||
|
||||
// Otherwise, the window is currently showing a folder and if there is an
|
||||
@@ -774,9 +766,11 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// the window load event has fired.
|
||||
else {
|
||||
this.pendingLoadConfig = configuration;
|
||||
this.readyState = ReadyState.NAVIGATING;
|
||||
}
|
||||
|
||||
// Indicate we are navigting now
|
||||
this.readyState = ReadyState.NAVIGATING;
|
||||
|
||||
// Load URL
|
||||
this._win.loadURL(FileAccess.asBrowserUri(this.environmentMainService.sandbox ?
|
||||
'vs/code/electron-sandbox/workbench/workbench.html' :
|
||||
@@ -814,7 +808,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// Also, preserve the environment if we're loading from an
|
||||
// extension development host that had its environment set
|
||||
// (for https://github.com/microsoft/vscode/issues/123508)
|
||||
const currentUserEnv = (this.currentConfig ?? this.pendingLoadConfig)?.userEnv;
|
||||
const currentUserEnv = (this._config ?? this.pendingLoadConfig)?.userEnv;
|
||||
if (currentUserEnv) {
|
||||
const shouldPreserveLaunchCliEnvironment = isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(configuration.userEnv);
|
||||
const shouldPreserveDebugEnvironmnet = this.isExtensionDevelopmentHost;
|
||||
@@ -854,7 +848,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
async reload(cli?: NativeParsedArgs): Promise<void> {
|
||||
|
||||
// Copy our current config for reuse
|
||||
const configuration = Object.assign({}, this.currentConfig);
|
||||
const configuration = Object.assign({}, this._config);
|
||||
|
||||
// Validate workspace
|
||||
configuration.workspace = await this.validateWorkspaceBeforeReload(configuration);
|
||||
|
||||
@@ -3,195 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { BrowserWindow, Rectangle, WebContents } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { WebContents } from 'electron';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INativeWindowConfiguration, IOpenEmptyWindowOptions, IWindowOpenable } from 'vs/platform/windows/common/windows';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export const enum LoadReason {
|
||||
|
||||
/**
|
||||
* The window is loaded for the first time.
|
||||
*/
|
||||
INITIAL = 1,
|
||||
|
||||
/**
|
||||
* The window is loaded into a different workspace context.
|
||||
*/
|
||||
LOAD,
|
||||
|
||||
/**
|
||||
* The window is reloaded.
|
||||
*/
|
||||
RELOAD
|
||||
}
|
||||
|
||||
export const enum UnloadReason {
|
||||
|
||||
/**
|
||||
* The window is closed.
|
||||
*/
|
||||
CLOSE = 1,
|
||||
|
||||
/**
|
||||
* All windows unload because the application quits.
|
||||
*/
|
||||
QUIT,
|
||||
|
||||
/**
|
||||
* The window is reloaded.
|
||||
*/
|
||||
RELOAD,
|
||||
|
||||
/**
|
||||
* The window is loaded into a different workspace context.
|
||||
*/
|
||||
LOAD
|
||||
}
|
||||
|
||||
export const enum OpenContext {
|
||||
|
||||
// opening when running from the command line
|
||||
CLI,
|
||||
|
||||
// macOS only: opening from the dock (also when opening files to a running instance from desktop)
|
||||
DOCK,
|
||||
|
||||
// opening from the main application window
|
||||
MENU,
|
||||
|
||||
// opening from a file or folder dialog
|
||||
DIALOG,
|
||||
|
||||
// opening from the OS's UI
|
||||
DESKTOP,
|
||||
|
||||
// opening through the API
|
||||
API
|
||||
}
|
||||
|
||||
export interface IWindowState {
|
||||
width?: number;
|
||||
height?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
mode?: WindowMode;
|
||||
display?: number;
|
||||
}
|
||||
|
||||
export const defaultWindowState = function (mode = WindowMode.Normal): IWindowState {
|
||||
return {
|
||||
width: 1024,
|
||||
height: 768,
|
||||
mode
|
||||
};
|
||||
};
|
||||
|
||||
export const enum WindowMode {
|
||||
Maximized,
|
||||
Normal,
|
||||
Minimized, // not used anymore, but also cannot remove due to existing stored UI state (needs migration)
|
||||
Fullscreen
|
||||
}
|
||||
|
||||
export interface ILoadEvent {
|
||||
workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined;
|
||||
reason: LoadReason;
|
||||
}
|
||||
|
||||
export interface ICodeWindow extends IDisposable {
|
||||
|
||||
readonly onWillLoad: Event<ILoadEvent>;
|
||||
readonly onDidSignalReady: Event<void>;
|
||||
readonly onDidClose: Event<void>;
|
||||
readonly onDidDestroy: Event<void>;
|
||||
|
||||
readonly whenClosedOrLoaded: Promise<void>;
|
||||
|
||||
readonly id: number;
|
||||
readonly win: BrowserWindow | null; /* `null` after being disposed */
|
||||
readonly config: INativeWindowConfiguration | undefined;
|
||||
|
||||
readonly openedWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier;
|
||||
|
||||
readonly backupPath?: string;
|
||||
|
||||
readonly remoteAuthority?: string;
|
||||
|
||||
readonly isExtensionDevelopmentHost: boolean;
|
||||
readonly isExtensionTestHost: boolean;
|
||||
|
||||
readonly lastFocusTime: number;
|
||||
|
||||
readonly isReady: boolean;
|
||||
ready(): Promise<ICodeWindow>;
|
||||
setReady(): void;
|
||||
|
||||
readonly hasHiddenTitleBarStyle: boolean;
|
||||
|
||||
addTabbedWindow(window: ICodeWindow): void;
|
||||
|
||||
load(config: INativeWindowConfiguration, options?: { isReload?: boolean }): void;
|
||||
reload(cli?: NativeParsedArgs): void;
|
||||
|
||||
focus(options?: { force: boolean }): void;
|
||||
close(): void;
|
||||
|
||||
getBounds(): Rectangle;
|
||||
|
||||
send(channel: string, ...args: any[]): void;
|
||||
sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void;
|
||||
|
||||
readonly isFullScreen: boolean;
|
||||
toggleFullScreen(): void;
|
||||
|
||||
isMinimized(): boolean;
|
||||
|
||||
setRepresentedFilename(name: string): void;
|
||||
getRepresentedFilename(): string | undefined;
|
||||
|
||||
setDocumentEdited(edited: boolean): void;
|
||||
isDocumentEdited(): boolean;
|
||||
|
||||
handleTitleDoubleClick(): void;
|
||||
|
||||
updateTouchBar(items: ISerializableCommandAction[][]): void;
|
||||
|
||||
serializeWindowState(): IWindowState;
|
||||
}
|
||||
|
||||
export const enum WindowError {
|
||||
|
||||
/**
|
||||
* Maps to the `unresponsive` event on a `BrowserWindow`.
|
||||
*/
|
||||
UNRESPONSIVE = 1,
|
||||
|
||||
/**
|
||||
* Maps to the `render-proces-gone` event on a `WebContents`.
|
||||
*/
|
||||
CRASHED = 2,
|
||||
|
||||
/**
|
||||
* Maps to the `did-fail-load` event on a `WebContents`.
|
||||
*/
|
||||
LOAD = 3
|
||||
}
|
||||
import { ICodeWindow } from 'vs/platform/window/electron-main/window';
|
||||
import { IOpenEmptyWindowOptions, IWindowOpenable } from 'vs/platform/window/common/window';
|
||||
|
||||
export const IWindowsMainService = createDecorator<IWindowsMainService>('windowsMainService');
|
||||
|
||||
export interface IWindowsCountChangedEvent {
|
||||
readonly oldCount: number;
|
||||
readonly newCount: number;
|
||||
}
|
||||
|
||||
export interface IWindowsMainService {
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
@@ -220,6 +42,32 @@ export interface IWindowsMainService {
|
||||
getWindowByWebContents(webContents: WebContents): ICodeWindow | undefined;
|
||||
}
|
||||
|
||||
export interface IWindowsCountChangedEvent {
|
||||
readonly oldCount: number;
|
||||
readonly newCount: number;
|
||||
}
|
||||
|
||||
export const enum OpenContext {
|
||||
|
||||
// opening when running from the command line
|
||||
CLI,
|
||||
|
||||
// macOS only: opening from the dock (also when opening files to a running instance from desktop)
|
||||
DOCK,
|
||||
|
||||
// opening from the main application window
|
||||
MENU,
|
||||
|
||||
// opening from a file or folder dialog
|
||||
DIALOG,
|
||||
|
||||
// opening from the OS's UI
|
||||
DESKTOP,
|
||||
|
||||
// opening through the API
|
||||
API
|
||||
}
|
||||
|
||||
export interface IBaseOpenConfiguration {
|
||||
readonly context: OpenContext;
|
||||
readonly contextWindowId?: number;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ICodeWindow } from 'vs/platform/window/electron-main/window';
|
||||
import { IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
export function findWindowOnFile(windows: ICodeWindow[], fileUri: URI, localWorkspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace | undefined): ICodeWindow | undefined {
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, BrowserWindow, MessageBoxOptions, nativeTheme, WebContents } from 'electron';
|
||||
import { app, BrowserWindow, MessageBoxOptions, WebContents } from 'electron';
|
||||
import { statSync } from 'fs';
|
||||
import { hostname, release } from 'os';
|
||||
import { coalesce, distinct, firstOrDefault } from 'vs/base/common/arrays';
|
||||
@@ -17,10 +17,9 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { basename, join, normalize, posix } from 'vs/base/common/path';
|
||||
import { getMarks, mark } from 'vs/base/common/performance';
|
||||
import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
import { IProcessEnvironment, isMacintosh, isWindows, OS } from 'vs/base/common/platform';
|
||||
import { cwd } from 'vs/base/common/process';
|
||||
import { extUriBiasedIgnorePathCase, normalizePath, originalFSPath, removeTrailingPathSeparator } from 'vs/base/common/resources';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { extUriBiasedIgnorePathCase, isEqualAuthority, normalizePath, originalFSPath, removeTrailingPathSeparator } from 'vs/base/common/resources';
|
||||
import { assertIsDefined, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -30,7 +29,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { FileType, IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
@@ -39,15 +38,19 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protocol';
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { IStateMainService } from 'vs/platform/state/electron-main/state';
|
||||
import { IAddFoldersRequest, INativeOpenFileRequest, INativeWindowConfiguration, IOpenEmptyWindowOptions, IPath, IPathsToWaitFor, isFileToOpen, isFolderToOpen, isWorkspaceToOpen, IWindowOpenable, IWindowSettings } from 'vs/platform/windows/common/windows';
|
||||
import { IAddFoldersRequest, INativeOpenFileRequest, INativeWindowConfiguration, IOpenEmptyWindowOptions, IPath, IPathsToWaitFor, isFileToOpen, isFolderToOpen, isWorkspaceToOpen, IWindowOpenable, IWindowSettings } from 'vs/platform/window/common/window';
|
||||
import { CodeWindow } from 'vs/platform/windows/electron-main/window';
|
||||
import { ICodeWindow, IOpenConfiguration, IOpenEmptyConfiguration, IWindowsCountChangedEvent, IWindowsMainService, OpenContext, UnloadReason } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IOpenConfiguration, IOpenEmptyConfiguration, IWindowsCountChangedEvent, IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows';
|
||||
import { findWindowOnExtensionDevelopmentPath, findWindowOnFile, findWindowOnWorkspaceOrFolder } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { IWindowState, WindowsStateHandler } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { hasWorkspaceFileExtension, IRecent, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IRecent } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { hasWorkspaceFileExtension, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
import { getSingleFolderWorkspaceIdentifier, getWorkspaceIdentifier } from 'vs/platform/workspaces/electron-main/workspaces';
|
||||
import { IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
|
||||
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
|
||||
import { ICodeWindow, UnloadReason } from 'vs/platform/window/electron-main/window';
|
||||
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
|
||||
import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
|
||||
//#region Helper Interfaces
|
||||
|
||||
@@ -116,23 +119,33 @@ interface IFilesToOpen {
|
||||
filesToWait?: IPathsToWaitFor;
|
||||
}
|
||||
|
||||
interface IPathToOpen extends IPath {
|
||||
interface IPathToOpen<T = IEditorOptions> extends IPath<T> {
|
||||
|
||||
// the workspace to open
|
||||
/**
|
||||
* The workspace to open
|
||||
*/
|
||||
readonly workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier;
|
||||
|
||||
// whether the path is considered to be transient or not
|
||||
// for example, a transient workspace should not add to
|
||||
// the workspaces history and should never restore
|
||||
/**
|
||||
* Whether the path is considered to be transient or not
|
||||
* for example, a transient workspace should not add to
|
||||
* the workspaces history and should never restore.
|
||||
*/
|
||||
readonly transient?: boolean;
|
||||
|
||||
// the backup path to use
|
||||
/**
|
||||
* The backup path to use
|
||||
*/
|
||||
readonly backupPath?: string;
|
||||
|
||||
// the remote authority for the Code instance to open. Undefined if not remote.
|
||||
/**
|
||||
* The remote authority for the Code instance to open. Undefined if not remote.
|
||||
*/
|
||||
readonly remoteAuthority?: string;
|
||||
|
||||
// optional label for the recent history
|
||||
/**
|
||||
* Optional label for the recent history
|
||||
*/
|
||||
label?: string;
|
||||
}
|
||||
|
||||
@@ -189,7 +202,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
@IDialogMainService private readonly dialogMainService: IDialogMainService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IProtocolMainService private readonly protocolMainService: IProtocolMainService
|
||||
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
|
||||
@IThemeMainService private readonly themeMainService: IThemeMainService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -210,13 +224,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
// Allow access to extension development path
|
||||
if (window.config.extensionDevelopmentPath) {
|
||||
for (const extensionDevelopmentPath of window.config.extensionDevelopmentPath) {
|
||||
disposables.add(this.protocolMainService.addValidFileRoot(URI.file(extensionDevelopmentPath)));
|
||||
disposables.add(this.protocolMainService.addValidFileRoot(extensionDevelopmentPath));
|
||||
}
|
||||
}
|
||||
|
||||
// Allow access to extension tests path
|
||||
if (window.config.extensionTestsPath) {
|
||||
disposables.add(this.protocolMainService.addValidFileRoot(URI.file(window.config.extensionTestsPath)));
|
||||
disposables.add(this.protocolMainService.addValidFileRoot(window.config.extensionTestsPath));
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -413,7 +427,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
emptyToOpen: number,
|
||||
filesToOpen: IFilesToOpen | undefined,
|
||||
foldersToAdd: ISingleFolderWorkspacePathToOpen[]
|
||||
): { windows: ICodeWindow[], filesOpenedInWindow: ICodeWindow | undefined } {
|
||||
): { windows: ICodeWindow[]; filesOpenedInWindow: ICodeWindow | undefined } {
|
||||
|
||||
// Keep track of used windows and remember
|
||||
// if files have been opened in one of them
|
||||
@@ -571,16 +585,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
const remoteAuthority = emptyWindowBackupInfo.remoteAuthority;
|
||||
const filesToOpenInWindow = isEqualAuthority(filesToOpen?.remoteAuthority, remoteAuthority) ? filesToOpen : undefined;
|
||||
|
||||
addUsedWindow(this.openInBrowserWindow({
|
||||
userEnv: openConfig.userEnv,
|
||||
cli: openConfig.cli,
|
||||
initialStartup: openConfig.initialStartup,
|
||||
filesToOpen: filesToOpenInWindow,
|
||||
remoteAuthority,
|
||||
forceNewWindow: true,
|
||||
forceNewTabbedWindow: openConfig.forceNewTabbedWindow,
|
||||
emptyWindowBackupInfo
|
||||
}), !!filesToOpenInWindow);
|
||||
addUsedWindow(this.doOpenEmpty(openConfig, true, remoteAuthority, filesToOpenInWindow, emptyWindowBackupInfo), !!filesToOpenInWindow);
|
||||
|
||||
openFolderInNewWindow = true; // any other folders to open must open in new window then
|
||||
});
|
||||
@@ -606,7 +611,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
}
|
||||
|
||||
private doOpenFilesInExistingWindow(configuration: IOpenConfiguration, window: ICodeWindow, filesToOpen?: IFilesToOpen): ICodeWindow {
|
||||
this.logService.trace('windowsManager#doOpenFilesInExistingWindow');
|
||||
this.logService.trace('windowsManager#doOpenFilesInExistingWindow', { filesToOpen });
|
||||
|
||||
window.focus(); // make sure window has focus
|
||||
|
||||
@@ -622,7 +627,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
}
|
||||
|
||||
private doAddFoldersToExistingWindow(window: ICodeWindow, foldersToAdd: URI[]): ICodeWindow {
|
||||
this.logService.trace('windowsManager#doAddFoldersToExistingWindow');
|
||||
this.logService.trace('windowsManager#doAddFoldersToExistingWindow', { foldersToAdd });
|
||||
|
||||
window.focus(); // make sure window has focus
|
||||
|
||||
@@ -632,8 +637,11 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return window;
|
||||
}
|
||||
|
||||
private doOpenEmpty(openConfig: IOpenConfiguration, forceNewWindow: boolean, remoteAuthority: string | undefined, filesToOpen: IFilesToOpen | undefined, windowToUse?: ICodeWindow): ICodeWindow {
|
||||
if (!forceNewWindow && !windowToUse && typeof openConfig.contextWindowId === 'number') {
|
||||
private doOpenEmpty(openConfig: IOpenConfiguration, forceNewWindow: boolean, remoteAuthority: string | undefined, filesToOpen: IFilesToOpen | undefined, emptyWindowBackupInfo?: IEmptyWindowBackupInfo): ICodeWindow {
|
||||
this.logService.trace('windowsManager#doOpenEmpty', { restore: !!emptyWindowBackupInfo, remoteAuthority, filesToOpen, forceNewWindow });
|
||||
|
||||
let windowToUse: ICodeWindow | undefined;
|
||||
if (!forceNewWindow && typeof openConfig.contextWindowId === 'number') {
|
||||
windowToUse = this.getWindowById(openConfig.contextWindowId); // fix for https://github.com/microsoft/vscode/issues/97172
|
||||
}
|
||||
|
||||
@@ -645,11 +653,14 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
forceNewWindow,
|
||||
forceNewTabbedWindow: openConfig.forceNewTabbedWindow,
|
||||
filesToOpen,
|
||||
windowToUse
|
||||
windowToUse,
|
||||
emptyWindowBackupInfo
|
||||
});
|
||||
}
|
||||
|
||||
private doOpenFolderOrWorkspace(openConfig: IOpenConfiguration, folderOrWorkspace: IWorkspacePathToOpen | ISingleFolderWorkspacePathToOpen, forceNewWindow: boolean, filesToOpen: IFilesToOpen | undefined, windowToUse?: ICodeWindow): ICodeWindow {
|
||||
this.logService.trace('windowsManager#doOpenFolderOrWorkspace', { folderOrWorkspace, filesToOpen });
|
||||
|
||||
if (!forceNewWindow && !windowToUse && typeof openConfig.contextWindowId === 'number') {
|
||||
windowToUse = this.getWindowById(openConfig.contextWindowId); // fix for https://github.com/microsoft/vscode/issues/49587
|
||||
}
|
||||
@@ -756,8 +767,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
defaultId: 0,
|
||||
message: uri.scheme === Schemas.file ? localize('pathNotExistTitle', "Path does not exist") : localize('uriInvalidTitle', "URI can not be opened"),
|
||||
detail: uri.scheme === Schemas.file ?
|
||||
localize('pathNotExistDetail', "The path '{0}' does not exist on this computer.", getPathLabel(uri.fsPath, this.environmentMainService)) :
|
||||
localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString()),
|
||||
localize('pathNotExistDetail', "The path '{0}' does not exist on this computer.", getPathLabel(uri, { os: OS, tildify: this.environmentMainService })) :
|
||||
localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString(true)),
|
||||
noLink: true
|
||||
};
|
||||
|
||||
@@ -843,7 +854,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
case 'one':
|
||||
case 'all':
|
||||
case 'preserve':
|
||||
case 'folders':
|
||||
case 'folders': {
|
||||
|
||||
// Collect previously opened windows
|
||||
const lastSessionWindows: IWindowState[] = [];
|
||||
@@ -880,6 +891,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
}
|
||||
|
||||
return pathsToOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,7 +927,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return this.doResolveRemoteOpenable(openable, options);
|
||||
}
|
||||
|
||||
private doResolveRemoteOpenable(openable: IWindowOpenable, options: IPathResolveOptions): IPathToOpen | undefined {
|
||||
private doResolveRemoteOpenable(openable: IWindowOpenable, options: IPathResolveOptions): IPathToOpen<ITextEditorOptions> | undefined {
|
||||
let uri = this.resourceFromOpenable(openable);
|
||||
|
||||
// use remote authority from vscode
|
||||
@@ -931,7 +943,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
return {
|
||||
fileUri: uri.with({ path }),
|
||||
selection: line ? { startLineNumber: line, startColumn: column || 1 } : undefined,
|
||||
options: {
|
||||
selection: line ? { startLineNumber: line, startColumn: column || 1 } : undefined
|
||||
},
|
||||
remoteAuthority
|
||||
};
|
||||
}
|
||||
@@ -960,7 +974,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return openable.fileUri;
|
||||
}
|
||||
|
||||
private doResolveFilePath(path: string, options: IPathResolveOptions): IPathToOpen | undefined {
|
||||
private doResolveFilePath(path: string, options: IPathResolveOptions): IPathToOpen<ITextEditorOptions> | undefined {
|
||||
|
||||
// Extract line/col information from path
|
||||
let lineNumber: number | undefined;
|
||||
@@ -989,14 +1003,23 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { workspace: { id: workspace.id, configPath: workspace.configPath }, remoteAuthority: workspace.remoteAuthority, exists: true, transient: workspace.transient };
|
||||
return {
|
||||
workspace: { id: workspace.id, configPath: workspace.configPath },
|
||||
type: FileType.File,
|
||||
exists: true,
|
||||
remoteAuthority: workspace.remoteAuthority,
|
||||
transient: workspace.transient
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
fileUri: URI.file(path),
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
exists: true
|
||||
type: FileType.File,
|
||||
exists: true,
|
||||
options: {
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1004,6 +1027,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
else if (pathStat.isDirectory()) {
|
||||
return {
|
||||
workspace: getSingleFolderWorkspaceIdentifier(URI.file(path), pathStat),
|
||||
type: FileType.Directory,
|
||||
exists: true
|
||||
};
|
||||
}
|
||||
@@ -1015,6 +1039,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
else if (!isWindows && path === '/dev/null') {
|
||||
return {
|
||||
fileUri: URI.file(path),
|
||||
type: FileType.File,
|
||||
exists: true
|
||||
};
|
||||
}
|
||||
@@ -1028,6 +1053,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (options.ignoreFileNotFound) {
|
||||
return {
|
||||
fileUri,
|
||||
type: FileType.File,
|
||||
exists: false
|
||||
};
|
||||
}
|
||||
@@ -1036,7 +1062,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private doResolvePathRemote(path: string, options: IPathResolveOptions): IPathToOpen | undefined {
|
||||
private doResolvePathRemote(path: string, options: IPathResolveOptions): IPathToOpen<ITextEditorOptions> | undefined {
|
||||
const first = path.charCodeAt(0);
|
||||
const remoteAuthority = options.remoteAuthority;
|
||||
|
||||
@@ -1070,7 +1096,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (options.forceOpenWorkspaceAsFile) {
|
||||
return {
|
||||
fileUri: uri,
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
options: {
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined
|
||||
},
|
||||
remoteAuthority: options.remoteAuthority
|
||||
};
|
||||
}
|
||||
@@ -1082,7 +1110,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
else if (options.gotoLineMode || posix.basename(path).indexOf('.') !== -1) {
|
||||
return {
|
||||
fileUri: uri,
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
options: {
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined
|
||||
},
|
||||
remoteAuthority
|
||||
};
|
||||
}
|
||||
@@ -1091,7 +1121,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return { workspace: getSingleFolderWorkspaceIdentifier(uri), remoteAuthority };
|
||||
}
|
||||
|
||||
private shouldOpenNewWindow(openConfig: IOpenConfiguration): { openFolderInNewWindow: boolean; openFilesInNewWindow: boolean; } {
|
||||
private shouldOpenNewWindow(openConfig: IOpenConfiguration): { openFolderInNewWindow: boolean; openFilesInNewWindow: boolean } {
|
||||
|
||||
// let the user settings override how folders are open in a new window or same window unless we are forced
|
||||
const windowConfig = this.configurationService.getValue<IWindowSettings | undefined>('window');
|
||||
@@ -1178,7 +1208,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
const extensionDevelopmentPathRemoteAuthority = getRemoteAuthority(url);
|
||||
if (extensionDevelopmentPathRemoteAuthority) {
|
||||
if (remoteAuthority) {
|
||||
if (extensionDevelopmentPathRemoteAuthority !== remoteAuthority) {
|
||||
if (!isEqualAuthority(extensionDevelopmentPathRemoteAuthority, remoteAuthority)) {
|
||||
this.logService.error('more than one extension development path authority');
|
||||
}
|
||||
} else {
|
||||
@@ -1198,7 +1228,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return false;
|
||||
}
|
||||
|
||||
return getRemoteAuthority(uri) === remoteAuthority;
|
||||
return isEqualAuthority(getRemoteAuthority(uri), remoteAuthority);
|
||||
});
|
||||
|
||||
folderUris = folderUris.filter(folderUriStr => {
|
||||
@@ -1207,7 +1237,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return false;
|
||||
}
|
||||
|
||||
return folderUri ? getRemoteAuthority(folderUri) === remoteAuthority : false;
|
||||
return folderUri ? isEqualAuthority(getRemoteAuthority(folderUri), remoteAuthority) : false;
|
||||
});
|
||||
|
||||
fileUris = fileUris.filter(fileUriStr => {
|
||||
@@ -1216,7 +1246,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileUri ? getRemoteAuthority(fileUri) === remoteAuthority : false;
|
||||
return fileUri ? isEqualAuthority(getRemoteAuthority(fileUri), remoteAuthority) : false;
|
||||
});
|
||||
|
||||
openConfig.cli._ = cliArgs;
|
||||
@@ -1287,14 +1317,10 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
os: { release: release(), hostname: hostname() },
|
||||
zoomLevel: typeof windowConfig?.zoomLevel === 'number' ? windowConfig.zoomLevel : undefined,
|
||||
|
||||
legacyWatcher: this.configurationService.getValue('files.legacyWatcher'),
|
||||
experimentalSandboxedFileService: this.configurationService.getValue('files.experimentalSandboxedFileService'),
|
||||
autoDetectHighContrast: windowConfig?.autoDetectHighContrast ?? true,
|
||||
autoDetectColorScheme: windowConfig?.autoDetectColorScheme ?? false,
|
||||
accessibilitySupport: app.accessibilitySupportEnabled,
|
||||
colorScheme: {
|
||||
dark: nativeTheme.shouldUseDarkColors,
|
||||
highContrast: nativeTheme.shouldUseInvertedColorScheme || nativeTheme.shouldUseHighContrastColors
|
||||
}
|
||||
colorScheme: this.themeMainService.getColorScheme()
|
||||
};
|
||||
|
||||
let window: ICodeWindow | undefined;
|
||||
@@ -1311,7 +1337,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
// Create the window
|
||||
mark('code/willCreateCodeWindow');
|
||||
const createdWindow = window = this.instantiationService.createInstance(<any>CodeWindow, { // {{SQL CARBON EDIT}} Fix weird compile error...
|
||||
const createdWindow = window = this.instantiationService.createInstance(CodeWindow, {
|
||||
state,
|
||||
extensionDevelopmentPath: configuration.extensionDevelopmentPath,
|
||||
isExtensionTestHost: !!configuration.extensionTestsPath
|
||||
@@ -1392,7 +1418,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (isWorkspaceIdentifier(configuration.workspace)) {
|
||||
configuration.backupPath = this.backupMainService.registerWorkspaceBackupSync({ workspace: configuration.workspace, remoteAuthority: configuration.remoteAuthority });
|
||||
} else if (isSingleFolderWorkspaceIdentifier(configuration.workspace)) {
|
||||
configuration.backupPath = this.backupMainService.registerFolderBackupSync(configuration.workspace.uri);
|
||||
configuration.backupPath = this.backupMainService.registerFolderBackupSync({ folderUri: configuration.workspace.uri, remoteAuthority: configuration.remoteAuthority });
|
||||
} else {
|
||||
const backupFolder = options.emptyWindowBackupInfo && options.emptyWindowBackupInfo.backupFolder;
|
||||
configuration.backupPath = this.backupMainService.registerEmptyWindowBackupSync(backupFolder, configuration.remoteAuthority);
|
||||
@@ -1477,7 +1503,3 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return this.getWindowById(browserWindow.id);
|
||||
}
|
||||
}
|
||||
|
||||
function isEqualAuthority(a1: string | undefined, a2: string | undefined) {
|
||||
return a1 === a2 || (a1 !== undefined && a2 !== undefined && equalsIgnoreCase(a1, a2));
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IStateMainService } from 'vs/platform/state/electron-main/state';
|
||||
import { INativeWindowConfiguration, IWindowSettings } from 'vs/platform/windows/common/windows';
|
||||
import { defaultWindowState, ICodeWindow, IWindowsMainService, IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { INativeWindowConfiguration, IWindowSettings } from 'vs/platform/window/common/window';
|
||||
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||
import { defaultWindowState, ICodeWindow, IWindowState as IWindowUIState, WindowMode } from 'vs/platform/window/electron-main/window';
|
||||
import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
export interface IWindowState {
|
||||
workspace?: IWorkspaceIdentifier;
|
||||
|
||||
@@ -1,29 +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 { getZoomLevel, setZoomFactor, setZoomLevel } from 'vs/base/browser/browser';
|
||||
import { webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
|
||||
|
||||
/**
|
||||
* Apply a zoom level to the window. Also sets it in our in-memory
|
||||
* browser helper so that it can be accessed in non-electron layers.
|
||||
*/
|
||||
export function applyZoom(zoomLevel: number): void {
|
||||
webFrame.setZoomLevel(zoomLevel);
|
||||
setZoomFactor(zoomLevelToZoomFactor(zoomLevel));
|
||||
// Cannot be trusted because the webFrame might take some time
|
||||
// until it really applies the new zoom level
|
||||
// See https://github.com/microsoft/vscode/issues/26151
|
||||
setZoomLevel(zoomLevel, false /* isTrusted */);
|
||||
}
|
||||
|
||||
export function zoomIn(): void {
|
||||
applyZoom(getZoomLevel() + 1);
|
||||
}
|
||||
|
||||
export function zoomOut(): void {
|
||||
applyZoom(getZoomLevel() - 1);
|
||||
}
|
||||
@@ -15,9 +15,9 @@ export class ActiveWindowManager extends Disposable {
|
||||
private activeWindowId: number | undefined;
|
||||
|
||||
constructor({ onDidOpenWindow, onDidFocusWindow, getActiveWindowId }: {
|
||||
onDidOpenWindow: Event<number>,
|
||||
onDidFocusWindow: Event<number>,
|
||||
getActiveWindowId(): Promise<number | undefined>
|
||||
onDidOpenWindow: Event<number>;
|
||||
onDidFocusWindow: Event<number>;
|
||||
getActiveWindowId(): Promise<number | undefined>;
|
||||
}) {
|
||||
super();
|
||||
|
||||
|
||||
@@ -11,12 +11,13 @@ import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { UriDto } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
|
||||
import { ICommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandAction } from 'vs/platform/action/common/action';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
import { ICodeWindow, ILoadEvent, IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { INativeWindowConfiguration } from 'vs/platform/window/common/window';
|
||||
import { ICodeWindow, ILoadEvent, IWindowState } from 'vs/platform/window/electron-main/window';
|
||||
import { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
suite('WindowsFinder', () => {
|
||||
|
||||
@@ -30,7 +31,7 @@ suite('WindowsFinder', () => {
|
||||
const testWorkspaceFolders = toWorkspaceFolders([{ path: join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase);
|
||||
const localWorkspaceResolver = (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : undefined; };
|
||||
|
||||
function createTestCodeWindow(options: { lastFocusTime: number, openedFolderUri?: URI, openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
|
||||
function createTestCodeWindow(options: { lastFocusTime: number; openedFolderUri?: URI; openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
|
||||
return new class implements ICodeWindow {
|
||||
onWillLoad: Event<ILoadEvent> = Event.None;
|
||||
onDidSignalReady: Event<void> = Event.None;
|
||||
@@ -55,7 +56,7 @@ suite('WindowsFinder', () => {
|
||||
addTabbedWindow(window: ICodeWindow): void { throw new Error('Method not implemented.'); }
|
||||
load(config: INativeWindowConfiguration, options: { isReload?: boolean }): void { throw new Error('Method not implemented.'); }
|
||||
reload(cli?: NativeParsedArgs): void { throw new Error('Method not implemented.'); }
|
||||
focus(options?: { force: boolean; }): void { throw new Error('Method not implemented.'); }
|
||||
focus(options?: { force: boolean }): void { throw new Error('Method not implemented.'); }
|
||||
close(): void { throw new Error('Method not implemented.'); }
|
||||
getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); }
|
||||
send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); }
|
||||
|
||||
@@ -7,9 +7,9 @@ import * as assert from 'assert';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/window/electron-main/window';
|
||||
import { getWindowsStateStoreData, IWindowsState, IWindowState, restoreWindowsState } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
suite('Windows State Storing', () => {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user