mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 09:35:39 -05:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -15,7 +15,7 @@ import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { hasArgs, asArray } from 'vs/platform/environment/node/argv';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
|
||||
import { parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleService, UnloadReason, LifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { ILifecycleService, UnloadReason, LifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, IEnterWorkspaceResult, IMessageBoxResult, INewWindowOptions, IURIToOpen, isFileToOpen, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
|
||||
@@ -38,6 +38,8 @@ import { getComparisonKey, isEqual, normalizePath, basename as resourcesBasename
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { restoreWindowsState, WindowsStateStorageData, getWindowsStateStoreData } from 'vs/code/electron-main/windowsStateStorage';
|
||||
import { getWorkspaceIdentifier } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
const enum WindowError {
|
||||
UNRESPONSIVE = 1,
|
||||
@@ -153,15 +155,13 @@ interface IWorkspacePathToOpen {
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export class WindowsManager implements IWindowsMainService {
|
||||
export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private static readonly windowsStateStorageKey = 'windowsState';
|
||||
|
||||
private static WINDOWS: ICodeWindow[] = [];
|
||||
|
||||
private initialUserEnv: IProcessEnvironment;
|
||||
private static readonly WINDOWS: ICodeWindow[] = [];
|
||||
|
||||
private readonly windowsState: IWindowsState;
|
||||
private lastClosedWindowState?: IWindowState;
|
||||
@@ -169,20 +169,21 @@ export class WindowsManager implements IWindowsMainService {
|
||||
private readonly dialogs: Dialogs;
|
||||
private readonly workspacesManager: WorkspacesManager;
|
||||
|
||||
private _onWindowReady = new Emitter<ICodeWindow>();
|
||||
onWindowReady: CommonEvent<ICodeWindow> = this._onWindowReady.event;
|
||||
private readonly _onWindowReady = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onWindowReady: CommonEvent<ICodeWindow> = this._onWindowReady.event;
|
||||
|
||||
private _onWindowClose = new Emitter<number>();
|
||||
onWindowClose: CommonEvent<number> = this._onWindowClose.event;
|
||||
private readonly _onWindowClose = this._register(new Emitter<number>());
|
||||
readonly onWindowClose: CommonEvent<number> = this._onWindowClose.event;
|
||||
|
||||
private _onWindowLoad = new Emitter<number>();
|
||||
onWindowLoad: CommonEvent<number> = this._onWindowLoad.event;
|
||||
private readonly _onWindowLoad = this._register(new Emitter<number>());
|
||||
readonly onWindowLoad: CommonEvent<number> = this._onWindowLoad.event;
|
||||
|
||||
private _onWindowsCountChanged = new Emitter<IWindowsCountChangedEvent>();
|
||||
onWindowsCountChanged: CommonEvent<IWindowsCountChangedEvent> = this._onWindowsCountChanged.event;
|
||||
private readonly _onWindowsCountChanged = this._register(new Emitter<IWindowsCountChangedEvent>());
|
||||
readonly onWindowsCountChanged: CommonEvent<IWindowsCountChangedEvent> = this._onWindowsCountChanged.event;
|
||||
|
||||
constructor(
|
||||
private readonly machineId: string,
|
||||
private readonly initialUserEnv: IProcessEnvironment,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@@ -194,6 +195,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
@IWorkspacesMainService private readonly workspacesMainService: IWorkspacesMainService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
const windowsStateStoreData = this.stateService.getItem<WindowsStateStorageData>(WindowsManager.windowsStateStorageKey);
|
||||
|
||||
this.windowsState = restoreWindowsState(windowsStateStoreData);
|
||||
@@ -203,12 +205,21 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
this.dialogs = new Dialogs(stateService, this);
|
||||
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, this);
|
||||
|
||||
this.lifecycleService.when(LifecycleMainPhase.Ready).then(() => this.registerListeners());
|
||||
this.lifecycleService.when(LifecycleMainPhase.AfterWindowOpen).then(() => this.installWindowsMutex());
|
||||
}
|
||||
|
||||
ready(initialUserEnv: IProcessEnvironment): void {
|
||||
this.initialUserEnv = initialUserEnv;
|
||||
|
||||
this.registerListeners();
|
||||
private installWindowsMutex(): void {
|
||||
if (isWindows) {
|
||||
try {
|
||||
const WindowsMutex = (require.__$__nodeRequire('windows-mutex') as typeof import('windows-mutex')).Mutex;
|
||||
const mutex = new WindowsMutex(product.win32MutexName);
|
||||
once(this.lifecycleService.onWillShutdown)(() => mutex.release());
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
@@ -543,6 +554,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
// Find suitable window or folder path to open files in
|
||||
const fileToCheck = fileInputs.filesToOpenOrCreate[0] || fileInputs.filesToDiff[0];
|
||||
|
||||
// only look at the windows with correct authority
|
||||
const windows = WindowsManager.WINDOWS.filter(w => w.remoteAuthority === fileInputs!.remoteAuthority);
|
||||
|
||||
@@ -639,7 +651,6 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
// Handle folders to open (instructed and to restore)
|
||||
const allFoldersToOpen = arrays.distinct(foldersToOpen, folder => getComparisonKey(folder.folderUri)); // prevent duplicates
|
||||
|
||||
if (allFoldersToOpen.length > 0) {
|
||||
|
||||
// Check for existing instances
|
||||
@@ -713,7 +724,9 @@ export class WindowsManager implements IWindowsMainService {
|
||||
if (fileInputs && !emptyToOpen) {
|
||||
emptyToOpen++;
|
||||
}
|
||||
|
||||
const remoteAuthority = fileInputs ? fileInputs.remoteAuthority : (openConfig.cli && openConfig.cli.remote || undefined);
|
||||
|
||||
for (let i = 0; i < emptyToOpen; i++) {
|
||||
usedWindows.push(this.openInBrowserWindow({
|
||||
userEnv: openConfig.userEnv,
|
||||
@@ -1289,7 +1302,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
// For all other cases we first call into registerEmptyWindowBackupSync() to set it before
|
||||
// loading the window.
|
||||
if (options.emptyWindowBackupInfo) {
|
||||
configuration.backupPath = join(this.environmentService.backupHome, options.emptyWindowBackupInfo.backupFolder);
|
||||
configuration.backupPath = join(this.environmentService.backupHome.fsPath, options.emptyWindowBackupInfo.backupFolder);
|
||||
}
|
||||
|
||||
let window: ICodeWindow | undefined;
|
||||
@@ -1536,14 +1549,13 @@ export class WindowsManager implements IWindowsMainService {
|
||||
return state;
|
||||
}
|
||||
|
||||
reload(win: ICodeWindow, cli?: ParsedArgs): void {
|
||||
async reload(win: ICodeWindow, cli?: ParsedArgs): Promise<void> {
|
||||
|
||||
// Only reload when the window has not vetoed this
|
||||
this.lifecycleService.unload(win, UnloadReason.RELOAD).then(veto => {
|
||||
if (!veto) {
|
||||
win.reload(undefined, cli);
|
||||
}
|
||||
});
|
||||
const veto = await this.lifecycleService.unload(win, UnloadReason.RELOAD);
|
||||
if (!veto) {
|
||||
win.reload(undefined, cli);
|
||||
}
|
||||
}
|
||||
|
||||
closeWorkspace(win: ICodeWindow): void {
|
||||
@@ -1554,8 +1566,10 @@ export class WindowsManager implements IWindowsMainService {
|
||||
});
|
||||
}
|
||||
|
||||
enterWorkspace(win: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | undefined> {
|
||||
return this.workspacesManager.enterWorkspace(win, path).then(result => result ? this.doEnterWorkspace(win, result) : undefined);
|
||||
async enterWorkspace(win: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | undefined> {
|
||||
const result = await this.workspacesManager.enterWorkspace(win, path);
|
||||
|
||||
return result ? this.doEnterWorkspace(win, result) : undefined;
|
||||
}
|
||||
|
||||
private doEnterWorkspace(win: ICodeWindow, result: IEnterWorkspaceResult): IEnterWorkspaceResult {
|
||||
@@ -1666,14 +1680,13 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
private onWindowError(window: ICodeWindow, error: WindowError): void {
|
||||
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: render process crashed!' : '[VS Code]: detected unresponsive');
|
||||
|
||||
/* __GDPR__
|
||||
"windowerror" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('windowerror', { type: error });
|
||||
|
||||
type WindowErrorClassification = {
|
||||
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
};
|
||||
type WindowErrorEvent = {
|
||||
type: WindowError;
|
||||
};
|
||||
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type: error });
|
||||
// Unresponsive
|
||||
if (error === WindowError.UNRESPONSIVE) {
|
||||
if (window.isExtensionDevelopmentHost || window.isExtensionTestHost || (window.win && window.win.webContents && window.win.webContents.isDevToolsOpened())) {
|
||||
@@ -1751,8 +1764,10 @@ export class WindowsManager implements IWindowsMainService {
|
||||
const paths = await this.dialogs.pick({ ...options, pickFolders: true, pickFiles: true, title });
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFileFolder', options.telemetryExtraData);
|
||||
const urisToOpen = await Promise.all(paths.map(path => {
|
||||
return dirExists(path).then(isDir => isDir ? { folderUri: URI.file(path) } : { fileUri: URI.file(path) });
|
||||
const urisToOpen = await Promise.all(paths.map(async path => {
|
||||
const isDir = await dirExists(path);
|
||||
|
||||
return isDir ? { folderUri: URI.file(path) } : { fileUri: URI.file(path) };
|
||||
}));
|
||||
this.open({
|
||||
context: OpenContext.DIALOG,
|
||||
@@ -1880,7 +1895,7 @@ class Dialogs {
|
||||
this.noWindowDialogQueue = new Queue<void>();
|
||||
}
|
||||
|
||||
pick(options: IInternalNativeOpenDialogOptions): Promise<string[] | undefined> {
|
||||
async pick(options: IInternalNativeOpenDialogOptions): Promise<string[] | undefined> {
|
||||
|
||||
// Ensure dialog options
|
||||
const dialogOptions: Electron.OpenDialogOptions = {
|
||||
@@ -1913,16 +1928,16 @@ class Dialogs {
|
||||
// Show Dialog
|
||||
const focusedWindow = (typeof options.windowId === 'number' ? this.windowsMainService.getWindowById(options.windowId) : undefined) || this.windowsMainService.getFocusedWindow();
|
||||
|
||||
return this.showOpenDialog(dialogOptions, focusedWindow).then(paths => {
|
||||
if (paths && paths.length > 0) {
|
||||
const paths = await this.showOpenDialog(dialogOptions, focusedWindow);
|
||||
if (paths && paths.length > 0) {
|
||||
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(paths[0]));
|
||||
return paths;
|
||||
}
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(paths[0]));
|
||||
|
||||
return undefined;
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
|
||||
return undefined; // {{SQL CARBON EDIT}} @anthonydresser strict-null-check
|
||||
}
|
||||
|
||||
private getDialogQueue(window?: ICodeWindow): Queue<any> {
|
||||
@@ -2028,28 +2043,26 @@ class WorkspacesManager {
|
||||
private readonly windowsMainService: IWindowsMainService,
|
||||
) { }
|
||||
|
||||
enterWorkspace(window: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | null> {
|
||||
async enterWorkspace(window: ICodeWindow, path: URI): Promise<IEnterWorkspaceResult | null> {
|
||||
if (!window || !window.win || !window.isReady) {
|
||||
return Promise.resolve(null); // return early if the window is not ready or disposed
|
||||
return null; // return early if the window is not ready or disposed
|
||||
}
|
||||
|
||||
return this.isValidTargetWorkspacePath(window, path).then(isValid => {
|
||||
if (!isValid) {
|
||||
return null; // return early if the workspace is not valid
|
||||
}
|
||||
const workspaceIdentifier = getWorkspaceIdentifier(path);
|
||||
return this.doOpenWorkspace(window, workspaceIdentifier);
|
||||
});
|
||||
const isValid = await this.isValidTargetWorkspacePath(window, path);
|
||||
if (!isValid) {
|
||||
return null; // return early if the workspace is not valid
|
||||
}
|
||||
|
||||
return this.doOpenWorkspace(window, getWorkspaceIdentifier(path));
|
||||
}
|
||||
|
||||
private isValidTargetWorkspacePath(window: ICodeWindow, path?: URI): Promise<boolean> {
|
||||
private async isValidTargetWorkspacePath(window: ICodeWindow, path?: URI): Promise<boolean> {
|
||||
if (!path) {
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (window.openedWorkspace && isEqual(window.openedWorkspace.configPath, path)) {
|
||||
return Promise.resolve(false); // window is already opened on a workspace with that path
|
||||
return false; // window is already opened on a workspace with that path
|
||||
}
|
||||
|
||||
// Prevent overwriting a workspace that is currently opened in another window
|
||||
@@ -2063,10 +2076,12 @@ class WorkspacesManager {
|
||||
noLink: true
|
||||
};
|
||||
|
||||
return this.windowsMainService.showMessageBox(options, this.windowsMainService.getFocusedWindow()).then(() => false);
|
||||
await this.windowsMainService.showMessageBox(options, this.windowsMainService.getFocusedWindow());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Promise.resolve(true); // OK
|
||||
return true; // OK
|
||||
}
|
||||
|
||||
private doOpenWorkspace(window: ICodeWindow, workspace: IWorkspaceIdentifier): IEnterWorkspaceResult {
|
||||
@@ -2090,14 +2105,16 @@ class WorkspacesManager {
|
||||
|
||||
return { workspace, backupPath };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function resourceFromURIToOpen(u: IURIToOpen) {
|
||||
function resourceFromURIToOpen(u: IURIToOpen): URI {
|
||||
if (isWorkspaceToOpen(u)) {
|
||||
return u.workspaceUri;
|
||||
} else if (isFolderToOpen(u)) {
|
||||
}
|
||||
|
||||
if (isFolderToOpen(u)) {
|
||||
return u.folderUri;
|
||||
}
|
||||
|
||||
return u.fileUri;
|
||||
}
|
||||
Reference in New Issue
Block a user