mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 10:58:31 -05:00
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:
@@ -3,14 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isMacintosh, isLinux, isWeb, isNative } from 'vs/base/common/platform';
|
||||
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 { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { LogLevel } from 'vs/platform/log/common/log';
|
||||
import { PerformanceMark } from 'vs/base/common/performance';
|
||||
import { ISandboxConfiguration } from 'vs/base/parts/sandbox/common/sandboxTypes';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export const WindowMinimumSize = {
|
||||
WIDTH: 400,
|
||||
@@ -19,7 +19,12 @@ export const WindowMinimumSize = {
|
||||
};
|
||||
|
||||
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)
|
||||
@@ -161,11 +166,15 @@ export interface IPathData {
|
||||
// the file path to open within the instance
|
||||
readonly fileUri?: UriComponents;
|
||||
|
||||
// the line number in the file path to open
|
||||
readonly lineNumber?: number;
|
||||
|
||||
// the column number in the file path to open
|
||||
readonly columnNumber?: number;
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,58 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWindowOpenable, IOpenEmptyWindowOptions, INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Rectangle, BrowserWindow, WebContents } from 'electron';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { BrowserWindow, Rectangle, WebContents } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
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 {
|
||||
|
||||
@@ -62,6 +103,7 @@ export const enum WindowMode {
|
||||
|
||||
export interface ILoadEvent {
|
||||
workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined;
|
||||
reason: LoadReason;
|
||||
}
|
||||
|
||||
export interface ICodeWindow extends IDisposable {
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWorkspaceIdentifier, IResolvedWorkspace, isWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
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';
|
||||
|
||||
export function findWindowOnFile(windows: ICodeWindow[], fileUri: URI, localWorkspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace | undefined): ICodeWindow | undefined {
|
||||
|
||||
|
||||
@@ -3,49 +3,50 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, BrowserWindow, MessageBoxOptions, nativeTheme, WebContents } from 'electron';
|
||||
import { statSync } from 'fs';
|
||||
import { release, hostname } from 'os';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { mark, getMarks } from 'vs/base/common/performance';
|
||||
import { basename, normalize, join, posix } from 'vs/base/common/path';
|
||||
import { localize } from 'vs/nls';
|
||||
import { hostname, release } from 'os';
|
||||
import { coalesce, distinct, firstOrDefault } from 'vs/base/common/arrays';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { isWindowsDriveLetter, parseLineAndColumnAware, sanitizeFilePath, toSlashes } from 'vs/base/common/extpath';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { getPathLabel, mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
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 } from 'vs/base/common/platform';
|
||||
import { cwd } from 'vs/base/common/process';
|
||||
import { extUriBiasedIgnorePathCase, 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';
|
||||
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
|
||||
import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IStateMainService } from 'vs/platform/state/electron-main/state';
|
||||
import { CodeWindow } from 'vs/platform/windows/electron-main/window';
|
||||
import { app, BrowserWindow, MessageBoxOptions, nativeTheme, WebContents } from 'electron';
|
||||
import { ILifecycleMainService, UnloadReason } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IWindowSettings, IPath, isFileToOpen, isWorkspaceToOpen, isFolderToOpen, IWindowOpenable, IOpenEmptyWindowOptions, IAddFoldersRequest, IPathsToWaitFor, INativeWindowConfiguration, INativeOpenFileRequest } from 'vs/platform/windows/common/windows';
|
||||
import { findWindowOnFile, findWindowOnWorkspaceOrFolder, findWindowOnExtensionDevelopmentPath } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent, ICodeWindow, IOpenEmptyConfiguration, OpenContext } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
|
||||
import { IProcessEnvironment, isMacintosh } from 'vs/base/common/platform';
|
||||
import { IWorkspaceIdentifier, hasWorkspaceFileExtension, IRecent, isWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { normalizePath, originalFSPath, removeTrailingPathSeparator, extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { IWindowState, WindowsStateHandler } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { getSingleFolderWorkspaceIdentifier, getWorkspaceIdentifier, IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
|
||||
import { assertIsDefined, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { isWindowsDriveLetter, toSlashes, parseLineAndColumnAware, sanitizeFilePath } from 'vs/base/common/extpath';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
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 { cwd } from 'vs/base/common/process';
|
||||
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';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
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 { CodeWindow } from 'vs/platform/windows/electron-main/window';
|
||||
import { ICodeWindow, IOpenConfiguration, IOpenEmptyConfiguration, IWindowsCountChangedEvent, IWindowsMainService, OpenContext, UnloadReason } 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 { 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';
|
||||
|
||||
//#region Helper Interfaces
|
||||
|
||||
@@ -71,11 +72,37 @@ interface IOpenBrowserWindowOptions {
|
||||
}
|
||||
|
||||
interface IPathResolveOptions {
|
||||
readonly ignoreFileNotFound?: boolean;
|
||||
readonly gotoLineMode?: boolean;
|
||||
readonly forceOpenWorkspaceAsFile?: boolean;
|
||||
|
||||
/**
|
||||
* The remoteAuthority to use if the URL to open is neither file nor vscode-remote
|
||||
* By default, resolving a path will check
|
||||
* if the path exists. This can be disabled
|
||||
* with this flag.
|
||||
*/
|
||||
readonly ignoreFileNotFound?: boolean;
|
||||
|
||||
/**
|
||||
* Will reject a path if it points to a transient
|
||||
* workspace as indicated by a `transient: true`
|
||||
* property in the workspace file.
|
||||
*/
|
||||
readonly rejectTransientWorkspaces?: boolean;
|
||||
|
||||
/**
|
||||
* If enabled, will resolve the path line/column
|
||||
* aware and properly remove this information
|
||||
* from the resulting file path.
|
||||
*/
|
||||
readonly gotoLineMode?: boolean;
|
||||
|
||||
/**
|
||||
* Forces to resolve the provided path as workspace
|
||||
* file instead of opening it as a file.
|
||||
*/
|
||||
readonly forceOpenWorkspaceAsFile?: boolean;
|
||||
|
||||
/**
|
||||
* The remoteAuthority to use if the URL to open is
|
||||
* neither `file` nor `vscode-remote`.
|
||||
*/
|
||||
readonly remoteAuthority?: string;
|
||||
}
|
||||
@@ -93,6 +120,11 @@ interface IPathToOpen extends IPath {
|
||||
// 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
|
||||
readonly transient?: boolean;
|
||||
|
||||
// the backup path to use
|
||||
readonly backupPath?: string;
|
||||
|
||||
@@ -208,9 +240,12 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
const foldersToAdd: ISingleFolderWorkspacePathToOpen[] = [];
|
||||
const foldersToOpen: ISingleFolderWorkspacePathToOpen[] = [];
|
||||
|
||||
const workspacesToOpen: IWorkspacePathToOpen[] = [];
|
||||
const workspacesToRestore: IWorkspacePathToOpen[] = [];
|
||||
const emptyToRestore: IEmptyWindowBackupInfo[] = [];
|
||||
const untitledWorkspacesToRestore: IWorkspacePathToOpen[] = [];
|
||||
|
||||
const emptyWindowsWithBackupsToRestore: IEmptyWindowBackupInfo[] = [];
|
||||
|
||||
let filesToOpen: IFilesToOpen | undefined;
|
||||
let emptyToOpen = 0;
|
||||
|
||||
@@ -234,7 +269,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
}
|
||||
filesToOpen.filesToOpenOrCreate.push(path);
|
||||
} else if (path.backupPath) {
|
||||
emptyToRestore.push({ backupFolder: basename(path.backupPath), remoteAuthority: path.remoteAuthority });
|
||||
emptyWindowsWithBackupsToRestore.push({ backupFolder: basename(path.backupPath), remoteAuthority: path.remoteAuthority });
|
||||
} else {
|
||||
emptyToOpen++;
|
||||
}
|
||||
@@ -256,19 +291,19 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (openConfig.initialStartup) {
|
||||
|
||||
// Untitled workspaces are always restored
|
||||
workspacesToRestore.push(...this.workspacesManagementMainService.getUntitledWorkspacesSync());
|
||||
workspacesToOpen.push(...workspacesToRestore);
|
||||
untitledWorkspacesToRestore.push(...this.workspacesManagementMainService.getUntitledWorkspacesSync());
|
||||
workspacesToOpen.push(...untitledWorkspacesToRestore);
|
||||
|
||||
// Empty windows with backups are always restored
|
||||
emptyToRestore.push(...this.backupMainService.getEmptyWindowBackupPaths());
|
||||
emptyWindowsWithBackupsToRestore.push(...this.backupMainService.getEmptyWindowBackupPaths());
|
||||
} else {
|
||||
emptyToRestore.length = 0;
|
||||
emptyWindowsWithBackupsToRestore.length = 0;
|
||||
}
|
||||
|
||||
// Open based on config
|
||||
const { windows: usedWindows, filesOpenedInWindow } = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, filesToOpen, foldersToAdd);
|
||||
const { windows: usedWindows, filesOpenedInWindow } = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyWindowsWithBackupsToRestore, emptyToOpen, filesToOpen, foldersToAdd);
|
||||
|
||||
this.logService.trace(`windowsManager#open used window count ${usedWindows.length} (workspacesToOpen: ${workspacesToOpen.length}, foldersToOpen: ${foldersToOpen.length}, emptyToRestore: ${emptyToRestore.length}, emptyToOpen: ${emptyToOpen})`);
|
||||
this.logService.trace(`windowsManager#open used window count ${usedWindows.length} (workspacesToOpen: ${workspacesToOpen.length}, foldersToOpen: ${foldersToOpen.length}, emptyToRestore: ${emptyWindowsWithBackupsToRestore.length}, emptyToOpen: ${emptyToOpen})`);
|
||||
|
||||
// Make sure to pass focus to the most relevant of the windows if we open multiple
|
||||
if (usedWindows.length > 1) {
|
||||
@@ -299,8 +334,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
for (let i = usedWindows.length - 1; i >= 0; i--) {
|
||||
const usedWindow = usedWindows[i];
|
||||
if (
|
||||
(usedWindow.openedWorkspace && workspacesToRestore.some(workspace => usedWindow.openedWorkspace && workspace.workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace
|
||||
(usedWindow.backupPath && emptyToRestore.some(empty => usedWindow.backupPath && empty.backupFolder === basename(usedWindow.backupPath))) // skip over restored empty window
|
||||
(usedWindow.openedWorkspace && untitledWorkspacesToRestore.some(workspace => usedWindow.openedWorkspace && workspace.workspace.id === usedWindow.openedWorkspace.id)) || // skip over restored workspace
|
||||
(usedWindow.backupPath && emptyWindowsWithBackupsToRestore.some(empty => usedWindow.backupPath && empty.backupFolder === basename(usedWindow.backupPath))) // skip over restored empty window
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@@ -324,7 +359,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (!usedWindows.some(window => window.isExtensionDevelopmentHost) && !isDiff && !openConfig.noRecentEntry) {
|
||||
const recents: IRecent[] = [];
|
||||
for (const pathToOpen of pathsToOpen) {
|
||||
if (isWorkspacePathToOpen(pathToOpen)) {
|
||||
if (isWorkspacePathToOpen(pathToOpen) && !pathToOpen.transient /* never add transient workspaces to history */) {
|
||||
recents.push({ label: pathToOpen.label, workspace: pathToOpen.workspace, remoteAuthority: pathToOpen.remoteAuthority });
|
||||
} else if (isSingleFolderWorkspacePathToOpen(pathToOpen)) {
|
||||
recents.push({ label: pathToOpen.label, folderUri: pathToOpen.workspace.uri, remoteAuthority: pathToOpen.remoteAuthority });
|
||||
@@ -702,10 +737,11 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
const options: MessageBoxOptions = {
|
||||
title: this.productService.nameLong,
|
||||
type: 'info',
|
||||
buttons: [localize('ok', "OK")],
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'ok', comment: ['&& denotes a mnemonic'] }, "&&OK"))],
|
||||
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 seem to exist anymore on disk.", getPathLabel(uri.fsPath, this.environmentMainService)) :
|
||||
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()),
|
||||
noLink: true
|
||||
};
|
||||
@@ -808,7 +844,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
// Workspaces
|
||||
if (lastSessionWindow.workspace) {
|
||||
const pathToOpen = this.resolveOpenable({ workspaceUri: lastSessionWindow.workspace.configPath }, { remoteAuthority: lastSessionWindow.remoteAuthority });
|
||||
const pathToOpen = this.resolveOpenable({ workspaceUri: lastSessionWindow.workspace.configPath }, { remoteAuthority: lastSessionWindow.remoteAuthority, rejectTransientWorkspaces: true /* https://github.com/microsoft/vscode/issues/119695 */ });
|
||||
if (isWorkspacePathToOpen(pathToOpen)) {
|
||||
pathsToOpen.push(pathToOpen);
|
||||
}
|
||||
@@ -848,7 +884,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
return restoreWindows;
|
||||
}
|
||||
|
||||
private resolveOpenable(openable: IWindowOpenable, options: IPathResolveOptions = {}): IPathToOpen | undefined {
|
||||
private resolveOpenable(openable: IWindowOpenable, options: IPathResolveOptions = Object.create(null)): IPathToOpen | undefined {
|
||||
|
||||
// handle file:// openables with some extra validation
|
||||
let uri = this.resourceFromOpenable(openable);
|
||||
@@ -878,7 +914,11 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (options.gotoLineMode) {
|
||||
const { path, line, column } = parseLineAndColumnAware(uri.path);
|
||||
|
||||
return { fileUri: uri.with({ path }), lineNumber: line, columnNumber: column, remoteAuthority };
|
||||
return {
|
||||
fileUri: uri.with({ path }),
|
||||
selection: line ? { startLineNumber: line, startColumn: column || 1 } : undefined,
|
||||
remoteAuthority
|
||||
};
|
||||
}
|
||||
|
||||
return { fileUri: uri, remoteAuthority };
|
||||
@@ -910,7 +950,6 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
// Extract line/col information from path
|
||||
let lineNumber: number | undefined;
|
||||
let columnNumber: number | undefined;
|
||||
|
||||
if (options.gotoLineMode) {
|
||||
({ path, line: lineNumber, column: columnNumber } = parseLineAndColumnAware(path));
|
||||
}
|
||||
@@ -926,12 +965,23 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
if (!options.forceOpenWorkspaceAsFile) {
|
||||
const workspace = this.workspacesManagementMainService.resolveLocalWorkspaceSync(URI.file(path));
|
||||
if (workspace) {
|
||||
return { workspace: { id: workspace.id, configPath: workspace.configPath }, remoteAuthority: workspace.remoteAuthority, exists: true };
|
||||
|
||||
// If the workspace is transient and we are to ignore
|
||||
// transient workspaces, reject it.
|
||||
if (workspace.transient && options.rejectTransientWorkspaces) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { workspace: { id: workspace.id, configPath: workspace.configPath }, remoteAuthority: workspace.remoteAuthority, exists: true, transient: workspace.transient };
|
||||
}
|
||||
}
|
||||
|
||||
// File
|
||||
return { fileUri: URI.file(path), lineNumber, columnNumber, exists: true };
|
||||
return {
|
||||
fileUri: URI.file(path),
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
exists: true
|
||||
};
|
||||
}
|
||||
|
||||
// Folder (we check for isDirectory() because e.g. paths like /dev/null
|
||||
@@ -987,14 +1037,23 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
// file name ends with .code-workspace
|
||||
if (hasWorkspaceFileExtension(path)) {
|
||||
if (options.forceOpenWorkspaceAsFile) {
|
||||
return { fileUri: uri, lineNumber, columnNumber, remoteAuthority: options.remoteAuthority };
|
||||
return {
|
||||
fileUri: uri,
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
remoteAuthority: options.remoteAuthority
|
||||
};
|
||||
}
|
||||
|
||||
return { workspace: getWorkspaceIdentifier(uri), remoteAuthority };
|
||||
}
|
||||
|
||||
// file name starts with a dot or has an file extension
|
||||
else if (options.gotoLineMode || posix.basename(path).indexOf('.') !== -1) {
|
||||
return { fileUri: uri, lineNumber, columnNumber, remoteAuthority };
|
||||
return {
|
||||
fileUri: uri,
|
||||
selection: lineNumber ? { startLineNumber: lineNumber, startColumn: columnNumber || 1 } : undefined,
|
||||
remoteAuthority
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* 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';
|
||||
import { setZoomFactor, setZoomLevel, getZoomLevel } from 'vs/base/browser/browser';
|
||||
|
||||
/**
|
||||
* Apply a zoom level to the window. Also sets it in our in-memory
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
|
||||
export class ActiveWindowManager extends Disposable {
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { ICodeWindow, ILoadEvent, IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { join } from 'vs/base/common/path';
|
||||
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 { 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 { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
suite('WindowsFinder', () => {
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
import * as assert from 'assert';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { restoreWindowsState, getWindowsStateStoreData, IWindowsState, IWindowState } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { getWindowsStateStoreData, IWindowsState, IWindowState, restoreWindowsState } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
suite('Windows State Storing', () => {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user