mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-13 11:38:36 -05:00
Merge from vscode 817eb6b0c720a4ecbc13c020afbbebfed667aa09 (#7356)
This commit is contained in:
@@ -13,12 +13,12 @@ import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter, shell, MessageBoxReturnValue, MessageBoxOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, Display } from 'electron';
|
||||
import { parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMainPhase } 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, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, IEnterWorkspaceResult, IMessageBoxResult, INewWindowOptions, IURIToOpen, isFileToOpen, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, IPathsToWaitFor, IEnterWorkspaceResult, IURIToOpen, isFileToOpen, isWorkspaceToOpen, isFolderToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderUri } from 'vs/code/node/windowsFinder';
|
||||
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
@@ -197,9 +197,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
const windowsStateStoreData = this.stateService.getItem<WindowsStateStorageData>(WindowsManager.windowsStateStorageKey);
|
||||
|
||||
this.windowsState = restoreWindowsState(windowsStateStoreData);
|
||||
this.windowsState = restoreWindowsState(this.stateService.getItem<WindowsStateStorageData>(WindowsManager.windowsStateStorageKey));
|
||||
if (!Array.isArray(this.windowsState.openedWindows)) {
|
||||
this.windowsState.openedWindows = [];
|
||||
}
|
||||
@@ -227,7 +226,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
private registerListeners(): void {
|
||||
|
||||
// React to workbench ready events from windows
|
||||
ipc.on('vscode:workbenchReady', (event: Electron.Event, windowId: number) => {
|
||||
ipc.on('vscode:workbenchReady', (event: Event, windowId: number) => {
|
||||
this.logService.trace('IPC#vscode-workbenchReady');
|
||||
|
||||
const win = this.getWindowById(windowId);
|
||||
@@ -381,6 +380,12 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
};
|
||||
}
|
||||
|
||||
async openExternal(url: string): Promise<boolean> {
|
||||
shell.openExternal(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
open(openConfig: IOpenConfiguration): ICodeWindow[] {
|
||||
this.logService.trace('windowsManager#open');
|
||||
openConfig = this.validateOpenConfig(openConfig);
|
||||
@@ -867,7 +872,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
message = localize('uriInvalidTitle', "URI can not be opened");
|
||||
detail = localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString());
|
||||
}
|
||||
const options: Electron.MessageBoxOptions = {
|
||||
const options: MessageBoxOptions = {
|
||||
title: product.nameLong,
|
||||
type: 'info',
|
||||
buttons: [localize('ok', "OK")],
|
||||
@@ -1468,7 +1473,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
//
|
||||
|
||||
// We want the new window to open on the same display that the last active one is in
|
||||
let displayToUse: Electron.Display | undefined;
|
||||
let displayToUse: Display | undefined;
|
||||
const displays = screen.getAllDisplays();
|
||||
|
||||
// Single Display
|
||||
@@ -1605,13 +1610,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
return getLastActiveWindow(WindowsManager.WINDOWS.filter(window => window.remoteAuthority === remoteAuthority));
|
||||
}
|
||||
|
||||
openNewWindow(context: OpenContext, options?: INewWindowOptions): ICodeWindow[] {
|
||||
openEmptyWindow(context: OpenContext, options?: { reuse?: boolean, remoteAuthority?: string }): ICodeWindow[] {
|
||||
let cli = this.environmentService.args;
|
||||
const remote = options && options.remoteAuthority || undefined;
|
||||
const remote = options && options.remoteAuthority;
|
||||
if (cli && (cli.remote !== remote)) {
|
||||
cli = { ...cli, remote };
|
||||
}
|
||||
const forceReuseWindow = options && options.reuseWindow;
|
||||
const forceReuseWindow = options && options.reuse;
|
||||
const forceNewWindow = !forceReuseWindow;
|
||||
return this.open({ context, cli, forceEmpty: true, forceNewWindow, forceReuseWindow });
|
||||
}
|
||||
@@ -1665,11 +1670,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
getWindowById(windowId: number): ICodeWindow | undefined {
|
||||
const res = WindowsManager.WINDOWS.filter(window => window.id === windowId);
|
||||
if (res && res.length === 1) {
|
||||
return res[0];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return arrays.firstOrDefault(res);
|
||||
}
|
||||
|
||||
getWindows(): ICodeWindow[] {
|
||||
@@ -1714,9 +1715,9 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result.button === 0) {
|
||||
if (result.response === 0) {
|
||||
window.reload();
|
||||
} else if (result.button === 2) {
|
||||
} else if (result.response === 2) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it is unresponsive
|
||||
}
|
||||
@@ -1737,9 +1738,9 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result.button === 0) {
|
||||
if (result.response === 0) {
|
||||
window.reload();
|
||||
} else if (result.button === 1) {
|
||||
} else if (result.response === 1) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it has crashed
|
||||
}
|
||||
@@ -1761,7 +1762,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
this._onWindowClose.fire(win.id);
|
||||
}
|
||||
|
||||
async pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
|
||||
async pickFileFolderAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('open', "Open");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFolders: true, pickFiles: true, title });
|
||||
if (paths) {
|
||||
@@ -1773,7 +1774,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}));
|
||||
this.open({
|
||||
context: OpenContext.DIALOG,
|
||||
contextWindowId: options.windowId,
|
||||
contextWindowId: win ? win.id : undefined,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen,
|
||||
forceNewWindow: options.forceNewWindow
|
||||
@@ -1781,14 +1782,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
async pickFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
|
||||
async pickFolderAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openFolder', "Open Folder");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFolders: true, title });
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFolder', options.telemetryExtraData);
|
||||
this.open({
|
||||
context: OpenContext.DIALOG,
|
||||
contextWindowId: options.windowId,
|
||||
contextWindowId: win ? win.id : undefined,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: paths.map(path => ({ folderUri: URI.file(path) })),
|
||||
forceNewWindow: options.forceNewWindow
|
||||
@@ -1796,14 +1797,14 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
async pickFileAndOpen(options: INativeOpenDialogOptions): Promise<void> {
|
||||
async pickFileAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openFile', "Open File");
|
||||
const paths = await this.dialogs.pick({ ...options, pickFiles: true, title });
|
||||
if (paths) {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openFile', options.telemetryExtraData);
|
||||
this.open({
|
||||
context: OpenContext.DIALOG,
|
||||
contextWindowId: options.windowId,
|
||||
contextWindowId: win ? win.id : undefined,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: paths.map(path => ({ fileUri: URI.file(path) })),
|
||||
forceNewWindow: options.forceNewWindow
|
||||
@@ -1811,7 +1812,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
async pickWorkspaceAndOpen(options: INativeOpenDialogOptions): Promise<void> {
|
||||
async pickWorkspaceAndOpen(options: INativeOpenDialogOptions, win?: ICodeWindow): Promise<void> {
|
||||
const title = localize('openWorkspaceTitle', "Open Workspace");
|
||||
const buttonLabel = mnemonicButtonLabel(localize({ key: 'openWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open"));
|
||||
const filters = WORKSPACE_FILTER;
|
||||
@@ -1820,7 +1821,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
this.sendPickerTelemetry(paths, options.telemetryEventName || 'openWorkspace', options.telemetryExtraData);
|
||||
this.open({
|
||||
context: OpenContext.DIALOG,
|
||||
contextWindowId: options.windowId,
|
||||
contextWindowId: win ? win.id : undefined,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: paths.map(path => ({ workspaceUri: URI.file(path) })),
|
||||
forceNewWindow: options.forceNewWindow
|
||||
@@ -1842,15 +1843,15 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
});
|
||||
}
|
||||
|
||||
showMessageBox(options: Electron.MessageBoxOptions, win?: ICodeWindow): Promise<IMessageBoxResult> {
|
||||
showMessageBox(options: MessageBoxOptions, win?: ICodeWindow): Promise<MessageBoxReturnValue> {
|
||||
return this.dialogs.showMessageBox(options, win);
|
||||
}
|
||||
|
||||
showSaveDialog(options: Electron.SaveDialogOptions, win?: ICodeWindow): Promise<string> {
|
||||
showSaveDialog(options: SaveDialogOptions, win?: ICodeWindow): Promise<SaveDialogReturnValue> {
|
||||
return this.dialogs.showSaveDialog(options, win);
|
||||
}
|
||||
|
||||
showOpenDialog(options: Electron.OpenDialogOptions, win?: ICodeWindow): Promise<string[]> {
|
||||
showOpenDialog(options: OpenDialogOptions, win?: ICodeWindow): Promise<OpenDialogReturnValue> {
|
||||
return this.dialogs.showOpenDialog(options, win);
|
||||
}
|
||||
|
||||
@@ -1897,10 +1898,10 @@ class Dialogs {
|
||||
this.noWindowDialogQueue = new Queue<void>();
|
||||
}
|
||||
|
||||
async pick(options: IInternalNativeOpenDialogOptions): Promise<string[] | undefined> {
|
||||
async pick(options: IInternalNativeOpenDialogOptions, win?: ICodeWindow): Promise<string[] | undefined> {
|
||||
|
||||
// Ensure dialog options
|
||||
const dialogOptions: Electron.OpenDialogOptions = {
|
||||
const dialogOptions: OpenDialogOptions = {
|
||||
title: options.title,
|
||||
buttonLabel: options.buttonLabel,
|
||||
filters: options.filters
|
||||
@@ -1928,15 +1929,15 @@ class Dialogs {
|
||||
}
|
||||
|
||||
// Show Dialog
|
||||
const focusedWindow = (typeof options.windowId === 'number' ? this.windowsMainService.getWindowById(options.windowId) : undefined) || this.windowsMainService.getFocusedWindow();
|
||||
const windowToUse = win || this.windowsMainService.getFocusedWindow();
|
||||
|
||||
const paths = await this.showOpenDialog(dialogOptions, focusedWindow);
|
||||
if (paths && paths.length > 0) {
|
||||
const result = await this.showOpenDialog(dialogOptions, windowToUse);
|
||||
if (result && result.filePaths && result.filePaths.length > 0) {
|
||||
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(paths[0]));
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(result.filePaths[0]));
|
||||
|
||||
return paths;
|
||||
return result.filePaths;
|
||||
}
|
||||
|
||||
return undefined; // {{SQL CARBON EDIT}} @anthonydresser strict-null-check
|
||||
@@ -1956,20 +1957,17 @@ class Dialogs {
|
||||
return windowDialogQueue;
|
||||
}
|
||||
|
||||
showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): Promise<IMessageBoxResult> {
|
||||
showMessageBox(options: MessageBoxOptions, window?: ICodeWindow): Promise<MessageBoxReturnValue> {
|
||||
return this.getDialogQueue(window).queue(async () => {
|
||||
let result: Electron.MessageBoxReturnValue;
|
||||
if (window) {
|
||||
result = await dialog.showMessageBox(window.win, options);
|
||||
} else {
|
||||
result = await dialog.showMessageBox(options);
|
||||
return dialog.showMessageBox(window.win, options);
|
||||
}
|
||||
|
||||
return { button: result.response, checkboxChecked: result.checkboxChecked };
|
||||
return dialog.showMessageBox(options);
|
||||
});
|
||||
}
|
||||
|
||||
showSaveDialog(options: Electron.SaveDialogOptions, window?: ICodeWindow): Promise<string> {
|
||||
showSaveDialog(options: SaveDialogOptions, window?: ICodeWindow): Promise<SaveDialogReturnValue> {
|
||||
|
||||
function normalizePath(path: string | undefined): string | undefined {
|
||||
if (path && isMacintosh) {
|
||||
@@ -1980,18 +1978,20 @@ class Dialogs {
|
||||
}
|
||||
|
||||
return this.getDialogQueue(window).queue(async () => {
|
||||
let result: Electron.SaveDialogReturnValue;
|
||||
let result: SaveDialogReturnValue;
|
||||
if (window) {
|
||||
result = await dialog.showSaveDialog(window.win, options);
|
||||
} else {
|
||||
result = await dialog.showSaveDialog(options);
|
||||
}
|
||||
|
||||
return normalizePath(result.filePath);
|
||||
result.filePath = normalizePath(result.filePath);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
showOpenDialog(options: Electron.OpenDialogOptions, window?: ICodeWindow): Promise<string[]> {
|
||||
showOpenDialog(options: OpenDialogOptions, window?: ICodeWindow): Promise<OpenDialogReturnValue> {
|
||||
|
||||
function normalizePaths(paths: string[] | undefined): string[] | undefined {
|
||||
if (paths && paths.length > 0 && isMacintosh) {
|
||||
@@ -2012,14 +2012,16 @@ class Dialogs {
|
||||
}
|
||||
|
||||
// Show dialog
|
||||
let result: Electron.OpenDialogReturnValue;
|
||||
let result: OpenDialogReturnValue;
|
||||
if (window) {
|
||||
result = await dialog.showOpenDialog(window.win, options);
|
||||
} else {
|
||||
result = await dialog.showOpenDialog(options);
|
||||
}
|
||||
|
||||
return normalizePaths(result.filePaths);
|
||||
result.filePaths = normalizePaths(result.filePaths);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2056,7 +2058,7 @@ class WorkspacesManager {
|
||||
|
||||
// Prevent overwriting a workspace that is currently opened in another window
|
||||
if (findWindowOnWorkspace(this.windowsMainService.getWindows(), getWorkspaceIdentifier(path))) {
|
||||
const options: Electron.MessageBoxOptions = {
|
||||
const options: MessageBoxOptions = {
|
||||
title: product.nameLong,
|
||||
type: 'info',
|
||||
buttons: [localize('ok', "OK")],
|
||||
|
||||
Reference in New Issue
Block a user