VS Code merge to df8fe74bd55313de0dd2303bc47a4aab0ca56b0e (#17979)

* Merge from vscode 504f934659740e9d41501cad9f162b54d7745ad9

* delete unused folders

* distro

* Bump build node version

* update chokidar

* FIx hygiene errors

* distro

* Fix extension lint issues

* Remove strict-vscode

* Add copyright header exemptions

* Bump vscode-extension-telemetry to fix webpacking issue with zone.js

* distro

* Fix failing tests (revert marked.js back to current one until we decide to update)

* Skip searchmodel test

* Fix mac build

* temp debug script loading

* Try disabling coverage

* log error too

* Revert "log error too"

This reverts commit af0183e5d4ab458fdf44b88fbfab9908d090526f.

* Revert "temp debug script loading"

This reverts commit 3d687d541c76db2c5b55626c78ae448d3c25089c.

* Add comments explaining coverage disabling

* Fix ansi_up loading issue

* Merge latest from ads

* Use newer option

* Fix compile

* add debug logging warn

* Always log stack

* log more

* undo debug

* Update to use correct base path (+cleanup)

* distro

* fix compile errors

* Remove strict-vscode

* Fix sql editors not showing

* Show db dropdown input & fix styling

* Fix more info in gallery

* Fix gallery asset requests

* Delete unused workflow

* Fix tapable resolutions for smoke test compile error

* Fix smoke compile

* Disable crash reporting

* Disable interactive

Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
Charles Gagnon
2022-01-06 09:06:56 -08:00
committed by GitHub
parent fd2736b6a6
commit 2bc6a0cd01
2099 changed files with 79520 additions and 43813 deletions

View File

@@ -3,38 +3,39 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { join } from 'vs/base/common/path';
import { localize } from 'vs/nls';
import { getMarks, mark } from 'vs/base/common/performance';
import { app, BrowserWindow, BrowserWindowConstructorOptions, Display, Event, nativeImage, NativeImage, Rectangle, screen, SegmentedControlSegment, systemPreferences, TouchBar, TouchBarSegmentedControl, WebFrameMain } from 'electron';
import { RunOnceScheduler } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, Event, WebFrameMain } from 'electron';
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
import { ILogService } from 'vs/platform/log/common/log';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
import { IProductService } from 'vs/platform/product/common/productService';
import { WindowMinimumSize, IWindowSettings, MenuBarVisibility, getTitleBarStyle, getMenuBarVisibility, zoomLevelToZoomFactor, INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { Disposable } from 'vs/base/common/lifecycle';
import { browserCodeLoadingCacheStrategy, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { FileAccess, Schemas } from 'vs/base/common/network';
import { join } from 'vs/base/common/path';
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 { 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 { 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, INativeWindowConfiguration, IWindowSettings, MenuBarVisibility, WindowMinimumSize, zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows';
import { defaultWindowState, ICodeWindow, ILoadEvent, IWindowState, LoadReason, WindowError, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/common/extensionGalleryService';
import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { IStorageMainService } from 'vs/platform/storage/electron-main/storageMainService';
import { IFileService } from 'vs/platform/files/common/files';
import { FileAccess, Schemas } from 'vs/base/common/network';
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protocol';
export interface IWindowCreationOptions {
state: IWindowState;
@@ -92,22 +93,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
//#endregion
private hiddenTitleBarStyle: boolean | undefined;
private showTimeoutHandle: NodeJS.Timeout | undefined;
private windowState: IWindowState;
private currentMenuBarVisibility: MenuBarVisibility | undefined;
private representedFilename: string | undefined;
private documentEdited: boolean | undefined;
private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[] = [];
private marketplaceHeadersPromise: Promise<object>;
private readonly touchBarGroups: TouchBarSegmentedControl[] = [];
private currentHttpProxy: string | undefined = undefined;
private currentNoProxy: string | undefined = undefined;
//#region Properties
private _id: number;
get id(): number { return this._id; }
@@ -124,13 +111,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
get remoteAuthority(): string | undefined { return this.currentConfig?.remoteAuthority; }
private pendingLoadConfig: INativeWindowConfiguration | undefined;
private currentConfig: INativeWindowConfiguration | undefined;
get config(): INativeWindowConfiguration | undefined { return this.currentConfig; }
private readonly configObjectUrl = this._register(this.protocolMainService.createIPCObjectUrl<INativeWindowConfiguration>());
private hiddenTitleBarStyle: boolean | undefined;
get hasHiddenTitleBarStyle(): boolean { return !!this.hiddenTitleBarStyle; }
get isExtensionDevelopmentHost(): boolean { return !!(this.currentConfig?.extensionDevelopmentPath); }
@@ -139,6 +123,27 @@ export class CodeWindow extends Disposable implements ICodeWindow {
get isExtensionDevelopmentTestFromCli(): boolean { return this.isExtensionDevelopmentHost && this.isExtensionTestHost && !this.currentConfig?.debugId; }
//#endregion
private readonly windowState: IWindowState;
private currentMenuBarVisibility: MenuBarVisibility | undefined;
private representedFilename: string | undefined;
private documentEdited: boolean | undefined;
private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[] = [];
private readonly touchBarGroups: TouchBarSegmentedControl[] = [];
private marketplaceHeadersPromise: Promise<object>;
private currentHttpProxy: string | undefined = undefined;
private currentNoProxy: string | undefined = undefined;
private readonly configObjectUrl = this._register(this.protocolMainService.createIPCObjectUrl<INativeWindowConfiguration>());
private pendingLoadConfig: INativeWindowConfiguration | undefined;
private wasLoaded = false;
constructor(
config: IWindowCreationOptions,
@ILogService private readonly logService: ILogService,
@@ -181,14 +186,11 @@ export class CodeWindow extends Disposable implements ICodeWindow {
title: this.productService.nameLong,
webPreferences: {
preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath,
additionalArguments: this.environmentMainService.sandbox ?
[`--vscode-window-config=${this.configObjectUrl.resource.toString()}`, '--context-isolation' /* TODO@bpasero: Use process.contextIsolateed when 13-x-y is adopted (https://github.com/electron/electron/pull/28030) */] :
[`--vscode-window-config=${this.configObjectUrl.resource.toString()}`],
v8CacheOptions: browserCodeLoadingCacheStrategy,
additionalArguments: [`--vscode-window-config=${this.configObjectUrl.resource.toString()}`],
v8CacheOptions: this.environmentMainService.useCodeCache ? 'bypassHeatCheck' : 'none',
enableWebSQL: false,
spellcheck: false,
nativeWindowOpen: true,
webviewTag: true,
zoomFactor: zoomLevelToZoomFactor(windowSettings?.zoomLevel),
...this.environmentMainService.sandbox ?
@@ -205,12 +207,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
}
};
if (browserCodeLoadingCacheStrategy) {
this.logService.info(`window: using vscode-file:// protocol and V8 cache options: ${browserCodeLoadingCacheStrategy}`);
} else {
this.logService.info(`window: vscode-file:// protocol is explicitly disabled`);
}
// Apply icon to window
// Linux: always
// Windows: only when running out of sources, otherwise an icon is set by us on the executable
@@ -563,18 +559,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.logService.error('CodeWindow: detected unresponsive');
break;
case WindowError.LOAD:
this.logService.error(`CodeWindow: failed to load workbench window (reason: ${details?.reason || '<unknown>'}, code: ${details?.exitCode || '<unknown>'})`);
this.logService.error(`CodeWindow: failed to load (reason: ${details?.reason || '<unknown>'}, code: ${details?.exitCode || '<unknown>'})`);
break;
}
// If we run extension tests from CLI, showing a dialog is not
// very helpful in this case. Rather, we bring down the test run
// to signal back a failing run.
if (this.isExtensionDevelopmentTestFromCli) {
this.lifecycleMainService.kill(1);
return;
}
// Telemetry
type WindowErrorClassification = {
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
@@ -588,67 +576,92 @@ export class CodeWindow extends Disposable implements ICodeWindow {
};
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type, reason: details?.reason, code: details?.exitCode });
// Unresponsive
if (type === WindowError.UNRESPONSIVE) {
if (this.isExtensionDevelopmentHost || this.isExtensionTestHost || (this._win && this._win.webContents && this._win.webContents.isDevToolsOpened())) {
// TODO@electron Workaround for https://github.com/microsoft/vscode/issues/56994
// In certain cases the window can report unresponsiveness because a breakpoint was hit
// and the process is stopped executing. The most typical cases are:
// - devtools are opened and debugging happens
// - window is an extensions development host that is being debugged
// - window is an extension test development host that is being debugged
return;
}
// Inform User if non-recoverable
switch (type) {
case WindowError.UNRESPONSIVE:
case WindowError.CRASHED:
// Show Dialog
const result = await this.dialogMainService.showMessageBox({
title: this.productService.nameLong,
type: 'warning',
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'wait', comment: ['&& denotes a mnemonic'] }, "&&Keep Waiting")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
message: localize('appStalled', "The window is no longer responding"),
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
noLink: true
}, this._win);
// If we run extension tests from CLI, showing a dialog is not
// very helpful in this case. Rather, we bring down the test run
// to signal back a failing run.
if (this.isExtensionDevelopmentTestFromCli) {
this.lifecycleMainService.kill(1);
return;
}
if (!this._win) {
return; // Return early if the window has been going down already
}
// Unresponsive
if (type === WindowError.UNRESPONSIVE) {
if (this.isExtensionDevelopmentHost || this.isExtensionTestHost || (this._win && this._win.webContents && this._win.webContents.isDevToolsOpened())) {
// TODO@electron Workaround for https://github.com/microsoft/vscode/issues/56994
// In certain cases the window can report unresponsiveness because a breakpoint was hit
// and the process is stopped executing. The most typical cases are:
// - devtools are opened and debugging happens
// - window is an extensions development host that is being debugged
// - window is an extension test development host that is being debugged
return;
}
if (result.response === 0) {
this._win.webContents.forcefullyCrashRenderer(); // Calling reload() immediately after calling this method will force the reload to occur in a new process
this.reload();
} else if (result.response === 2) {
this.destroyWindow();
}
}
// Show Dialog
const result = await this.dialogMainService.showMessageBox({
title: this.productService.nameLong,
type: 'warning',
buttons: [
mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")),
mnemonicButtonLabel(localize({ key: 'wait', comment: ['&& denotes a mnemonic'] }, "&&Keep Waiting")),
mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))
],
message: localize('appStalled', "The window is not responding"),
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
noLink: true,
defaultId: 0,
cancelId: 1
}, this._win);
// Crashed
else if (type === WindowError.CRASHED) {
let message: string;
if (!details) {
message = localize('appCrashed', "The window has crashed");
} else {
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}', code: '{1}')", details.reason, details.exitCode ?? '<unknown>');
}
if (!this._win) {
return; // Return early if the window has been going down already
}
const result = await this.dialogMainService.showMessageBox({
title: this.productService.nameLong,
type: 'warning',
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
message,
detail: localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
noLink: true
}, this._win);
if (result.response === 0) {
this._win.webContents.forcefullyCrashRenderer(); // Calling reload() immediately after calling this method will force the reload to occur in a new process
this.reload();
} else if (result.response === 2) {
this.destroyWindow();
}
}
if (!this._win) {
return; // Return early if the window has been going down already
}
// Crashed
else if (type === WindowError.CRASHED) {
let message: string;
if (!details) {
message = localize('appCrashed', "The window has crashed");
} else {
message = localize('appCrashedDetails', "The window has crashed (reason: '{0}', code: '{1}')", details.reason, details.exitCode ?? '<unknown>');
}
if (result.response === 0) {
this.reload();
} else if (result.response === 1) {
this.destroyWindow();
}
const result = await this.dialogMainService.showMessageBox({
title: this.productService.nameLong,
type: 'warning',
buttons: [
mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")),
mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))
],
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
}, this._win);
if (!this._win) {
return; // Return early if the window has been going down already
}
if (result.response === 0) {
this.reload();
} else if (result.response === 1) {
this.destroyWindow();
}
}
break;
}
}
@@ -745,20 +758,25 @@ export class CodeWindow extends Disposable implements ICodeWindow {
'vs/code/electron-browser/workbench/workbench.html', require
).toString(true));
// Remember that we did load
const wasLoaded = this.wasLoaded;
this.wasLoaded = true;
// Make window visible if it did not open in N seconds because this indicates an error
// Only do this when running out of sources and not when running tests
if (!this.environmentMainService.isBuilt && !this.environmentMainService.extensionTestsLocationURI) {
this.showTimeoutHandle = setTimeout(() => {
this._register(new RunOnceScheduler(() => {
if (this._win && !this._win.isVisible() && !this._win.isMinimized()) {
this._win.show();
this.focus({ force: true });
this._win.webContents.openDevTools();
}
}, 10000);
}, 10000)).schedule();
}
// Event
this._onWillLoad.fire({ workspace: configuration.workspace });
this._onWillLoad.fire({ workspace: configuration.workspace, reason: options.isReload ? LoadReason.RELOAD : wasLoaded ? LoadReason.LOAD : LoadReason.INITIAL });
}
private updateConfiguration(configuration: INativeWindowConfiguration, options: ILoadOptions): void {
@@ -768,9 +786,16 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// preserve that user environment in subsequent loads,
// unless the new configuration context was also a CLI
// (for https://github.com/microsoft/vscode/issues/108571)
// 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;
if (currentUserEnv && isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(configuration.userEnv)) {
configuration.userEnv = { ...currentUserEnv, ...configuration.userEnv }; // still allow to override certain environment as passed in
if (currentUserEnv) {
const shouldPreserveLaunchCliEnvironment = isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(configuration.userEnv);
const shouldPreserveDebugEnvironmnet = this.isExtensionDevelopmentHost;
if (shouldPreserveLaunchCliEnvironment || shouldPreserveDebugEnvironmnet) {
configuration.userEnv = { ...currentUserEnv, ...configuration.userEnv }; // still allow to override certain environment as passed in
}
}
// If named pipe was instantiated for the crashpad_handler process, reuse the same
@@ -807,7 +832,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
const configuration = Object.assign({}, this.currentConfig);
// Validate workspace
configuration.workspace = await this.validateWorkspace(configuration);
configuration.workspace = await this.validateWorkspaceBeforeReload(configuration);
// Delete some properties we do not want during reload
delete configuration.filesToOpenOrCreate;
@@ -830,7 +855,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.load(configuration, { isReload: true, disableExtensions: cli?.['disable-extensions'] });
}
private async validateWorkspace(configuration: INativeWindowConfiguration): Promise<IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined> {
private async validateWorkspaceBeforeReload(configuration: INativeWindowConfiguration): Promise<IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined> {
// Multi folder
if (isWorkspaceIdentifier(configuration.workspace)) {
@@ -1350,10 +1375,6 @@ export class CodeWindow extends Disposable implements ICodeWindow {
override dispose(): void {
super.dispose();
if (this.showTimeoutHandle) {
clearTimeout(this.showTimeoutHandle);
}
this._win = null!; // Important to dereference the window object to allow for GC
}
}