mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 01:25:37 -05:00
Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6
This commit is contained in:
committed by
Anthony Dresser
parent
39d9eed585
commit
a63578e6f7
@@ -17,6 +17,9 @@
|
||||
<!-- Builtin Extensions (running out of sources) -->
|
||||
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
|
||||
|
||||
<!-- Workbench Credentials (running out of sources) -->
|
||||
<meta id="vscode-workbench-credentials" data-settings="{{WORKBENCH_CREDENTIALS}}">
|
||||
|
||||
<!-- Workarounds/Hacks (remote user data uri) -->
|
||||
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, ICommand, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -16,6 +15,7 @@ import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/wi
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { isStandalone } from 'vs/base/browser/browser';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
interface ICredential {
|
||||
service: string;
|
||||
@@ -27,6 +27,13 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
||||
|
||||
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
|
||||
|
||||
constructor(credentials: ICredential[]) {
|
||||
this._credentials = credentials;
|
||||
for (const { service, account, password } of this._credentials) {
|
||||
this.setPassword(service, account, password);
|
||||
}
|
||||
}
|
||||
|
||||
private _credentials: ICredential[] | undefined;
|
||||
private get credentials(): ICredential[] {
|
||||
if (!this._credentials) {
|
||||
@@ -277,6 +284,20 @@ class WorkspaceProvider implements IWorkspaceProvider {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hasRemote(): boolean {
|
||||
if (this.workspace) {
|
||||
if (isFolderToOpen(this.workspace)) {
|
||||
return this.workspace.folderUri.scheme === Schemas.vscodeRemote;
|
||||
}
|
||||
|
||||
if (isWorkspaceToOpen(this.workspace)) {
|
||||
return this.workspace.workspaceUri.scheme === Schemas.vscodeRemote;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class WindowIndicator implements IWindowIndicator {
|
||||
@@ -287,8 +308,6 @@ class WindowIndicator implements IWindowIndicator {
|
||||
readonly tooltip: string;
|
||||
readonly command: string | undefined;
|
||||
|
||||
readonly commandImpl: ICommand | undefined = undefined;
|
||||
|
||||
constructor(workspace: IWorkspace) {
|
||||
let repositoryOwner: string | undefined = undefined;
|
||||
let repositoryName: string | undefined = undefined;
|
||||
@@ -306,20 +325,16 @@ class WindowIndicator implements IWindowIndicator {
|
||||
}
|
||||
}
|
||||
|
||||
// Repo
|
||||
if (repositoryName && repositoryOwner) {
|
||||
this.label = localize('openInDesktopLabel', "$(remote) Open in Desktop");
|
||||
this.tooltip = localize('openInDesktopTooltip', "Open in Desktop");
|
||||
this.command = '_web.openInDesktop';
|
||||
this.commandImpl = {
|
||||
id: this.command,
|
||||
handler: () => {
|
||||
const protocol = product.quality === 'stable' ? 'vscode' : 'vscode-insiders';
|
||||
window.open(`${protocol}://vscode.git/clone?url=${encodeURIComponent(`https://github.com/${repositoryOwner}/${repositoryName}.git`)}`);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
this.label = localize('playgroundLabel', "Web Playground");
|
||||
this.tooltip = this.label;
|
||||
this.label = localize('playgroundLabelRepository', "$(remote) VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
|
||||
this.tooltip = localize('playgroundRepositoryTooltip', "VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
|
||||
}
|
||||
|
||||
// No Repo
|
||||
else {
|
||||
this.label = localize('playgroundLabel', "$(remote) VS Code Web Playground");
|
||||
this.tooltip = localize('playgroundTooltip', "VS Code Web Playground");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,6 +406,9 @@ class WindowIndicator implements IWindowIndicator {
|
||||
}
|
||||
}
|
||||
|
||||
// Workspace Provider
|
||||
const workspaceProvider = new WorkspaceProvider(workspace, payload);
|
||||
|
||||
// Home Indicator
|
||||
const homeIndicator: IHomeIndicator = {
|
||||
href: 'https://github.com/Microsoft/vscode',
|
||||
@@ -398,13 +416,10 @@ class WindowIndicator implements IWindowIndicator {
|
||||
title: localize('home', "Home")
|
||||
};
|
||||
|
||||
// Commands
|
||||
const commands: ICommand[] = [];
|
||||
|
||||
// Window indicator
|
||||
const windowIndicator = new WindowIndicator(workspace);
|
||||
if (windowIndicator.commandImpl) {
|
||||
commands.push(windowIndicator.commandImpl);
|
||||
// Window indicator (unless connected to a remote)
|
||||
let windowIndicator: WindowIndicator | undefined = undefined;
|
||||
if (!workspaceProvider.hasRemote()) {
|
||||
windowIndicator = new WindowIndicator(workspace);
|
||||
}
|
||||
|
||||
// Product Quality Change Handler
|
||||
@@ -422,15 +437,19 @@ class WindowIndicator implements IWindowIndicator {
|
||||
window.location.href = `${window.location.origin}?${queryString}`;
|
||||
};
|
||||
|
||||
// Find credentials from DOM
|
||||
const credentialsElement = document.getElementById('vscode-workbench-credentials');
|
||||
const credentialsElementAttribute = credentialsElement ? credentialsElement.getAttribute('data-settings') : undefined;
|
||||
const credentialsProvider = new LocalStorageCredentialsProvider(credentialsElementAttribute ? JSON.parse(credentialsElementAttribute) : []);
|
||||
|
||||
// Finally create workbench
|
||||
create(document.body, {
|
||||
...config,
|
||||
homeIndicator,
|
||||
commands,
|
||||
windowIndicator,
|
||||
productQualityChangeHandler,
|
||||
workspaceProvider: new WorkspaceProvider(workspace, payload),
|
||||
workspaceProvider,
|
||||
urlCallbackProvider: new PollingURLCallbackProvider(),
|
||||
credentialsProvider: new LocalStorageCredentialsProvider()
|
||||
credentialsProvider
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -33,8 +33,8 @@ const bootstrapWindow = (() => {
|
||||
return window.MonacoBootstrapWindow;
|
||||
})();
|
||||
|
||||
// Setup shell environment
|
||||
process['lazyEnv'] = getLazyEnv();
|
||||
// Load environment in parallel to workbench loading to avoid waterfall
|
||||
const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved;
|
||||
|
||||
// Load workbench main JS, CSS and NLS all in parallel. This is an
|
||||
// optimization to prevent a waterfall of loading to happen, because
|
||||
@@ -46,18 +46,19 @@ bootstrapWindow.load([
|
||||
'vs/nls!vs/workbench/workbench.desktop.main',
|
||||
'vs/css!vs/workbench/workbench.desktop.main'
|
||||
],
|
||||
function (workbench, configuration) {
|
||||
async function (workbench, configuration) {
|
||||
|
||||
// Mark start of workbench
|
||||
perf.mark('didLoadWorkbenchMain');
|
||||
performance.mark('workbench-start');
|
||||
|
||||
return process['lazyEnv'].then(function () {
|
||||
perf.mark('main/startup');
|
||||
// Wait for process environment being fully resolved
|
||||
await whenEnvResolved;
|
||||
|
||||
// @ts-ignore
|
||||
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
|
||||
});
|
||||
perf.mark('main/startup');
|
||||
|
||||
// @ts-ignore
|
||||
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
|
||||
},
|
||||
{
|
||||
removeDeveloperKeybindingsAfterLoad: true,
|
||||
@@ -77,7 +78,7 @@ bootstrapWindow.load([
|
||||
* @param {{
|
||||
* partsSplashPath?: string,
|
||||
* highContrast?: boolean,
|
||||
* defaultThemeType?: string,
|
||||
* autoDetectHighContrast?: boolean,
|
||||
* extensionDevelopmentPath?: string[],
|
||||
* folderUri?: object,
|
||||
* workspace?: object
|
||||
@@ -96,7 +97,8 @@ function showPartsSplash(configuration) {
|
||||
}
|
||||
|
||||
// high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts
|
||||
if (data && configuration.highContrast && data.baseTheme !== 'hc-black') {
|
||||
const isHighContrast = configuration.highContrast && configuration.autoDetectHighContrast;
|
||||
if (data && isHighContrast && data.baseTheme !== 'hc-black') {
|
||||
data = undefined;
|
||||
}
|
||||
|
||||
@@ -111,14 +113,10 @@ function showPartsSplash(configuration) {
|
||||
baseTheme = data.baseTheme;
|
||||
shellBackground = data.colorInfo.editorBackground;
|
||||
shellForeground = data.colorInfo.foreground;
|
||||
} else if (configuration.highContrast || configuration.defaultThemeType === 'hc') {
|
||||
} else if (isHighContrast) {
|
||||
baseTheme = 'hc-black';
|
||||
shellBackground = '#000000';
|
||||
shellForeground = '#FFFFFF';
|
||||
} else if (configuration.defaultThemeType === 'vs') {
|
||||
baseTheme = 'vs';
|
||||
shellBackground = '#FFFFFF';
|
||||
shellForeground = '#000000';
|
||||
} else {
|
||||
baseTheme = 'vs-dark';
|
||||
shellBackground = '#1E1E1E';
|
||||
@@ -172,26 +170,3 @@ function showPartsSplash(configuration) {
|
||||
|
||||
perf.mark('didShowPartsSplash');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function getLazyEnv() {
|
||||
const ipcRenderer = bootstrapWindow.globals().ipcRenderer;
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
const handle = setTimeout(function () {
|
||||
resolve();
|
||||
console.warn('renderer did not receive lazyEnv in time');
|
||||
}, 10000);
|
||||
|
||||
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
|
||||
clearTimeout(handle);
|
||||
Object.assign(process.env, shellEnv);
|
||||
// @ts-ignore
|
||||
resolve(process.env);
|
||||
});
|
||||
|
||||
ipcRenderer.send('vscode:fetchShellEnv');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/err
|
||||
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
||||
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { RunOnceScheduler, timeout } from 'vs/base/common/async';
|
||||
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
|
||||
import { homedir } from 'os';
|
||||
import { join, sep, posix } from 'vs/base/common/path';
|
||||
@@ -68,11 +68,11 @@ import { statSync } from 'fs';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
|
||||
import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc';
|
||||
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
|
||||
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
|
||||
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
|
||||
@@ -80,8 +80,6 @@ import { INativeEnvironmentService } from 'vs/platform/environment/node/environm
|
||||
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
|
||||
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
|
||||
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
|
||||
import { createServer, AddressInfo } from 'net';
|
||||
import { IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { stripComments } from 'vs/base/common/json';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -272,6 +270,12 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
try {
|
||||
const shellEnv = await getShellEnvironment(this.logService, this.environmentService);
|
||||
|
||||
// TODO@sandbox workaround for https://github.com/electron/electron/issues/25119
|
||||
if (this.environmentService.sandbox) {
|
||||
await timeout(100);
|
||||
}
|
||||
|
||||
if (!webContents.isDestroyed()) {
|
||||
webContents.send('vscode:acceptShellEnv', shellEnv);
|
||||
}
|
||||
@@ -297,7 +301,7 @@ export class CodeApplication extends Disposable {
|
||||
const nativeKeymap = await import('native-keymap');
|
||||
nativeKeymap.onDidChangeKeyboardLayout(() => {
|
||||
if (this.windowsMainService) {
|
||||
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged', false);
|
||||
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged');
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -364,17 +368,17 @@ export class CodeApplication extends Disposable {
|
||||
const sharedProcess = this.instantiationService.createInstance(SharedProcess, machineId, this.userEnv);
|
||||
const sharedProcessClient = sharedProcess.whenIpcReady().then(() => {
|
||||
this.logService.trace('Shared process: IPC ready');
|
||||
|
||||
return connect(this.environmentService.sharedIPCHandle, 'main');
|
||||
});
|
||||
const sharedProcessReady = sharedProcess.whenReady().then(() => {
|
||||
this.logService.trace('Shared process: init ready');
|
||||
|
||||
return sharedProcessClient;
|
||||
});
|
||||
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => {
|
||||
this._register(new RunOnceScheduler(async () => {
|
||||
const userEnv = await getShellEnvironment(this.logService, this.environmentService);
|
||||
|
||||
sharedProcess.spawn(userEnv);
|
||||
sharedProcess.spawn(await getShellEnvironment(this.logService, this.environmentService));
|
||||
}, 3000)).schedule();
|
||||
});
|
||||
|
||||
@@ -847,6 +851,9 @@ export class CodeApplication extends Disposable {
|
||||
} catch (error) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
||||
// Start to fetch shell environment after window has opened
|
||||
getShellEnvironment(this.logService, this.environmentService);
|
||||
}
|
||||
|
||||
private handleRemoteAuthorities(): void {
|
||||
@@ -858,100 +865,3 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHostDebugBroadcastChannel<TContext> {
|
||||
|
||||
constructor(private windowsMainService: IWindowsMainService) {
|
||||
super();
|
||||
}
|
||||
|
||||
call(ctx: TContext, command: string, arg?: any): Promise<any> {
|
||||
if (command === 'openExtensionDevelopmentHostWindow') {
|
||||
return this.openExtensionDevelopmentHostWindow(arg[0], arg[1], arg[2]);
|
||||
} else {
|
||||
return super.call(ctx, command, arg);
|
||||
}
|
||||
}
|
||||
|
||||
private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise<IOpenExtensionWindowResult> {
|
||||
const pargs = parseArgs(args, OPTIONS);
|
||||
const extDevPaths = pargs.extensionDevelopmentPath;
|
||||
if (!extDevPaths) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const [codeWindow] = this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
|
||||
context: OpenContext.API,
|
||||
cli: pargs,
|
||||
userEnv: Object.keys(env).length > 0 ? env : undefined
|
||||
});
|
||||
|
||||
if (!debugRenderer) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const debug = codeWindow.win.webContents.debugger;
|
||||
|
||||
let listeners = debug.isAttached() ? Infinity : 0;
|
||||
const server = createServer(listener => {
|
||||
if (listeners++ === 0) {
|
||||
debug.attach();
|
||||
}
|
||||
|
||||
let closed = false;
|
||||
const writeMessage = (message: object) => {
|
||||
if (!closed) { // in case sendCommand promises settle after closed
|
||||
listener.write(JSON.stringify(message) + '\0'); // null-delimited, CDP-compatible
|
||||
}
|
||||
};
|
||||
|
||||
const onMessage = (_event: Event, method: string, params: unknown, sessionId?: string) =>
|
||||
writeMessage(({ method, params, sessionId }));
|
||||
|
||||
codeWindow.win.on('close', () => {
|
||||
debug.removeListener('message', onMessage);
|
||||
listener.end();
|
||||
closed = true;
|
||||
});
|
||||
|
||||
debug.addListener('message', onMessage);
|
||||
|
||||
let buf = Buffer.alloc(0);
|
||||
listener.on('data', data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
for (let delimiter = buf.indexOf(0); delimiter !== -1; delimiter = buf.indexOf(0)) {
|
||||
let data: { id: number; sessionId: string; params: {} };
|
||||
try {
|
||||
const contents = buf.slice(0, delimiter).toString('utf8');
|
||||
buf = buf.slice(delimiter + 1);
|
||||
data = JSON.parse(contents);
|
||||
} catch (e) {
|
||||
console.error('error reading cdp line', e);
|
||||
}
|
||||
|
||||
// depends on a new API for which electron.d.ts has not been updated:
|
||||
// @ts-ignore
|
||||
debug.sendCommand(data.method, data.params, data.sessionId)
|
||||
.then((result: object) => writeMessage({ id: data.id, sessionId: data.sessionId, result }))
|
||||
.catch((error: Error) => writeMessage({ id: data.id, sessionId: data.sessionId, error: { code: 0, message: error.message } }));
|
||||
}
|
||||
});
|
||||
|
||||
listener.on('error', err => {
|
||||
console.error('error on cdp pipe:', err);
|
||||
});
|
||||
|
||||
listener.on('close', () => {
|
||||
closed = true;
|
||||
if (--listeners === 0) {
|
||||
debug.detach();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise(r => server.listen(0, r));
|
||||
codeWindow.win.on('close', () => server.close());
|
||||
|
||||
return { rendererDebugPort: (server.address() as AddressInfo).port };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
|
||||
import * as nls from 'vs/nls';
|
||||
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, nativeTheme, Event } from 'electron';
|
||||
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event, Details } from 'electron';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
@@ -167,12 +167,23 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
title: product.nameLong,
|
||||
webPreferences: {
|
||||
preload: URI.parse(this.doGetPreloadUrl()).fsPath,
|
||||
nodeIntegration: true,
|
||||
enableWebSQL: false,
|
||||
enableRemoteModule: false,
|
||||
nativeWindowOpen: true,
|
||||
webviewTag: true,
|
||||
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel)
|
||||
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel),
|
||||
...this.environmentService.sandbox ?
|
||||
|
||||
// Sandbox
|
||||
{
|
||||
sandbox: true,
|
||||
contextIsolation: true
|
||||
} :
|
||||
|
||||
// No Sandbox
|
||||
{
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -325,7 +336,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
return !!this.documentEdited;
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
focus(options?: { force: boolean }): void {
|
||||
// macOS: Electron >6.x changed its behaviour to not
|
||||
// bring the application to the foreground when a window
|
||||
// is focused programmatically. Only via `app.focus` and
|
||||
// the option `steal: true` can you get the previous
|
||||
// behaviour back. The only reason to use this option is
|
||||
// when a window is getting focused while the application
|
||||
// is not in the foreground.
|
||||
if (isMacintosh && options?.force) {
|
||||
app.focus({ steal: true });
|
||||
}
|
||||
|
||||
if (!this._win) {
|
||||
return;
|
||||
}
|
||||
@@ -392,7 +414,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
private registerListeners(): void {
|
||||
|
||||
// Crashes & Unrsponsive
|
||||
this._win.webContents.on('crashed', () => this.onWindowError(WindowError.CRASHED));
|
||||
this._win.webContents.on('render-process-gone', (event, details) => this.onWindowError(WindowError.CRASHED, details));
|
||||
this._win.on('unresponsive', () => this.onWindowError(WindowError.UNRESPONSIVE));
|
||||
|
||||
// Window close
|
||||
@@ -524,8 +546,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) })));
|
||||
}
|
||||
|
||||
private onWindowError(error: WindowError): void {
|
||||
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: renderer process crashed!' : '[VS Code]: detected unresponsive');
|
||||
private onWindowError(error: WindowError.UNRESPONSIVE): void;
|
||||
private onWindowError(error: WindowError.CRASHED, details: Details): void;
|
||||
private onWindowError(error: WindowError, details?: Details): void {
|
||||
this.logService.error(error === WindowError.CRASHED ? `[VS Code]: renderer process crashed (detail: ${details?.reason})` : '[VS Code]: detected unresponsive');
|
||||
|
||||
// If we run extension tests from CLI, showing a dialog is not
|
||||
// very helpful in this case. Rather, we bring down the test run
|
||||
@@ -579,11 +603,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
// Crashed
|
||||
else {
|
||||
let message: string;
|
||||
if (details && details.reason !== 'crashed') {
|
||||
message = nls.localize('appCrashedDetails', "The window has crashed (reason: '{0}')", details?.reason);
|
||||
} else {
|
||||
message = nls.localize('appCrashed', "The window has crashed", details?.reason);
|
||||
}
|
||||
|
||||
this.dialogMainService.showMessageBox({
|
||||
title: product.nameLong,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(nls.localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(nls.localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message: nls.localize('appCrashed', "The window has crashed"),
|
||||
message,
|
||||
detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
|
||||
noLink: true
|
||||
}, this._win).then(result => {
|
||||
@@ -699,7 +730,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
this.showTimeoutHandle = setTimeout(() => {
|
||||
if (this._win && !this._win.isVisible() && !this._win.isMinimized()) {
|
||||
this._win.show();
|
||||
this._win.focus();
|
||||
this.focus({ force: true });
|
||||
this._win.webContents.openDevTools();
|
||||
}
|
||||
}, 10000);
|
||||
@@ -754,11 +785,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
windowConfiguration.fullscreen = this.isFullScreen;
|
||||
|
||||
// Set Accessibility Config
|
||||
let autoDetectHighContrast = true;
|
||||
if (windowConfig?.autoDetectHighContrast === false) {
|
||||
autoDetectHighContrast = false;
|
||||
}
|
||||
windowConfiguration.highContrast = isWindows && autoDetectHighContrast && nativeTheme.shouldUseInvertedColorScheme;
|
||||
windowConfiguration.highContrast = nativeTheme.shouldUseInvertedColorScheme || nativeTheme.shouldUseHighContrastColors;
|
||||
windowConfiguration.autoDetectHighContrast = windowConfig?.autoDetectHighContrast ?? true;
|
||||
windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled;
|
||||
|
||||
// Title style related
|
||||
@@ -799,7 +827,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
}
|
||||
|
||||
private doGetUrl(config: object): string {
|
||||
return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
|
||||
let workbench: string;
|
||||
if (this.environmentService.sandbox) {
|
||||
workbench = 'vs/code/electron-sandbox/workbench/workbench.html';
|
||||
} else {
|
||||
workbench = 'vs/code/electron-browser/workbench/workbench.html';
|
||||
}
|
||||
|
||||
return `${require.toUrl(workbench)}?config=${encodeURIComponent(JSON.stringify(config))}`;
|
||||
}
|
||||
|
||||
private doGetPreloadUrl(): string {
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is
|
||||
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { ipcRenderer, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
|
||||
import { $, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
|
||||
import { $, reset, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
|
||||
import { Button } from 'vs/base/browser/ui/button/button';
|
||||
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
|
||||
import * as collections from 'vs/base/common/collections';
|
||||
@@ -277,33 +277,25 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
private updateSettingsSearchDetails(data: ISettingsSearchIssueReporterData): void {
|
||||
const target = document.querySelector('.block-settingsSearchResults .block-info');
|
||||
const target = document.querySelector<HTMLElement>('.block-settingsSearchResults .block-info');
|
||||
if (target) {
|
||||
const details = `
|
||||
<div class='block-settingsSearchResults-details'>
|
||||
<div>Query: "${data.query}"</div>
|
||||
<div>Literal match count: ${data.filterResultCount}</div>
|
||||
</div>
|
||||
`;
|
||||
const queryDiv = $<HTMLDivElement>('div', undefined, `Query: "${data.query}"` as string);
|
||||
const countDiv = $<HTMLElement>('div', undefined, `Literal match count: ${data.filterResultCount}` as string);
|
||||
const detailsDiv = $<HTMLDivElement>('.block-settingsSearchResults-details', undefined, queryDiv, countDiv);
|
||||
|
||||
let table = `
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Extension</th>
|
||||
<th>Score</th>
|
||||
</tr>`;
|
||||
|
||||
data.actualSearchResults
|
||||
.forEach(setting => {
|
||||
table += `
|
||||
<tr>
|
||||
<td>${setting.key}</td>
|
||||
<td>${setting.extensionId}</td>
|
||||
<td>${String(setting.score).slice(0, 5)}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
target.innerHTML = `${details}<table>${table}</table>`;
|
||||
const table = $('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, 'Setting'),
|
||||
$('th', undefined, 'Extension'),
|
||||
$('th', undefined, 'Score'),
|
||||
),
|
||||
...data.actualSearchResults.map(setting => $('tr', undefined,
|
||||
$('td', undefined, setting.key),
|
||||
$('td', undefined, setting.extensionId),
|
||||
$('td', undefined, String(setting.score).slice(0, 5)),
|
||||
))
|
||||
);
|
||||
reset(target, detailsDiv, table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,9 +646,9 @@ export class IssueReporter extends Disposable {
|
||||
issueState.appendChild(issueIcon);
|
||||
issueState.appendChild(issueStateLabel);
|
||||
|
||||
item = $('div.issue', {}, issueState, link);
|
||||
item = $('div.issue', undefined, issueState, link);
|
||||
} else {
|
||||
item = $('div.issue', {}, link);
|
||||
item = $('div.issue', undefined, link);
|
||||
}
|
||||
|
||||
issues.appendChild(item);
|
||||
@@ -672,19 +664,19 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
private setUpTypes(): void {
|
||||
const makeOption = (issueType: IssueType, description: string) => `<option value="${issueType.valueOf()}">${escape(description)}</option>`;
|
||||
const makeOption = (issueType: IssueType, description: string) => $('option', { 'value': issueType.valueOf() }, escape(description));
|
||||
|
||||
const typeSelect = this.getElementById('issue-type')! as HTMLSelectElement;
|
||||
const { issueType } = this.issueReporterModel.getData();
|
||||
if (issueType === IssueType.SettingsSearchIssue) {
|
||||
typeSelect.innerHTML = makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue"));
|
||||
reset(typeSelect, makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue")));
|
||||
typeSelect.disabled = true;
|
||||
} else {
|
||||
typeSelect.innerHTML = [
|
||||
reset(typeSelect,
|
||||
makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")),
|
||||
makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request")),
|
||||
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue"))
|
||||
].join('\n');
|
||||
);
|
||||
}
|
||||
|
||||
typeSelect.value = issueType.toString();
|
||||
@@ -774,9 +766,8 @@ export class IssueReporter extends Disposable {
|
||||
} else {
|
||||
show(extensionsBlock);
|
||||
}
|
||||
|
||||
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`;
|
||||
descriptionSubtitle.innerHTML = localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
|
||||
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
|
||||
reset(descriptionSubtitle, localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
|
||||
} else if (issueType === IssueType.PerformanceIssue) {
|
||||
show(blockContainer);
|
||||
show(systemBlock);
|
||||
@@ -790,11 +781,11 @@ export class IssueReporter extends Disposable {
|
||||
show(extensionsBlock);
|
||||
}
|
||||
|
||||
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`;
|
||||
descriptionSubtitle.innerHTML = localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
|
||||
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
|
||||
reset(descriptionSubtitle, localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
|
||||
} else if (issueType === IssueType.FeatureRequest) {
|
||||
descriptionTitle.innerHTML = `${localize('description', "Description")} <span class="required-input">*</span>`;
|
||||
descriptionSubtitle.innerHTML = localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
|
||||
reset(descriptionTitle, localize('description', "Description"), $('span.required-input', undefined, '*'));
|
||||
reset(descriptionSubtitle, localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
|
||||
show(problemSource);
|
||||
|
||||
if (fileOnExtension) {
|
||||
@@ -805,8 +796,8 @@ export class IssueReporter extends Disposable {
|
||||
show(searchedExtensionsBlock);
|
||||
show(settingsSearchResultsBlock);
|
||||
|
||||
descriptionTitle.innerHTML = `${localize('expectedResults', "Expected Results")} <span class="required-input">*</span>`;
|
||||
descriptionSubtitle.innerHTML = localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
|
||||
reset(descriptionTitle, localize('expectedResults', "Expected Results"), $('span.required-input', undefined, '*'));
|
||||
reset(descriptionSubtitle, localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,42 +919,82 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
private updateSystemInfo(state: IssueReporterModelData) {
|
||||
const target = document.querySelector('.block-system .block-info');
|
||||
const target = document.querySelector<HTMLElement>('.block-system .block-info');
|
||||
|
||||
if (target) {
|
||||
const systemInfo = state.systemInfo!;
|
||||
let renderedData = `
|
||||
<table>
|
||||
<tr><td>CPUs</td><td>${systemInfo.cpus}</td></tr>
|
||||
<tr><td>GPU Status</td><td>${Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('<br>')}</td></tr>
|
||||
<tr><td>Load (avg)</td><td>${systemInfo.load}</td></tr>
|
||||
<tr><td>Memory (System)</td><td>${systemInfo.memory}</td></tr>
|
||||
<tr><td>Process Argv</td><td>${systemInfo.processArgs}</td></tr>
|
||||
<tr><td>Screen Reader</td><td>${systemInfo.screenReader}</td></tr>
|
||||
<tr><td>VM</td><td>${systemInfo.vmHint}</td></tr>
|
||||
</table>`;
|
||||
const renderedDataTable = $('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'CPUs'),
|
||||
$('td', undefined, systemInfo.cpus || ''),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'GPU Status' as string),
|
||||
$('td', undefined, Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('\n')),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Load (avg)' as string),
|
||||
$('td', undefined, systemInfo.load || ''),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Memory (System)' as string),
|
||||
$('td', undefined, systemInfo.memory),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Process Argv' as string),
|
||||
$('td', undefined, systemInfo.processArgs),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Screen Reader' as string),
|
||||
$('td', undefined, systemInfo.screenReader),
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'VM'),
|
||||
$('td', undefined, systemInfo.vmHint),
|
||||
),
|
||||
);
|
||||
reset(target, renderedDataTable);
|
||||
|
||||
systemInfo.remoteData.forEach(remote => {
|
||||
target.appendChild($<HTMLHRElement>('hr'));
|
||||
if (isRemoteDiagnosticError(remote)) {
|
||||
renderedData += `
|
||||
<hr>
|
||||
<table>
|
||||
<tr><td>Remote</td><td>${remote.hostName}</td></tr>
|
||||
<tr><td></td><td>${remote.errorMessage}</td></tr>
|
||||
</table>`;
|
||||
const remoteDataTable = $('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Remote'),
|
||||
$('td', undefined, remote.hostName)
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, ''),
|
||||
$('td', undefined, remote.errorMessage)
|
||||
)
|
||||
);
|
||||
target.appendChild(remoteDataTable);
|
||||
} else {
|
||||
renderedData += `
|
||||
<hr>
|
||||
<table>
|
||||
<tr><td>Remote</td><td>${remote.hostName}</td></tr>
|
||||
<tr><td>OS</td><td>${remote.machineInfo.os}</td></tr>
|
||||
<tr><td>CPUs</td><td>${remote.machineInfo.cpus}</td></tr>
|
||||
<tr><td>Memory (System)</td><td>${remote.machineInfo.memory}</td></tr>
|
||||
<tr><td>VM</td><td>${remote.machineInfo.vmHint}</td></tr>
|
||||
</table>`;
|
||||
const remoteDataTable = $('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Remote'),
|
||||
$('td', undefined, remote.hostName)
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'OS'),
|
||||
$('td', undefined, remote.machineInfo.os)
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'CPUs'),
|
||||
$('td', undefined, remote.machineInfo.cpus || '')
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'Memory (System)' as string),
|
||||
$('td', undefined, remote.machineInfo.memory)
|
||||
),
|
||||
$('tr', undefined,
|
||||
$('td', undefined, 'VM'),
|
||||
$('td', undefined, remote.machineInfo.vmHint)
|
||||
),
|
||||
);
|
||||
target.appendChild(remoteDataTable);
|
||||
}
|
||||
});
|
||||
|
||||
target.innerHTML = renderedData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -995,15 +1026,18 @@ export class IssueReporter extends Disposable {
|
||||
return 0;
|
||||
});
|
||||
|
||||
const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData) => {
|
||||
const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData): HTMLOptionElement => {
|
||||
const selected = selectedExtension && extension.id === selectedExtension.id;
|
||||
return `<option value="${extension.id}" ${selected ? 'selected' : ''}>${escape(extension.name)}</option>`;
|
||||
return $<HTMLOptionElement>('option', {
|
||||
'value': extension.id,
|
||||
'selected': selected || ''
|
||||
}, extension.name);
|
||||
};
|
||||
|
||||
const extensionsSelector = this.getElementById('extension-selector');
|
||||
if (extensionsSelector) {
|
||||
const { selectedExtension } = this.issueReporterModel.getData();
|
||||
extensionsSelector.innerHTML = '<option></option>' + extensionOptions.map(extension => makeOption(extension, selectedExtension)).join('\n');
|
||||
reset(extensionsSelector, $<HTMLOptionElement>('option'), ...extensionOptions.map(extension => makeOption(extension, selectedExtension)));
|
||||
|
||||
this.addEventListener('extension-selector', 'change', (e: Event) => {
|
||||
const selectedExtensionId = (<HTMLInputElement>e.target).value;
|
||||
@@ -1071,9 +1105,9 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
private updateProcessInfo(state: IssueReporterModelData) {
|
||||
const target = document.querySelector('.block-process .block-info');
|
||||
const target = document.querySelector('.block-process .block-info') as HTMLElement;
|
||||
if (target) {
|
||||
target.innerHTML = `<code>${state.processInfo}</code>`;
|
||||
reset(target, $('code', undefined, state.processInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,7 +1119,7 @@ export class IssueReporter extends Disposable {
|
||||
const target = document.querySelector<HTMLElement>('.block-extensions .block-info');
|
||||
if (target) {
|
||||
if (this.configuration.disableExtensions) {
|
||||
target.innerHTML = localize('disabledExtensions', "Extensions are disabled");
|
||||
reset(target, localize('disabledExtensions', "Extensions are disabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1097,8 +1131,7 @@ export class IssueReporter extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const table = this.getExtensionTableHtml(extensions);
|
||||
target.innerHTML = `<table>${table}</table>${themeExclusionStr}`;
|
||||
reset(target, this.getExtensionTableHtml(extensions), document.createTextNode(themeExclusionStr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,28 +1144,24 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
|
||||
const table = this.getExtensionTableHtml(extensions);
|
||||
target.innerHTML = `<table>${table}</table>`;
|
||||
target.innerText = '';
|
||||
target.appendChild(table);
|
||||
}
|
||||
}
|
||||
|
||||
private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): string {
|
||||
let table = `
|
||||
<tr>
|
||||
<th>Extension</th>
|
||||
<th>Author (truncated)</th>
|
||||
<th>Version</th>
|
||||
</tr>`;
|
||||
|
||||
table += extensions.map(extension => {
|
||||
return `
|
||||
<tr>
|
||||
<td>${extension.name}</td>
|
||||
<td>${extension.publisher.substr(0, 3)}</td>
|
||||
<td>${extension.version}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
|
||||
return table;
|
||||
private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): HTMLTableElement {
|
||||
return $('table', undefined,
|
||||
$('tr', undefined,
|
||||
$('th', undefined, 'Extension'),
|
||||
$('th', undefined, 'Author (truncated)' as string),
|
||||
$('th', undefined, 'Version'),
|
||||
),
|
||||
...extensions.map(extension => $('tr', undefined,
|
||||
$('td', undefined, extension.name),
|
||||
$('td', undefined, extension.publisher.substr(0, 3)),
|
||||
$('td', undefined, extension.version),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
private openLink(event: MouseEvent): void {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z"/></svg>
|
||||
|
Before Width: | Height: | Size: 139 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M11 10H5.344L11 4.414V10z"/></svg>
|
||||
|
Before Width: | Height: | Size: 118 B |
@@ -58,6 +58,7 @@ table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
th[scope='col'] {
|
||||
vertical-align: bottom;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
@@ -65,6 +66,7 @@ th[scope='col'] {
|
||||
border-top: 1px solid #cccccc;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: .25rem;
|
||||
vertical-align: top;
|
||||
@@ -100,7 +102,6 @@ tbody > tr:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
margin-right: 4px;
|
||||
.header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/processExplorer';
|
||||
import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
|
||||
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -16,6 +17,7 @@ import { addDisposableListener, addClass } from 'vs/base/browser/dom';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
import { MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
|
||||
|
||||
const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/;
|
||||
const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/;
|
||||
@@ -156,15 +158,15 @@ class ProcessExplorer {
|
||||
return maxProcessId;
|
||||
}
|
||||
|
||||
private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: HTMLImageElement, sectionName: string) {
|
||||
private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: CodiconLabel, sectionName: string) {
|
||||
if (shouldExpand) {
|
||||
body.classList.remove('hidden');
|
||||
this.collapsedStateCache.set(sectionName, false);
|
||||
twistie.src = './media/expanded.svg';
|
||||
twistie.text = '$(chevron-down)';
|
||||
} else {
|
||||
body.classList.add('hidden');
|
||||
this.collapsedStateCache.set(sectionName, true);
|
||||
twistie.src = './media/collapsed.svg';
|
||||
twistie.text = '$(chevron-right)';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,18 +193,27 @@ class ProcessExplorer {
|
||||
|
||||
private renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) {
|
||||
const headerRow = document.createElement('tr');
|
||||
const data = document.createElement('td');
|
||||
data.textContent = sectionName;
|
||||
data.colSpan = 4;
|
||||
headerRow.appendChild(data);
|
||||
|
||||
const twistie = document.createElement('img');
|
||||
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistie, sectionName);
|
||||
data.prepend(twistie);
|
||||
const headerData = document.createElement('td');
|
||||
headerData.colSpan = 4;
|
||||
headerRow.appendChild(headerData);
|
||||
|
||||
this.listeners.add(addDisposableListener(data, 'click', (e) => {
|
||||
const headerContainer = document.createElement('div');
|
||||
headerContainer.className = 'header';
|
||||
headerData.appendChild(headerContainer);
|
||||
|
||||
const twistieContainer = document.createElement('div');
|
||||
const twistieCodicon = new CodiconLabel(twistieContainer);
|
||||
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistieCodicon, sectionName);
|
||||
headerContainer.appendChild(twistieContainer);
|
||||
|
||||
const headerLabel = document.createElement('span');
|
||||
headerLabel.textContent = sectionName;
|
||||
headerContainer.appendChild(headerLabel);
|
||||
|
||||
this.listeners.add(addDisposableListener(headerData, 'click', (e) => {
|
||||
const isHidden = body.classList.contains('hidden');
|
||||
this.updateSectionCollapsedState(isHidden, body, twistie, sectionName);
|
||||
this.updateSectionCollapsedState(isHidden, body, twistieCodicon, sectionName);
|
||||
}));
|
||||
|
||||
container.appendChild(headerRow);
|
||||
|
||||
18
src/vs/code/electron-sandbox/workbench/workbench.html
Normal file
18
src/vs/code/electron-sandbox/workbench/workbench.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview: https://*.vscode-webview-test.com; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https: vscode-remote-resource:;">
|
||||
</head>
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Init Bootstrap Helpers -->
|
||||
<script src="../../../../bootstrap.js"></script>
|
||||
<script src="../../../../vs/loader.js"></script>
|
||||
<script src="../../../../bootstrap-window.js"></script>
|
||||
|
||||
<!-- Startup via workbench.js -->
|
||||
<script src="workbench.js"></script>
|
||||
</html>
|
||||
74
src/vs/code/electron-sandbox/workbench/workbench.js
Normal file
74
src/vs/code/electron-sandbox/workbench/workbench.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path="../../../../typings/require.d.ts" />
|
||||
|
||||
//@ts-check
|
||||
'use strict';
|
||||
|
||||
const perf = (function () {
|
||||
globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || [];
|
||||
return {
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
mark(name) {
|
||||
globalThis.MonacoPerformanceMarks.push(name, Date.now());
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
perf.mark('renderer/started');
|
||||
|
||||
/**
|
||||
* @type {{
|
||||
* load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown,
|
||||
* globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals')
|
||||
* }}
|
||||
*/
|
||||
const bootstrapWindow = (() => {
|
||||
// @ts-ignore (defined in bootstrap-window.js)
|
||||
return window.MonacoBootstrapWindow;
|
||||
})();
|
||||
|
||||
// Load environment in parallel to workbench loading to avoid waterfall
|
||||
const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved;
|
||||
|
||||
// Load workbench main JS, CSS and NLS all in parallel. This is an
|
||||
// optimization to prevent a waterfall of loading to happen, because
|
||||
// we know for a fact that workbench.desktop.sandbox.main will depend on
|
||||
// the related CSS and NLS counterparts.
|
||||
bootstrapWindow.load([
|
||||
'vs/workbench/workbench.desktop.sandbox.main',
|
||||
'vs/nls!vs/workbench/workbench.desktop.main',
|
||||
'vs/css!vs/workbench/workbench.desktop.main'
|
||||
],
|
||||
async function (workbench, configuration) {
|
||||
|
||||
// Mark start of workbench
|
||||
perf.mark('didLoadWorkbenchMain');
|
||||
performance.mark('workbench-start');
|
||||
|
||||
// Wait for process environment being fully resolved
|
||||
await whenEnvResolved;
|
||||
|
||||
perf.mark('main/startup');
|
||||
|
||||
// @ts-ignore
|
||||
return require('vs/workbench/electron-sandbox/desktop.main').main(configuration);
|
||||
},
|
||||
{
|
||||
removeDeveloperKeybindingsAfterLoad: true,
|
||||
canModifyDOM: function (windowConfig) {
|
||||
// TODO@sandbox part-splash is non-sandboxed only
|
||||
},
|
||||
beforeLoaderConfig: function (windowConfig, loaderConfig) {
|
||||
loaderConfig.recordStats = true;
|
||||
},
|
||||
beforeRequire: function () {
|
||||
perf.mark('willLoadWorkbenchMain');
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -14,7 +14,7 @@ import * as paths from 'vs/base/common/path';
|
||||
import { whenDeleted, writeFileSync } from 'vs/base/node/pfs';
|
||||
import { findFreePort, randomPort } from 'vs/base/node/ports';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { ProfilingSession, Target } from 'v8-inspect-profiler';
|
||||
import type { ProfilingSession, Target } from 'v8-inspect-profiler';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { hasStdinWithoutTty, stdinDataListener, getStdinFilePath, readFromStdin } from 'vs/platform/environment/node/stdin';
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import { localize } from 'vs/nls';
|
||||
import { raceTimeout } from 'vs/base/common/async';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as semver from 'semver-umd';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -214,6 +213,8 @@ export class Main {
|
||||
throw new Error('Invalid vsix');
|
||||
}
|
||||
|
||||
const semver = await import('semver-umd');
|
||||
|
||||
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
|
||||
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
|
||||
const newer = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier) && semver.gt(local.manifest.version, manifest.version));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as cp from 'child_process';
|
||||
import { spawn } from 'child_process';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
@@ -30,7 +30,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
|
||||
logService.trace('getUnixShellEnvironment#env', env);
|
||||
logService.trace('getUnixShellEnvironment#spawn', command);
|
||||
|
||||
const child = cp.spawn(process.env.SHELL!, ['-ilc', command], {
|
||||
const child = spawn(process.env.SHELL!, ['-ilc', command], {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'pipe', process.stderr],
|
||||
env
|
||||
@@ -82,8 +82,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
|
||||
return promise.catch(() => ({}));
|
||||
}
|
||||
|
||||
|
||||
let _shellEnv: Promise<typeof process.env>;
|
||||
let shellEnvPromise: Promise<typeof process.env> | undefined = undefined;
|
||||
|
||||
/**
|
||||
* We need to get the environment from a user's shell.
|
||||
@@ -91,21 +90,21 @@ let _shellEnv: Promise<typeof process.env>;
|
||||
* from within a shell.
|
||||
*/
|
||||
export function getShellEnvironment(logService: ILogService, environmentService: INativeEnvironmentService): Promise<typeof process.env> {
|
||||
if (_shellEnv === undefined) {
|
||||
if (!shellEnvPromise) {
|
||||
if (environmentService.args['disable-user-env-probe']) {
|
||||
logService.trace('getShellEnvironment: disable-user-env-probe set, skipping');
|
||||
_shellEnv = Promise.resolve({});
|
||||
shellEnvPromise = Promise.resolve({});
|
||||
} else if (isWindows) {
|
||||
logService.trace('getShellEnvironment: running on Windows, skipping');
|
||||
_shellEnv = Promise.resolve({});
|
||||
shellEnvPromise = Promise.resolve({});
|
||||
} else if (process.env['VSCODE_CLI'] === '1' && process.env['VSCODE_FORCE_USER_ENV'] !== '1') {
|
||||
logService.trace('getShellEnvironment: running on CLI, skipping');
|
||||
_shellEnv = Promise.resolve({});
|
||||
shellEnvPromise = Promise.resolve({});
|
||||
} else {
|
||||
logService.trace('getShellEnvironment: running on Unix');
|
||||
_shellEnv = getUnixShellEnvironment(logService);
|
||||
shellEnvPromise = getUnixShellEnvironment(logService);
|
||||
}
|
||||
}
|
||||
|
||||
return _shellEnv;
|
||||
return shellEnvPromise;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,8 @@ suite('Windows Native Helpers', () => {
|
||||
});
|
||||
|
||||
test('vscode-windows-ca-certs', async () => {
|
||||
const windowsCerts = await new Promise<any>((resolve, reject) => {
|
||||
require(['vscode-windows-ca-certs'], resolve, reject);
|
||||
});
|
||||
// @ts-ignore Windows only
|
||||
const windowsCerts = await import('vscode-windows-ca-certs');
|
||||
assert.ok(windowsCerts, 'Unable to load vscode-windows-ca-certs dependency.');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user