diff --git a/build/buildfile.js b/build/buildfile.js
index 614d5f9cdad..b1ce1186d4e 100644
--- a/build/buildfile.js
+++ b/build/buildfile.js
@@ -43,9 +43,7 @@ exports.code = [
// 'vs/code/node/cli' is not included here because it comes in via ./src/cli.js
createModuleDescription('vs/code/node/cliProcessMain'),
createModuleDescription('vs/code/electron-utility/sharedProcess/sharedProcessMain'),
- createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain'),
createModuleDescription('vs/code/electron-sandbox/workbench/workbench'),
- createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorer'),
createModuleDescription('vs/workbench/contrib/webview/browser/pre/service-worker')
];
diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js
index 7046ee004bb..65ce8db5207 100644
--- a/build/gulpfile.vscode.js
+++ b/build/gulpfile.vscode.js
@@ -96,9 +96,6 @@ const vscodeResourceIncludes = [
// Extension Host Worker
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
- // Process Explorer
- 'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.html',
-
// Tree Sitter highlights
'out-build/vs/editor/common/languages/highlights/*.scm',
@@ -142,9 +139,7 @@ const bundleVSCodeTask = task.define('bundle-vscode', task.series(
],
resources: vscodeResources,
fileContentMapper: filePath => {
- if (
- filePath.endsWith('vs/code/electron-sandbox/workbench/workbench.js') ||
- filePath.endsWith('vs/code/electron-sandbox/processExplorer/processExplorer.js')) {
+ if (filePath.endsWith('vs/code/electron-sandbox/workbench/workbench.js')) {
return async (content) => {
const bootstrapWindowContent = await fs.promises.readFile(path.join(root, 'out-build', 'bootstrap-window.js'), 'utf-8');
return `${bootstrapWindowContent}\n${content}`; // prepend bootstrap-window.js content to entry points that are Electron windows
@@ -152,9 +147,7 @@ const bundleVSCodeTask = task.define('bundle-vscode', task.series(
}
return undefined;
},
- skipTSBoilerplateRemoval: entryPoint =>
- entryPoint === 'vs/code/electron-sandbox/workbench/workbench' ||
- entryPoint === 'vs/code/electron-sandbox/processExplorer/processExplorer',
+ skipTSBoilerplateRemoval: entryPoint => entryPoint === 'vs/code/electron-sandbox/workbench/workbench'
}
}
)
diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts
index 2c6cc9b6eec..cb2d2352cdc 100644
--- a/src/vs/code/electron-main/app.ts
+++ b/src/vs/code/electron-main/app.ts
@@ -51,7 +51,6 @@ import { DiskFileSystemProvider } from '../../platform/files/node/diskFileSystem
import { SyncDescriptor } from '../../platform/instantiation/common/descriptors.js';
import { IInstantiationService, ServicesAccessor } from '../../platform/instantiation/common/instantiation.js';
import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js';
-import { IProcessMainService } from '../../platform/process/common/process.js';
import { ProcessMainService } from '../../platform/process/electron-main/processMainService.js';
import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from '../../platform/keyboardLayout/electron-main/keyboardLayoutMainService.js';
import { ILaunchMainService, LaunchMainService } from '../../platform/launch/electron-main/launchMainService.js';
@@ -1018,9 +1017,6 @@ export class CodeApplication extends Disposable {
services.set(IDiagnosticsMainService, new SyncDescriptor(DiagnosticsMainService, undefined, false /* proxied to other processes */));
services.set(IDiagnosticsService, ProxyChannel.toService(getDelayedChannel(sharedProcessReady.then(client => client.getChannel('diagnostics')))));
- // Process
- services.set(IProcessMainService, new SyncDescriptor(ProcessMainService, [this.userEnv]));
-
// Encryption
services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService));
@@ -1162,7 +1158,7 @@ export class CodeApplication extends Disposable {
mainProcessElectronServer.registerChannel('update', updateChannel);
// Process
- const processChannel = ProxyChannel.fromService(accessor.get(IProcessMainService), disposables);
+ const processChannel = ProxyChannel.fromService(new ProcessMainService(this.logService, accessor.get(IDiagnosticsService), accessor.get(IDiagnosticsMainService)), disposables);
mainProcessElectronServer.registerChannel('process', processChannel);
// Encryption
diff --git a/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css b/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css
deleted file mode 100644
index 4d915c2023b..00000000000
--- a/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css
+++ /dev/null
@@ -1,86 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-html {
- font-size: 13px;
-}
-
-/* Font Families (with CJK support) */
-
-.mac { font-family: -apple-system, BlinkMacSystemFont, sans-serif; }
-.mac:lang(zh-Hans) { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", sans-serif; }
-.mac:lang(zh-Hant) { font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", sans-serif; }
-.mac:lang(ja) { font-family: -apple-system, BlinkMacSystemFont, "Hiragino Kaku Gothic Pro", sans-serif; }
-.mac:lang(ko) { font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Nanum Gothic", "AppleGothic", sans-serif; }
-
-.windows { font-family: "Segoe WPC", "Segoe UI", sans-serif; }
-.windows:lang(zh-Hans) { font-family: "Segoe WPC", "Segoe UI", "Microsoft YaHei", sans-serif; }
-.windows:lang(zh-Hant) { font-family: "Segoe WPC", "Segoe UI", "Microsoft Jhenghei", sans-serif; }
-.windows:lang(ja) { font-family: "Segoe WPC", "Segoe UI", "Yu Gothic UI", "Meiryo UI", sans-serif; }
-.windows:lang(ko) { font-family: "Segoe WPC", "Segoe UI", "Malgun Gothic", "Dotom", sans-serif; }
-
-/* Linux: add `system-ui` as first font and not `Ubuntu` to allow other distribution pick their standard OS font */
-.linux { font-family: system-ui, "Ubuntu", "Droid Sans", sans-serif; }
-.linux:lang(zh-Hans) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; }
-.linux:lang(zh-Hant) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans", sans-serif; }
-.linux:lang(ja) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", sans-serif; }
-.linux:lang(ko) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; }
-
-body {
- margin: 0;
- padding: 0;
- height: 100%;
- width: 100%;
- user-select: none;
- color: #cccccc;
-}
-
-.cpu {
- width: 60px;
-}
-
-.pid {
- width: 50px
-}
-
-.memory {
- width: 90px;
-}
-
-.monaco-list:focus {
- outline: 0;
-}
-
-.monaco-list-row:first-of-type {
- border-bottom: 1px solid;
-}
-
-.row {
- display: flex;
-}
-
-.centered {
- text-align: center;
-}
-
-.nameLabel{
- text-align: left;
- width: calc(100% - 185px);
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.data {
- white-space: pre;
- padding-left: .5rem;
- font-weight: normal;
- text-align: left;
- height: 22px;
-}
-
-.error {
- padding-left: 20px;
- white-space: nowrap;
-}
diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html b/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html
deleted file mode 100644
index 19d194fc1c5..00000000000
--- a/src/vs/code/electron-sandbox/processExplorer/processExplorer-dev.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorer.html b/src/vs/code/electron-sandbox/processExplorer/processExplorer.html
deleted file mode 100644
index d2747202950..00000000000
--- a/src/vs/code/electron-sandbox/processExplorer/processExplorer.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorer.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorer.ts
deleted file mode 100644
index 17be24c02f0..00000000000
--- a/src/vs/code/electron-sandbox/processExplorer/processExplorer.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-/* eslint-disable no-restricted-globals */
-
-(async function () {
-
- type IBootstrapWindow = import('../../../platform/window/electron-sandbox/window.js').IBootstrapWindow;
- type IProcessExplorerMain = import('./processExplorerMain.js').IProcessExplorerMain;
- type ProcessExplorerWindowConfiguration = import('../../../platform/process/common/process.js').ProcessExplorerWindowConfiguration;
-
- const bootstrapWindow: IBootstrapWindow = (window as any).MonacoBootstrapWindow; // defined by bootstrap-window.ts
-
- const { result, configuration } = await bootstrapWindow.load('vs/code/electron-sandbox/processExplorer/processExplorerMain', {
- configureDeveloperSettings: function () {
- return {
- forceEnableDeveloperKeybindings: true
- };
- },
- });
-
- result.startup(configuration);
-}());
diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts
deleted file mode 100644
index 616165dc977..00000000000
--- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts
+++ /dev/null
@@ -1,606 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import './media/processExplorer.css';
-import '../../../base/browser/ui/codicons/codiconStyles.js'; // make sure codicon css is loaded
-import { localize } from '../../../nls.js';
-import { $, append } from '../../../base/browser/dom.js';
-import { createStyleSheet } from '../../../base/browser/domStylesheets.js';
-import { IListVirtualDelegate } from '../../../base/browser/ui/list/list.js';
-import { DataTree } from '../../../base/browser/ui/tree/dataTree.js';
-import { IDataSource, ITreeNode, ITreeRenderer } from '../../../base/browser/ui/tree/tree.js';
-import { RunOnceScheduler } from '../../../base/common/async.js';
-import { ProcessItem } from '../../../base/common/processes.js';
-import { IContextMenuItem } from '../../../base/parts/contextmenu/common/contextmenu.js';
-import { popup } from '../../../base/parts/contextmenu/electron-sandbox/contextmenu.js';
-import { ipcRenderer } from '../../../base/parts/sandbox/electron-sandbox/globals.js';
-import { IRemoteDiagnosticError, isRemoteDiagnosticError } from '../../../platform/diagnostics/common/diagnostics.js';
-import { ByteSize } from '../../../platform/files/common/files.js';
-import { ElectronIPCMainProcessService } from '../../../platform/ipc/electron-sandbox/mainProcessService.js';
-import { ProcessExplorerData, ProcessExplorerStyles, ProcessExplorerWindowConfiguration } from '../../../platform/process/common/process.js';
-import { INativeHostService } from '../../../platform/native/common/native.js';
-import { NativeHostService } from '../../../platform/native/common/nativeHostService.js';
-import { getIconsStyleSheet } from '../../../platform/theme/browser/iconsStyleSheet.js';
-import { applyZoom, zoomIn, zoomOut } from '../../../platform/window/electron-sandbox/window.js';
-import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';
-import { KeyCode } from '../../../base/common/keyCodes.js';
-import { mainWindow } from '../../../base/browser/window.js';
-
-const DEBUG_FLAGS_PATTERN = /\s--inspect(?:-brk|port)?=(?\d+)?/;
-const DEBUG_PORT_PATTERN = /\s--inspect-port=(?\d+)/;
-
-class ProcessListDelegate implements IListVirtualDelegate {
- getHeight(element: MachineProcessInformation | ProcessItem | IRemoteDiagnosticError) {
- return 22;
- }
-
- getTemplateId(element: ProcessInformation | MachineProcessInformation | ProcessItem | IRemoteDiagnosticError) {
- if (isProcessItem(element)) {
- return 'process';
- }
-
- if (isMachineProcessInformation(element)) {
- return 'machine';
- }
-
- if (isRemoteDiagnosticError(element)) {
- return 'error';
- }
-
- if (isProcessInformation(element)) {
- return 'header';
- }
-
- return '';
- }
-}
-
-interface IProcessItemTemplateData extends IProcessRowTemplateData {
- readonly CPU: HTMLElement;
- readonly memory: HTMLElement;
- readonly PID: HTMLElement;
-}
-
-interface IProcessRowTemplateData {
- readonly name: HTMLElement;
-}
-
-class ProcessTreeDataSource implements IDataSource {
- hasChildren(element: ProcessTree | ProcessInformation | MachineProcessInformation | ProcessItem | IRemoteDiagnosticError): boolean {
- if (isRemoteDiagnosticError(element)) {
- return false;
- }
-
- if (isProcessItem(element)) {
- return !!element.children?.length;
- } else {
- return true;
- }
- }
-
- getChildren(element: ProcessTree | ProcessInformation | MachineProcessInformation | ProcessItem | IRemoteDiagnosticError) {
- if (isProcessItem(element)) {
- return element.children ? element.children : [];
- }
-
- if (isRemoteDiagnosticError(element)) {
- return [];
- }
-
- if (isProcessInformation(element)) {
- // If there are multiple process roots, return these, otherwise go directly to the root process
- if (element.processRoots.length > 1) {
- return element.processRoots;
- } else {
- return [element.processRoots[0].rootProcess];
- }
- }
-
- if (isMachineProcessInformation(element)) {
- return [element.rootProcess];
- }
-
- return [element.processes];
- }
-}
-
-class ProcessHeaderTreeRenderer implements ITreeRenderer {
- templateId: string = 'header';
-
- renderTemplate(container: HTMLElement): IProcessItemTemplateData {
- const row = append(container, $('.row'));
- const name = append(row, $('.nameLabel'));
- const CPU = append(row, $('.cpu'));
- const memory = append(row, $('.memory'));
- const PID = append(row, $('.pid'));
- return { name, CPU, memory, PID };
- }
-
- renderElement(node: ITreeNode, index: number, templateData: IProcessItemTemplateData, height: number | undefined): void {
- templateData.name.textContent = localize('name', "Process Name");
- templateData.CPU.textContent = localize('cpu', "CPU (%)");
- templateData.PID.textContent = localize('pid', "PID");
- templateData.memory.textContent = localize('memory', "Memory (MB)");
-
- }
-
- disposeTemplate(templateData: any): void {
- // Nothing to do
- }
-}
-
-class MachineRenderer implements ITreeRenderer {
- templateId: string = 'machine';
- renderTemplate(container: HTMLElement): IProcessRowTemplateData {
- const data = Object.create(null);
- const row = append(container, $('.row'));
- data.name = append(row, $('.nameLabel'));
- return data;
- }
- renderElement(node: ITreeNode, index: number, templateData: IProcessRowTemplateData, height: number | undefined): void {
- templateData.name.textContent = node.element.name;
- }
- disposeTemplate(templateData: IProcessRowTemplateData): void {
- // Nothing to do
- }
-}
-
-class ErrorRenderer implements ITreeRenderer {
- templateId: string = 'error';
- renderTemplate(container: HTMLElement): IProcessRowTemplateData {
- const data = Object.create(null);
- const row = append(container, $('.row'));
- data.name = append(row, $('.nameLabel'));
- return data;
- }
- renderElement(node: ITreeNode, index: number, templateData: IProcessRowTemplateData, height: number | undefined): void {
- templateData.name.textContent = node.element.errorMessage;
- }
- disposeTemplate(templateData: IProcessRowTemplateData): void {
- // Nothing to do
- }
-}
-
-
-class ProcessRenderer implements ITreeRenderer {
- constructor(private platform: string, private totalMem: number, private mapPidToName: Map) { }
-
- templateId: string = 'process';
- renderTemplate(container: HTMLElement): IProcessItemTemplateData {
- const row = append(container, $('.row'));
-
- const name = append(row, $('.nameLabel'));
- const CPU = append(row, $('.cpu'));
- const memory = append(row, $('.memory'));
- const PID = append(row, $('.pid'));
-
- return { name, CPU, PID, memory };
- }
- renderElement(node: ITreeNode, index: number, templateData: IProcessItemTemplateData, height: number | undefined): void {
- const { element } = node;
-
- const pid = element.pid.toFixed(0);
-
- let name = element.name;
- if (this.mapPidToName.has(element.pid)) {
- name = this.mapPidToName.get(element.pid)!;
- }
-
- templateData.name.textContent = name;
- templateData.name.title = element.cmd;
-
- templateData.CPU.textContent = element.load.toFixed(0);
- templateData.PID.textContent = pid;
- templateData.PID.parentElement!.id = `pid-${pid}`;
-
- const memory = this.platform === 'win32' ? element.mem : (this.totalMem * (element.mem / 100));
- templateData.memory.textContent = (memory / ByteSize.MB).toFixed(0);
- }
-
- disposeTemplate(templateData: IProcessItemTemplateData): void {
- // Nothing to do
- }
-}
-
-interface MachineProcessInformation {
- name: string;
- rootProcess: ProcessItem | IRemoteDiagnosticError;
-}
-
-interface ProcessInformation {
- processRoots: MachineProcessInformation[];
-}
-
-interface ProcessTree {
- processes: ProcessInformation;
-}
-
-function isMachineProcessInformation(item: any): item is MachineProcessInformation {
- return !!item.name && !!item.rootProcess;
-}
-
-function isProcessInformation(item: any): item is ProcessInformation {
- return !!item.processRoots;
-}
-
-function isProcessItem(item: any): item is ProcessItem {
- return !!item.pid;
-}
-
-class ProcessExplorer {
- private lastRequestTime: number;
-
- private mapPidToName = new Map();
-
- private nativeHostService: INativeHostService;
-
- private tree: DataTree | undefined;
-
- constructor(windowId: number, private data: ProcessExplorerData) {
- const mainProcessService = new ElectronIPCMainProcessService(windowId);
- this.nativeHostService = new NativeHostService(windowId, mainProcessService) as INativeHostService;
-
- this.applyStyles(data.styles);
- this.setEventHandlers(data);
-
- ipcRenderer.on('vscode:pidToNameResponse', (event: unknown, pidToNames: [number, string][]) => {
- this.mapPidToName.clear();
-
- for (const [pid, name] of pidToNames) {
- this.mapPidToName.set(pid, name);
- }
- });
-
- ipcRenderer.on('vscode:listProcessesResponse', async (event: unknown, processRoots: MachineProcessInformation[]) => {
- processRoots.forEach((info, index) => {
- if (isProcessItem(info.rootProcess)) {
- info.rootProcess.name = index === 0 ? `${this.data.applicationName} main` : 'remote agent';
- }
- });
-
- if (!this.tree) {
- await this.createProcessTree(processRoots);
- } else {
- this.tree.setInput({ processes: { processRoots } });
- this.tree.layout(mainWindow.innerHeight, mainWindow.innerWidth);
- }
-
- this.requestProcessList(0);
- });
-
- this.lastRequestTime = Date.now();
- ipcRenderer.send('vscode:pidToNameRequest');
- ipcRenderer.send('vscode:listProcesses');
- }
-
- private setEventHandlers(data: ProcessExplorerData): void {
- mainWindow.document.onkeydown = (e: KeyboardEvent) => {
- const cmdOrCtrlKey = data.platform === 'darwin' ? e.metaKey : e.ctrlKey;
-
- // Cmd/Ctrl + w closes issue window
- if (cmdOrCtrlKey && e.keyCode === 87) {
- e.stopPropagation();
- e.preventDefault();
-
- ipcRenderer.send('vscode:closeProcessExplorer');
- }
-
- // Cmd/Ctrl + zooms in
- if (cmdOrCtrlKey && e.keyCode === 187) {
- zoomIn(mainWindow);
- }
-
- // Cmd/Ctrl - zooms out
- if (cmdOrCtrlKey && e.keyCode === 189) {
- zoomOut(mainWindow);
- }
- };
- }
-
- private async createProcessTree(processRoots: MachineProcessInformation[]): Promise {
- const container = mainWindow.document.getElementById('process-list');
- if (!container) {
- return;
- }
-
- const { totalmem } = await this.nativeHostService.getOSStatistics();
-
- const renderers = [
- new ProcessRenderer(this.data.platform, totalmem, this.mapPidToName),
- new ProcessHeaderTreeRenderer(),
- new MachineRenderer(),
- new ErrorRenderer()
- ];
-
- this.tree = new DataTree('processExplorer',
- container,
- new ProcessListDelegate(),
- renderers,
- new ProcessTreeDataSource(),
- {
- identityProvider: {
- getId: (element: ProcessTree | ProcessItem | MachineProcessInformation | ProcessInformation | IRemoteDiagnosticError) => {
- if (isProcessItem(element)) {
- return element.pid.toString();
- }
-
- if (isRemoteDiagnosticError(element)) {
- return element.hostName;
- }
-
- if (isProcessInformation(element)) {
- return 'processes';
- }
-
- if (isMachineProcessInformation(element)) {
- return element.name;
- }
-
- return 'header';
- }
- }
- });
-
- this.tree.setInput({ processes: { processRoots } });
- this.tree.layout(mainWindow.innerHeight, mainWindow.innerWidth);
- this.tree.onKeyDown(e => {
- const event = new StandardKeyboardEvent(e);
- if (event.keyCode === KeyCode.KeyE && event.altKey) {
- const selectionPids = this.getSelectedPids();
- void Promise.all(selectionPids.map((pid) => this.nativeHostService.killProcess(pid, 'SIGTERM'))).then(() => this.tree?.refresh());
- }
- });
- this.tree.onContextMenu(e => {
- if (isProcessItem(e.element)) {
- this.showContextMenu(e.element, true);
- }
- });
-
- container.style.height = `${mainWindow.innerHeight}px`;
-
- mainWindow.addEventListener('resize', () => {
- container.style.height = `${mainWindow.innerHeight}px`;
- this.tree?.layout(mainWindow.innerHeight, mainWindow.innerWidth);
- });
- }
-
- private isDebuggable(cmd: string): boolean {
- const matches = DEBUG_FLAGS_PATTERN.exec(cmd);
- return (matches && matches.groups!.port !== '0') || cmd.indexOf('node ') >= 0 || cmd.indexOf('node.exe') >= 0;
- }
-
- private attachTo(item: ProcessItem) {
- const config: any = {
- type: 'node',
- request: 'attach',
- name: `process ${item.pid}`
- };
-
- let matches = DEBUG_FLAGS_PATTERN.exec(item.cmd);
- if (matches) {
- config.port = Number(matches.groups!.port);
- } else {
- // no port -> try to attach via pid (send SIGUSR1)
- config.processId = String(item.pid);
- }
-
- // a debug-port=n or inspect-port=n overrides the port
- matches = DEBUG_PORT_PATTERN.exec(item.cmd);
- if (matches) {
- // override port
- config.port = Number(matches.groups!.port);
- }
-
- ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
- }
-
- private applyStyles(styles: ProcessExplorerStyles): void {
- const styleElement = createStyleSheet();
- const content: string[] = [];
-
- if (styles.listFocusBackground) {
- content.push(`.monaco-list:focus .monaco-list-row.focused { background-color: ${styles.listFocusBackground}; }`);
- content.push(`.monaco-list:focus .monaco-list-row.focused:hover { background-color: ${styles.listFocusBackground}; }`);
- }
-
- if (styles.listFocusForeground) {
- content.push(`.monaco-list:focus .monaco-list-row.focused { color: ${styles.listFocusForeground}; }`);
- }
-
- if (styles.listActiveSelectionBackground) {
- content.push(`.monaco-list:focus .monaco-list-row.selected { background-color: ${styles.listActiveSelectionBackground}; }`);
- content.push(`.monaco-list:focus .monaco-list-row.selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`);
- }
-
- if (styles.listActiveSelectionForeground) {
- content.push(`.monaco-list:focus .monaco-list-row.selected { color: ${styles.listActiveSelectionForeground}; }`);
- }
-
- if (styles.listHoverBackground) {
- content.push(`.monaco-list-row:hover:not(.selected):not(.focused) { background-color: ${styles.listHoverBackground}; }`);
- }
-
- if (styles.listHoverForeground) {
- content.push(`.monaco-list-row:hover:not(.selected):not(.focused) { color: ${styles.listHoverForeground}; }`);
- }
-
- if (styles.listFocusOutline) {
- content.push(`.monaco-list:focus .monaco-list-row.focused { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; }`);
- }
-
- if (styles.listHoverOutline) {
- content.push(`.monaco-list-row:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`);
- }
-
- // Scrollbars
- if (styles.scrollbarShadowColor) {
- content.push(`
- .monaco-scrollable-element > .shadow.top {
- box-shadow: ${styles.scrollbarShadowColor} 0 6px 6px -6px inset;
- }
-
- .monaco-scrollable-element > .shadow.left {
- box-shadow: ${styles.scrollbarShadowColor} 6px 0 6px -6px inset;
- }
-
- .monaco-scrollable-element > .shadow.top.left {
- box-shadow: ${styles.scrollbarShadowColor} 6px 6px 6px -6px inset;
- }
- `);
- }
-
- if (styles.scrollbarSliderBackgroundColor) {
- content.push(`
- .monaco-scrollable-element > .scrollbar > .slider {
- background: ${styles.scrollbarSliderBackgroundColor};
- }
- `);
- }
-
- if (styles.scrollbarSliderHoverBackgroundColor) {
- content.push(`
- .monaco-scrollable-element > .scrollbar > .slider:hover {
- background: ${styles.scrollbarSliderHoverBackgroundColor};
- }
- `);
- }
-
- if (styles.scrollbarSliderActiveBackgroundColor) {
- content.push(`
- .monaco-scrollable-element > .scrollbar > .slider.active {
- background: ${styles.scrollbarSliderActiveBackgroundColor};
- }
- `);
- }
-
- styleElement.textContent = content.join('\n');
-
- if (styles.color) {
- mainWindow.document.body.style.color = styles.color;
- }
- }
-
- private showContextMenu(item: ProcessItem, isLocal: boolean) {
- const items: IContextMenuItem[] = [];
- const pid = Number(item.pid);
-
- if (isLocal) {
- items.push({
- accelerator: 'Alt+E',
- label: localize('killProcess', "Kill Process"),
- click: () => {
- this.nativeHostService.killProcess(pid, 'SIGTERM');
- }
- });
-
- items.push({
- label: localize('forceKillProcess', "Force Kill Process"),
- click: () => {
- this.nativeHostService.killProcess(pid, 'SIGKILL');
- }
- });
-
- items.push({
- type: 'separator'
- });
- }
-
- items.push({
- label: localize('copy', "Copy"),
- click: () => {
- // Collect the selected pids
- const selectionPids = this.getSelectedPids();
- // If the selection does not contain the right clicked item, copy the right clicked
- // item only.
- if (!selectionPids?.includes(pid)) {
- selectionPids.length = 0;
- selectionPids.push(pid);
- }
- const rows = selectionPids?.map(e => mainWindow.document.getElementById(`pid-${e}`)).filter(e => !!e) as HTMLElement[];
- if (rows) {
- const text = rows.map(e => e.innerText).filter(e => !!e) as string[];
- this.nativeHostService.writeClipboardText(text.join('\n'));
- }
- }
- });
-
- items.push({
- label: localize('copyAll', "Copy All"),
- click: () => {
- const processList = mainWindow.document.getElementById('process-list');
- if (processList) {
- this.nativeHostService.writeClipboardText(processList.innerText);
- }
- }
- });
-
- if (item && isLocal && this.isDebuggable(item.cmd)) {
- items.push({
- type: 'separator'
- });
-
- items.push({
- label: localize('debug', "Debug"),
- click: () => {
- this.attachTo(item);
- }
- });
- }
-
- popup(items);
- }
-
- private requestProcessList(totalWaitTime: number): void {
- setTimeout(() => {
- const nextRequestTime = Date.now();
- const waited = totalWaitTime + nextRequestTime - this.lastRequestTime;
- this.lastRequestTime = nextRequestTime;
-
- // Wait at least a second between requests.
- if (waited > 1000) {
- ipcRenderer.send('vscode:pidToNameRequest');
- ipcRenderer.send('vscode:listProcesses');
- } else {
- this.requestProcessList(waited);
- }
- }, 200);
- }
-
- private getSelectedPids() {
- return this.tree?.getSelection()?.map(e => {
- if (!e || !('pid' in e)) {
- return undefined;
- }
- return e.pid;
- }).filter(e => !!e) as number[];
- }
-}
-
-function createCodiconStyleSheet() {
- const codiconStyleSheet = createStyleSheet();
- codiconStyleSheet.id = 'codiconStyles';
-
- const iconsStyleSheet = getIconsStyleSheet(undefined);
- function updateAll() {
- codiconStyleSheet.textContent = iconsStyleSheet.getCSS();
- }
-
- const delayer = new RunOnceScheduler(updateAll, 0);
- iconsStyleSheet.onDidChange(() => delayer.schedule());
- delayer.schedule();
-}
-
-export interface IProcessExplorerMain {
- startup(configuration: ProcessExplorerWindowConfiguration): void;
-}
-
-export function startup(configuration: ProcessExplorerWindowConfiguration): void {
- const platformClass = configuration.data.platform === 'win32' ? 'windows' : configuration.data.platform === 'linux' ? 'linux' : 'mac';
- mainWindow.document.body.classList.add(platformClass); // used by our fonts
- createCodiconStyleSheet();
- applyZoom(configuration.data.zoomLevel, mainWindow);
-
- new ProcessExplorer(configuration.windowId, configuration.data);
-}
diff --git a/src/vs/platform/native/common/native.ts b/src/vs/platform/native/common/native.ts
index a55e5b390ed..88b12468e52 100644
--- a/src/vs/platform/native/common/native.ts
+++ b/src/vs/platform/native/common/native.ts
@@ -190,6 +190,7 @@ export interface ICommonNativeHostService {
openDevTools(options?: Partial & INativeHostOptions): Promise;
toggleDevTools(options?: INativeHostOptions): Promise;
openGPUInfoWindow(): Promise;
+ stopTracing(): Promise;
// Perf Introspection
profileRenderer(session: string, duration: number): Promise;
diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts
index cac3b314a64..e60c3d6d465 100644
--- a/src/vs/platform/native/electron-main/nativeHostMainService.ts
+++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts
@@ -5,7 +5,7 @@
import * as fs from 'fs';
import { exec } from 'child_process';
-import { app, BrowserWindow, clipboard, Display, Menu, MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, OpenDialogOptions, OpenDialogReturnValue, powerMonitor, SaveDialogOptions, SaveDialogReturnValue, screen, shell, webContents } from 'electron';
+import { app, BrowserWindow, clipboard, contentTracing, Display, Menu, MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, OpenDialogOptions, OpenDialogReturnValue, powerMonitor, SaveDialogOptions, SaveDialogReturnValue, screen, shell, webContents } from 'electron';
import { arch, cpus, freemem, loadavg, platform, release, totalmem, type } from 'os';
import { promisify } from 'util';
import { memoize } from '../../../base/common/decorators.js';
@@ -989,6 +989,25 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
}
}
+ async stopTracing(windowId: number | undefined): Promise {
+ if (!this.environmentMainService.args.trace) {
+ return; // requires tracing to be on
+ }
+
+ const path = await contentTracing.stopRecording(`${randomPath(this.environmentMainService.userHome.fsPath, this.productService.applicationName)}.trace.txt`);
+
+ // Inform user to report an issue
+ await this.dialogMainService.showMessageBox({
+ type: 'info',
+ message: localize('trace.message', "Successfully created the trace file"),
+ detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
+ buttons: [localize({ key: 'trace.ok', comment: ['&& denotes a mnemonic'] }, "&&OK")],
+ }, BrowserWindow.getFocusedWindow() ?? undefined);
+
+ // Show item in explorer
+ this.showItemInFolder(undefined, path);
+ }
+
//#endregion
// #region Performance
diff --git a/src/vs/platform/process/common/process.ts b/src/vs/platform/process/common/process.ts
index 8495e91904a..7b3974a01f1 100644
--- a/src/vs/platform/process/common/process.ts
+++ b/src/vs/platform/process/common/process.ts
@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { ProcessItem } from '../../../base/common/processes.js';
-import { ISandboxConfiguration } from '../../../base/parts/sandbox/common/sandboxTypes.js';
import { IRemoteDiagnosticError, PerformanceInfo, SystemInfo } from '../../diagnostics/common/diagnostics.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';
@@ -30,50 +29,20 @@ export interface ISettingSearchResult {
score: number;
}
-export interface ProcessExplorerStyles extends WindowStyles {
- listHoverBackground?: string;
- listHoverForeground?: string;
- listFocusBackground?: string;
- listFocusForeground?: string;
- listFocusOutline?: string;
- listActiveSelectionBackground?: string;
- listActiveSelectionForeground?: string;
- listHoverOutline?: string;
- scrollbarShadowColor?: string;
- scrollbarSliderBackgroundColor?: string;
- scrollbarSliderHoverBackgroundColor?: string;
- scrollbarSliderActiveBackgroundColor?: string;
-}
-
-export interface ProcessExplorerData extends WindowData {
- pid: number;
- styles: ProcessExplorerStyles;
- platform: string;
- applicationName: string;
-}
-
-export interface ProcessExplorerWindowConfiguration extends ISandboxConfiguration {
- data: ProcessExplorerData;
-}
-
-export const IProcessMainService = createDecorator('processService');
+export const IProcessService = createDecorator('processService');
export interface IResolvedProcessInformation {
readonly pidToNames: [number, string][];
readonly processes: { name: string; rootProcess: ProcessItem | IRemoteDiagnosticError }[];
}
-export interface IProcessMainService {
+export interface IProcessService {
readonly _serviceBrand: undefined;
- getSystemStatus(): Promise;
- stopTracing(): Promise;
- openProcessExplorer(data: ProcessExplorerData): Promise;
-
resolve(): Promise;
- // Used by the process explorer
- $getSystemInfo(): Promise;
- $getPerformanceInfo(): Promise;
+ getSystemStatus(): Promise;
+ getSystemInfo(): Promise;
+ getPerformanceInfo(): Promise;
}
diff --git a/src/vs/platform/process/electron-main/processMainService.ts b/src/vs/platform/process/electron-main/processMainService.ts
index be12b2c8938..4939c35a2d2 100644
--- a/src/vs/platform/process/electron-main/processMainService.ts
+++ b/src/vs/platform/process/electron-main/processMainService.ts
@@ -3,64 +3,24 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { BrowserWindow, BrowserWindowConstructorOptions, contentTracing, Display, IpcMainEvent, screen } from 'electron';
-import { randomPath } from '../../../base/common/extpath.js';
-import { DisposableStore } from '../../../base/common/lifecycle.js';
-import { FileAccess } from '../../../base/common/network.js';
-import { IProcessEnvironment, isMacintosh } from '../../../base/common/platform.js';
import { listProcesses } from '../../../base/node/ps.js';
-import { validatedIpcMain } from '../../../base/parts/ipc/electron-main/ipcMain.js';
-import { getNLSLanguage, getNLSMessages, localize } from '../../../nls.js';
+import { localize } from '../../../nls.js';
import { IDiagnosticsService, IRemoteDiagnosticError, isRemoteDiagnosticError, PerformanceInfo, SystemInfo } from '../../diagnostics/common/diagnostics.js';
import { IDiagnosticsMainService } from '../../diagnostics/electron-main/diagnosticsMainService.js';
-import { IDialogMainService } from '../../dialogs/electron-main/dialogMainService.js';
-import { IEnvironmentMainService } from '../../environment/electron-main/environmentMainService.js';
-import { ICSSDevelopmentService } from '../../cssDev/node/cssDevService.js';
-import { IProcessMainService, IResolvedProcessInformation, ProcessExplorerData, ProcessExplorerWindowConfiguration } from '../common/process.js';
+import { IProcessService, IResolvedProcessInformation } from '../common/process.js';
import { ILogService } from '../../log/common/log.js';
-import { INativeHostMainService } from '../../native/electron-main/nativeHostMainService.js';
-import product from '../../product/common/product.js';
-import { IProductService } from '../../product/common/productService.js';
-import { IIPCObjectUrl, IProtocolMainService } from '../../protocol/electron-main/protocol.js';
-import { IStateService } from '../../state/node/state.js';
import { UtilityProcess } from '../../utilityProcess/electron-main/utilityProcess.js';
-import { zoomLevelToZoomFactor } from '../../window/common/window.js';
-import { IWindowState } from '../../window/electron-main/window.js';
import { ProcessItem } from '../../../base/common/processes.js';
-const processExplorerWindowState = 'issue.processExplorerWindowState';
-
-interface IBrowserWindowOptions {
- backgroundColor: string | undefined;
- title: string;
- zoomLevel: number;
-}
-
-type IStrictWindowState = Required>;
-
-export class ProcessMainService implements IProcessMainService {
+export class ProcessMainService implements IProcessService {
declare readonly _serviceBrand: undefined;
- private static readonly DEFAULT_BACKGROUND_COLOR = '#1E1E1E';
-
- private processExplorerWindow: BrowserWindow | null = null;
- private processExplorerParentWindow: BrowserWindow | null = null;
-
constructor(
- private userEnv: IProcessEnvironment,
- @IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
@ILogService private readonly logService: ILogService,
@IDiagnosticsService private readonly diagnosticsService: IDiagnosticsService,
- @IDiagnosticsMainService private readonly diagnosticsMainService: IDiagnosticsMainService,
- @IDialogMainService private readonly dialogMainService: IDialogMainService,
- @INativeHostMainService private readonly nativeHostMainService: INativeHostMainService,
- @IProtocolMainService private readonly protocolMainService: IProtocolMainService,
- @IProductService private readonly productService: IProductService,
- @IStateService private readonly stateService: IStateService,
- @ICSSDevelopmentService private readonly cssDevelopmentService: ICSSDevelopmentService
+ @IDiagnosticsMainService private readonly diagnosticsMainService: IDiagnosticsMainService
) {
- this.registerListeners();
}
async resolve(): Promise {
@@ -76,7 +36,6 @@ export class ProcessMainService implements IProcessMainService {
}
const processes: { name: string; rootProcess: ProcessItem | IRemoteDiagnosticError }[] = [];
-
try {
processes.push({ name: localize('local', "Local"), rootProcess: await listProcesses(process.pid) });
@@ -103,259 +62,20 @@ export class ProcessMainService implements IProcessMainService {
return { pidToNames, processes };
}
- //#region Register Listeners
-
- private registerListeners(): void {
- validatedIpcMain.on('vscode:listProcesses', async event => {
- const processes = [];
-
- try {
- processes.push({ name: localize('local', "Local"), rootProcess: await listProcesses(process.pid) });
-
- const remoteDiagnostics = await this.diagnosticsMainService.getRemoteDiagnostics({ includeProcesses: true });
- remoteDiagnostics.forEach(data => {
- if (isRemoteDiagnosticError(data)) {
- processes.push({
- name: data.hostName,
- rootProcess: data
- });
- } else {
- if (data.processes) {
- processes.push({
- name: data.hostName,
- rootProcess: data.processes
- });
- }
- }
- });
- } catch (e) {
- this.logService.error(`Listing processes failed: ${e}`);
- }
-
- this.safeSend(event, 'vscode:listProcessesResponse', processes);
- });
-
- validatedIpcMain.on('vscode:workbenchCommand', (_: unknown, commandInfo: { id: any; from: any; args: any }) => {
- const { id, from, args } = commandInfo;
-
- let parentWindow: BrowserWindow | null;
- switch (from) {
- case 'processExplorer':
- parentWindow = this.processExplorerParentWindow;
- break;
- default:
- // The issue reporter does not use this anymore.
- throw new Error(`Unexpected command source: ${from}`);
- }
-
- parentWindow?.webContents.send('vscode:runAction', { id, from, args });
- });
-
- validatedIpcMain.on('vscode:closeProcessExplorer', event => {
- this.processExplorerWindow?.close();
- });
-
- validatedIpcMain.on('vscode:pidToNameRequest', async event => {
- const mainProcessInfo = await this.diagnosticsMainService.getMainDiagnostics();
-
- const pidToNames: [number, string][] = [];
- for (const window of mainProcessInfo.windows) {
- pidToNames.push([window.pid, `window [${window.id}] (${window.title})`]);
- }
-
- for (const { pid, name } of UtilityProcess.getAll()) {
- pidToNames.push([pid, name]);
- }
-
- this.safeSend(event, 'vscode:pidToNameResponse', pidToNames);
- });
- }
-
- async openProcessExplorer(data: ProcessExplorerData): Promise {
- if (!this.processExplorerWindow) {
- this.processExplorerParentWindow = BrowserWindow.getFocusedWindow();
- if (this.processExplorerParentWindow) {
- const processExplorerDisposables = new DisposableStore();
-
- const processExplorerWindowConfigUrl = processExplorerDisposables.add(this.protocolMainService.createIPCObjectUrl());
-
- const savedPosition = this.stateService.getItem(processExplorerWindowState, undefined);
- const position = isStrictWindowState(savedPosition) ? savedPosition : this.getWindowPosition(this.processExplorerParentWindow, 800, 500);
-
- this.processExplorerWindow = this.createBrowserWindow(position, processExplorerWindowConfigUrl, {
- backgroundColor: data.styles.backgroundColor,
- title: localize('processExplorer', "Process Explorer"),
- zoomLevel: data.zoomLevel
- }, 'process-explorer');
-
- // Store into config object URL
- processExplorerWindowConfigUrl.update({
- appRoot: this.environmentMainService.appRoot,
- windowId: this.processExplorerWindow.id,
- userEnv: this.userEnv,
- data,
- product,
- nls: {
- messages: getNLSMessages(),
- language: getNLSLanguage()
- },
- cssModules: this.cssDevelopmentService.isEnabled ? await this.cssDevelopmentService.getCssModules() : undefined
- });
-
- this.processExplorerWindow.loadURL(
- FileAccess.asBrowserUri(`vs/code/electron-sandbox/processExplorer/processExplorer${this.environmentMainService.isBuilt ? '' : '-dev'}.html`).toString(true)
- );
-
- this.processExplorerWindow.on('close', () => {
- this.processExplorerWindow = null;
- processExplorerDisposables.dispose();
- });
-
- this.processExplorerParentWindow.on('close', () => {
- if (this.processExplorerWindow) {
- this.processExplorerWindow.close();
- this.processExplorerWindow = null;
-
- processExplorerDisposables.dispose();
- }
- });
-
- const storeState = () => {
- if (!this.processExplorerWindow) {
- return;
- }
- const size = this.processExplorerWindow.getSize();
- const position = this.processExplorerWindow.getPosition();
- if (!size || !position) {
- return;
- }
- const state: IWindowState = {
- width: size[0],
- height: size[1],
- x: position[0],
- y: position[1]
- };
- this.stateService.setItem(processExplorerWindowState, state);
- };
-
- this.processExplorerWindow.on('moved', storeState);
- this.processExplorerWindow.on('resized', storeState);
- }
- }
-
- if (this.processExplorerWindow) {
- this.focusWindow(this.processExplorerWindow);
- }
- }
-
- private focusWindow(window: BrowserWindow): void {
- if (window.isMinimized()) {
- window.restore();
- }
-
- window.focus();
- }
-
- private getWindowPosition(parentWindow: BrowserWindow, defaultWidth: number, defaultHeight: number): IStrictWindowState {
-
- // We want the new window to open on the same display that the parent is in
- let displayToUse: Display | undefined;
- const displays = screen.getAllDisplays();
-
- // Single Display
- if (displays.length === 1) {
- displayToUse = displays[0];
- }
-
- // Multi Display
- else {
-
- // on mac there is 1 menu per window so we need to use the monitor where the cursor currently is
- if (isMacintosh) {
- const cursorPoint = screen.getCursorScreenPoint();
- displayToUse = screen.getDisplayNearestPoint(cursorPoint);
- }
-
- // if we have a last active window, use that display for the new window
- if (!displayToUse && parentWindow) {
- displayToUse = screen.getDisplayMatching(parentWindow.getBounds());
- }
-
- // fallback to primary display or first display
- if (!displayToUse) {
- displayToUse = screen.getPrimaryDisplay() || displays[0];
- }
- }
-
- const displayBounds = displayToUse.bounds;
-
- const state: IStrictWindowState = {
- width: defaultWidth,
- height: defaultHeight,
- x: displayBounds.x + (displayBounds.width / 2) - (defaultWidth / 2),
- y: displayBounds.y + (displayBounds.height / 2) - (defaultHeight / 2)
- };
-
- if (displayBounds.width > 0 && displayBounds.height > 0 /* Linux X11 sessions sometimes report wrong display bounds */) {
- if (state.x < displayBounds.x) {
- state.x = displayBounds.x; // prevent window from falling out of the screen to the left
- }
-
- if (state.y < displayBounds.y) {
- state.y = displayBounds.y; // prevent window from falling out of the screen to the top
- }
-
- if (state.x > (displayBounds.x + displayBounds.width)) {
- state.x = displayBounds.x; // prevent window from falling out of the screen to the right
- }
-
- if (state.y > (displayBounds.y + displayBounds.height)) {
- state.y = displayBounds.y; // prevent window from falling out of the screen to the bottom
- }
-
- if (state.width > displayBounds.width) {
- state.width = displayBounds.width; // prevent window from exceeding display bounds width
- }
-
- if (state.height > displayBounds.height) {
- state.height = displayBounds.height; // prevent window from exceeding display bounds height
- }
- }
-
- return state;
- }
-
- async stopTracing(): Promise {
- if (!this.environmentMainService.args.trace) {
- return; // requires tracing to be on
- }
-
- const path = await contentTracing.stopRecording(`${randomPath(this.environmentMainService.userHome.fsPath, this.productService.applicationName)}.trace.txt`);
-
- // Inform user to report an issue
- await this.dialogMainService.showMessageBox({
- type: 'info',
- message: localize('trace.message', "Successfully created the trace file"),
- detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
- buttons: [localize({ key: 'trace.ok', comment: ['&& denotes a mnemonic'] }, "&&OK")],
- }, BrowserWindow.getFocusedWindow() ?? undefined);
-
- // Show item in explorer
- this.nativeHostMainService.showItemInFolder(undefined, path);
- }
-
async getSystemStatus(): Promise {
const [info, remoteData] = await Promise.all([this.diagnosticsMainService.getMainDiagnostics(), this.diagnosticsMainService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })]);
+
return this.diagnosticsService.getDiagnostics(info, remoteData);
}
- async $getSystemInfo(): Promise {
+ async getSystemInfo(): Promise {
const [info, remoteData] = await Promise.all([this.diagnosticsMainService.getMainDiagnostics(), this.diagnosticsMainService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })]);
const msg = await this.diagnosticsService.getSystemInfo(info, remoteData);
+
return msg;
}
- async $getPerformanceInfo(): Promise {
+ async getPerformanceInfo(): Promise {
try {
const [info, remoteData] = await Promise.all([this.diagnosticsMainService.getMainDiagnostics(), this.diagnosticsMainService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true })]);
return await this.diagnosticsService.getPerformanceInfo(info, remoteData);
@@ -365,58 +85,4 @@ export class ProcessMainService implements IProcessMainService {
throw error;
}
}
-
- private createBrowserWindow(position: IWindowState, ipcObjectUrl: IIPCObjectUrl, options: IBrowserWindowOptions, windowKind: string): BrowserWindow {
- const browserWindowOptions: BrowserWindowConstructorOptions & { experimentalDarkMode: boolean } = {
- fullscreen: false,
- skipTaskbar: false,
- resizable: true,
- width: position.width,
- height: position.height,
- minWidth: 300,
- minHeight: 200,
- x: position.x,
- y: position.y,
- title: options.title,
- backgroundColor: options.backgroundColor || ProcessMainService.DEFAULT_BACKGROUND_COLOR,
- webPreferences: {
- preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-sandbox/preload.js').fsPath,
- additionalArguments: [`--vscode-window-config=${ipcObjectUrl.resource.toString()}`],
- v8CacheOptions: this.environmentMainService.useCodeCache ? 'bypassHeatCheck' : 'none',
- enableWebSQL: false,
- spellcheck: false,
- zoomFactor: zoomLevelToZoomFactor(options.zoomLevel),
- sandbox: true
- },
- alwaysOnTop: true,
- experimentalDarkMode: true
- };
- const window = new BrowserWindow(browserWindowOptions);
-
- window.setMenuBarVisibility(false);
-
- return window;
- }
-
- private safeSend(event: IpcMainEvent, channel: string, ...args: unknown[]): void {
- if (!event.sender.isDestroyed()) {
- event.sender.send(channel, ...args);
- }
- }
-
- async closeProcessExplorer(): Promise {
- this.processExplorerWindow?.close();
- }
-}
-
-function isStrictWindowState(obj: unknown): obj is IStrictWindowState {
- if (typeof obj !== 'object' || obj === null) {
- return false;
- }
- return (
- 'x' in obj &&
- 'y' in obj &&
- 'width' in obj &&
- 'height' in obj
- );
}
diff --git a/src/vs/workbench/contrib/issue/common/issue.ts b/src/vs/workbench/contrib/issue/common/issue.ts
index f8f05bbb64d..5e12f63c971 100644
--- a/src/vs/workbench/contrib/issue/common/issue.ts
+++ b/src/vs/workbench/contrib/issue/common/issue.ts
@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { UriComponents } from '../../../../base/common/uri.js';
-import { ISandboxConfiguration } from '../../../../base/parts/sandbox/common/sandboxTypes.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
// Since data sent through the service is serialized to JSON, functions will be lost, so Color objects
@@ -86,32 +85,6 @@ export interface ISettingSearchResult {
score: number;
}
-export interface ProcessExplorerStyles extends WindowStyles {
- listHoverBackground?: string;
- listHoverForeground?: string;
- listFocusBackground?: string;
- listFocusForeground?: string;
- listFocusOutline?: string;
- listActiveSelectionBackground?: string;
- listActiveSelectionForeground?: string;
- listHoverOutline?: string;
- scrollbarShadowColor?: string;
- scrollbarSliderBackgroundColor?: string;
- scrollbarSliderHoverBackgroundColor?: string;
- scrollbarSliderActiveBackgroundColor?: string;
-}
-
-export interface ProcessExplorerData extends WindowData {
- pid: number;
- styles: ProcessExplorerStyles;
- platform: string;
- applicationName: string;
-}
-
-export interface ProcessExplorerWindowConfiguration extends ISandboxConfiguration {
- data: ProcessExplorerData;
-}
-
export const IIssueFormService = createDecorator('issueFormService');
export interface IIssueFormService {
@@ -132,11 +105,3 @@ export interface IWorkbenchIssueService {
readonly _serviceBrand: undefined;
openReporter(dataOverrides?: Partial): Promise;
}
-
-export const IWorkbenchProcessService = createDecorator('workbenchProcessService');
-
-export interface IWorkbenchProcessService {
- readonly _serviceBrand: undefined;
- openProcessExplorer(): Promise;
-}
-
diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issue.contribution.ts b/src/vs/workbench/contrib/issue/electron-sandbox/issue.contribution.ts
index 547921c95de..391b9333b2c 100644
--- a/src/vs/workbench/contrib/issue/electron-sandbox/issue.contribution.ts
+++ b/src/vs/workbench/contrib/issue/electron-sandbox/issue.contribution.ts
@@ -7,9 +7,11 @@ import { IDisposable } from '../../../../base/common/lifecycle.js';
import { localize, localize2 } from '../../../../nls.js';
import { Categories } from '../../../../platform/action/common/actionCommonCategories.js';
import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';
+import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
+import { IProcessService } from '../../../../platform/process/common/process.js';
import { IProductService } from '../../../../platform/product/common/productService.js';
import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from '../../../../platform/quickinput/common/quickAccess.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
@@ -21,7 +23,6 @@ import { BaseIssueContribution } from '../common/issue.contribution.js';
import { IIssueFormService, IWorkbenchIssueService, IssueType } from '../common/issue.js';
import { NativeIssueService } from './issueService.js';
import { NativeIssueFormService } from './nativeIssueFormService.js';
-import './processMainService.js';
//#region Issue Contribution
registerSingleton(IWorkbenchIssueService, NativeIssueService, InstantiationType.Delayed);
@@ -94,4 +95,8 @@ class ReportPerformanceIssueUsingReporterAction extends Action2 {
}
}
+CommandsRegistry.registerCommand('_issues.getSystemStatus', (accessor) => {
+ return accessor.get(IProcessService).getSystemStatus();
+});
+
// #endregion
diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts
index ae07c39997a..cbdf9723c31 100644
--- a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts
+++ b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts
@@ -14,7 +14,7 @@ import { isRemoteDiagnosticError } from '../../../../platform/diagnostics/common
import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js';
import { IFileService } from '../../../../platform/files/common/files.js';
import { INativeHostService } from '../../../../platform/native/common/native.js';
-import { IProcessMainService } from '../../../../platform/process/common/process.js';
+import { IProcessService } from '../../../../platform/process/common/process.js';
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
import { IUpdateService, StateType } from '../../../../platform/update/common/update.js';
import { applyZoom } from '../../../../platform/window/electron-sandbox/window.js';
@@ -32,7 +32,7 @@ const MAX_GITHUB_API_LENGTH = 65500;
export class IssueReporter extends BaseIssueReporterService {
- private readonly processMainService: IProcessMainService;
+ private readonly processService: IProcessService;
constructor(
disableExtensions: boolean,
data: IssueReporterData,
@@ -45,15 +45,15 @@ export class IssueReporter extends BaseIssueReporterService {
window: Window,
@INativeHostService private readonly nativeHostService: INativeHostService,
@IIssueFormService issueFormService: IIssueFormService,
- @IProcessMainService processMainService: IProcessMainService,
+ @IProcessService processService: IProcessService,
@IThemeService themeService: IThemeService,
@IFileService fileService: IFileService,
@IFileDialogService fileDialogService: IFileDialogService,
@IUpdateService private readonly updateService: IUpdateService
) {
super(disableExtensions, data, os, product, window, false, issueFormService, themeService, fileService, fileDialogService);
- this.processMainService = processMainService;
- this.processMainService.$getSystemInfo().then(info => {
+ this.processService = processService;
+ this.processService.getSystemInfo().then(info => {
this.issueReporterModel.update({ systemInfo: info });
this.receivedSystemInfo = true;
@@ -61,7 +61,7 @@ export class IssueReporter extends BaseIssueReporterService {
this.updatePreviewButtonState();
});
if (this.data.issueType === IssueType.PerformanceIssue) {
- this.processMainService.$getPerformanceInfo().then(info => {
+ this.processService.getPerformanceInfo().then(info => {
this.updatePerformanceInfo(info as Partial);
});
}
@@ -95,7 +95,7 @@ export class IssueReporter extends BaseIssueReporterService {
const issueType = parseInt((event.target).value);
this.issueReporterModel.update({ issueType: issueType });
if (issueType === IssueType.PerformanceIssue && !this.receivedPerformanceInfo) {
- this.processMainService.$getPerformanceInfo().then(info => {
+ this.processService.getPerformanceInfo().then(info => {
this.updatePerformanceInfo(info as Partial);
});
}
diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/process.contribution.ts b/src/vs/workbench/contrib/issue/electron-sandbox/process.contribution.ts
deleted file mode 100644
index 116d8d57839..00000000000
--- a/src/vs/workbench/contrib/issue/electron-sandbox/process.contribution.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import { localize, localize2 } from '../../../../nls.js';
-import { MenuRegistry, MenuId, registerAction2, Action2 } from '../../../../platform/actions/common/actions.js';
-import { IWorkbenchProcessService } from '../common/issue.js';
-import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
-import { Categories } from '../../../../platform/action/common/actionCommonCategories.js';
-import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
-import { INativeEnvironmentService } from '../../../../platform/environment/common/environment.js';
-import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
-import { INativeHostService } from '../../../../platform/native/common/native.js';
-import { IProgressService, ProgressLocation } from '../../../../platform/progress/common/progress.js';
-import { IProcessMainService } from '../../../../platform/process/common/process.js';
-import './processService.js';
-import './processMainService.js';
-import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
-import { AUX_WINDOW_GROUP, IEditorService } from '../../../services/editor/common/editorService.js';
-import { ProcessExplorerEditorInput } from '../../processExplorer/electron-sandbox/processExplorerEditorInput.js';
-
-//#region Commands
-
-class OpenProcessExplorer extends Action2 {
-
- static readonly ID = 'workbench.action.openProcessExplorer';
-
- constructor() {
- super({
- id: OpenProcessExplorer.ID,
- title: localize2('openProcessExplorer', 'Open Process Explorer'),
- category: Categories.Developer,
- f1: true
- });
- }
-
- override async run(accessor: ServicesAccessor): Promise {
- const processService = accessor.get(IWorkbenchProcessService);
- const configurationService = accessor.get(IConfigurationService);
- const editorService = accessor.get(IEditorService);
-
- if (configurationService.getValue('application.useNewProcessExplorer') !== true) {
- return processService.openProcessExplorer();
- }
-
- editorService.openEditor({ resource: ProcessExplorerEditorInput.RESOURCE, options: { pinned: true, auxiliary: { compact: true, bounds: { width: 800, height: 500 }, alwaysOnTop: true } } }, AUX_WINDOW_GROUP);
- }
-}
-registerAction2(OpenProcessExplorer);
-MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
- group: '5_tools',
- command: {
- id: OpenProcessExplorer.ID,
- title: localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")
- },
- order: 2
-});
-
-class StopTracing extends Action2 {
-
- static readonly ID = 'workbench.action.stopTracing';
-
- constructor() {
- super({
- id: StopTracing.ID,
- title: localize2('stopTracing', 'Stop Tracing'),
- category: Categories.Developer,
- f1: true
- });
- }
-
- override async run(accessor: ServicesAccessor): Promise {
- const processService = accessor.get(IProcessMainService);
- const environmentService = accessor.get(INativeEnvironmentService);
- const dialogService = accessor.get(IDialogService);
- const nativeHostService = accessor.get(INativeHostService);
- const progressService = accessor.get(IProgressService);
-
- if (!environmentService.args.trace) {
- const { confirmed } = await dialogService.confirm({
- message: localize('stopTracing.message', "Tracing requires to launch with a '--trace' argument"),
- primaryButton: localize({ key: 'stopTracing.button', comment: ['&& denotes a mnemonic'] }, "&&Relaunch and Enable Tracing"),
- });
-
- if (confirmed) {
- return nativeHostService.relaunch({ addArgs: ['--trace'] });
- }
- }
-
- await progressService.withProgress({
- location: ProgressLocation.Dialog,
- title: localize('stopTracing.title', "Creating trace file..."),
- cancellable: false,
- detail: localize('stopTracing.detail', "This can take up to one minute to complete.")
- }, () => processService.stopTracing());
- }
-}
-registerAction2(StopTracing);
-
-CommandsRegistry.registerCommand('_issues.getSystemStatus', (accessor) => {
- return accessor.get(IProcessMainService).getSystemStatus();
-});
-//#endregion
diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/processService.ts b/src/vs/workbench/contrib/issue/electron-sandbox/processService.ts
deleted file mode 100644
index d5837297bed..00000000000
--- a/src/vs/workbench/contrib/issue/electron-sandbox/processService.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import { getZoomLevel } from '../../../../base/browser/browser.js';
-import { platform } from '../../../../base/common/process.js';
-import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
-import { IProcessMainService, ProcessExplorerData } from '../../../../platform/process/common/process.js';
-import { IProductService } from '../../../../platform/product/common/productService.js';
-import { activeContrastBorder, editorBackground, editorForeground, listActiveSelectionBackground, listActiveSelectionForeground, listFocusBackground, listFocusForeground, listFocusOutline, listHoverBackground, listHoverForeground, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from '../../../../platform/theme/common/colorRegistry.js';
-import { IColorTheme, IThemeService } from '../../../../platform/theme/common/themeService.js';
-import { INativeWorkbenchEnvironmentService } from '../../../services/environment/electron-sandbox/environmentService.js';
-import { IWorkbenchProcessService } from '../common/issue.js';
-import { mainWindow } from '../../../../base/browser/window.js';
-
-export class ProcessService implements IWorkbenchProcessService {
- declare readonly _serviceBrand: undefined;
-
- constructor(
- @IProcessMainService private readonly processMainService: IProcessMainService,
- @IThemeService private readonly themeService: IThemeService,
- @INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService,
- @IProductService private readonly productService: IProductService,
- ) { }
-
- openProcessExplorer(): Promise {
- const theme = this.themeService.getColorTheme();
- const data: ProcessExplorerData = {
- pid: this.environmentService.mainPid,
- zoomLevel: getZoomLevel(mainWindow),
- styles: {
- backgroundColor: getColor(theme, editorBackground),
- color: getColor(theme, editorForeground),
- listHoverBackground: getColor(theme, listHoverBackground),
- listHoverForeground: getColor(theme, listHoverForeground),
- listFocusBackground: getColor(theme, listFocusBackground),
- listFocusForeground: getColor(theme, listFocusForeground),
- listFocusOutline: getColor(theme, listFocusOutline),
- listActiveSelectionBackground: getColor(theme, listActiveSelectionBackground),
- listActiveSelectionForeground: getColor(theme, listActiveSelectionForeground),
- listHoverOutline: getColor(theme, activeContrastBorder),
- scrollbarShadowColor: getColor(theme, scrollbarShadow),
- scrollbarSliderActiveBackgroundColor: getColor(theme, scrollbarSliderActiveBackground),
- scrollbarSliderBackgroundColor: getColor(theme, scrollbarSliderBackground),
- scrollbarSliderHoverBackgroundColor: getColor(theme, scrollbarSliderHoverBackground),
- },
- platform: platform,
- applicationName: this.productService.applicationName
- };
- return this.processMainService.openProcessExplorer(data);
- }
-
-
-}
-
-function getColor(theme: IColorTheme, key: string): string | undefined {
- const color = theme.getColor(key);
- return color ? color.toString() : undefined;
-}
-
-registerSingleton(IWorkbenchProcessService, ProcessService, InstantiationType.Delayed);
diff --git a/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorer.contribution.ts b/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorer.contribution.ts
index 7424d9b0412..817e74c82c7 100644
--- a/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorer.contribution.ts
+++ b/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorer.contribution.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { localize } from '../../../../nls.js';
+import { localize, localize2 } from '../../../../nls.js';
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
-import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
+import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/editor.js';
import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js';
@@ -14,6 +14,11 @@ import { EditorInput } from '../../../common/editor/editorInput.js';
import { IEditorResolverService, RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js';
import { ProcessExplorerEditorInput } from './processExplorerEditorInput.js';
import { ProcessExplorerEditor } from './processExplorerEditor.js';
+import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../platform/actions/common/actions.js';
+import { Categories } from '../../../../platform/action/common/actionCommonCategories.js';
+import { AUX_WINDOW_GROUP, IEditorService } from '../../../services/editor/common/editorService.js';
+
+//#region --- process explorer
class ProcessExplorerEditorContribution implements IWorkbenchContribution {
@@ -71,3 +76,40 @@ class ProcessExplorerEditorInputSerializer implements IEditorSerializer {
}
Registry.as(EditorExtensions.EditorFactory).registerEditorSerializer(ProcessExplorerEditorInput.ID, ProcessExplorerEditorInputSerializer);
+
+//#endregion
+
+//#region --- process explorer commands
+
+class OpenProcessExplorer extends Action2 {
+
+ static readonly ID = 'workbench.action.openProcessExplorer';
+
+ constructor() {
+ super({
+ id: OpenProcessExplorer.ID,
+ title: localize2('openProcessExplorer', 'Open Process Explorer'),
+ category: Categories.Developer,
+ f1: true
+ });
+ }
+
+ override async run(accessor: ServicesAccessor): Promise {
+ const editorService = accessor.get(IEditorService);
+
+ editorService.openEditor({ resource: ProcessExplorerEditorInput.RESOURCE, options: { pinned: true, auxiliary: { compact: true, bounds: { width: 800, height: 500 }, alwaysOnTop: true } } }, AUX_WINDOW_GROUP);
+ }
+}
+
+registerAction2(OpenProcessExplorer);
+
+MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
+ group: '5_tools',
+ command: {
+ id: OpenProcessExplorer.ID,
+ title: localize({ key: 'miOpenProcessExplorerer', comment: ['&& denotes a mnemonic'] }, "Open &&Process Explorer")
+ },
+ order: 2
+});
+
+//#endregion
diff --git a/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorerControl.ts b/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorerControl.ts
index 5bfba8fc8e6..c6f24657a15 100644
--- a/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorerControl.ts
+++ b/src/vs/workbench/contrib/processExplorer/electron-sandbox/processExplorerControl.ts
@@ -25,7 +25,7 @@ import { coalesce } from '../../../../base/common/arrays.js';
import { ICommandService } from '../../../../platform/commands/common/commands.js';
import { RenderIndentGuides } from '../../../../base/browser/ui/tree/abstractTree.js';
import { isWindows } from '../../../../base/common/platform.js';
-import { IProcessMainService } from '../../../../platform/process/common/process.js';
+import { IProcessService } from '../../../../platform/process/common/process.js';
import { Delayer } from '../../../../base/common/async.js';
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
import { IManagedHover } from '../../../../base/browser/ui/hover/hover.js';
@@ -345,7 +345,7 @@ export class ProcessExplorerControl extends Disposable {
@IProductService private readonly productService: IProductService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@ICommandService private readonly commandService: ICommandService,
- @IProcessMainService private readonly processMainService: IProcessMainService
+ @IProcessService private readonly processService: IProcessService
) {
super();
@@ -496,7 +496,7 @@ export class ProcessExplorerControl extends Disposable {
}
private async update(): Promise {
- const { processes, pidToNames } = await this.processMainService.resolve();
+ const { processes, pidToNames } = await this.processService.resolve();
this.model.update(processes, pidToNames);
diff --git a/src/vs/workbench/electron-sandbox/actions/developerActions.ts b/src/vs/workbench/electron-sandbox/actions/developerActions.ts
index 42ce42d0025..1bc0f68c98a 100644
--- a/src/vs/workbench/electron-sandbox/actions/developerActions.ts
+++ b/src/vs/workbench/electron-sandbox/actions/developerActions.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { localize2 } from '../../../nls.js';
+import { localize, localize2 } from '../../../nls.js';
import { INativeHostService } from '../../../platform/native/common/native.js';
import { IEditorService } from '../../services/editor/common/editorService.js';
import { Action2, MenuId } from '../../../platform/actions/common/actions.js';
@@ -16,6 +16,9 @@ import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js';
import { INativeWorkbenchEnvironmentService } from '../../services/environment/electron-sandbox/environmentService.js';
import { URI } from '../../../base/common/uri.js';
import { getActiveWindow } from '../../../base/browser/dom.js';
+import { IDialogService } from '../../../platform/dialogs/common/dialogs.js';
+import { INativeEnvironmentService } from '../../../platform/environment/common/environment.js';
+import { IProgressService, ProgressLocation } from '../../../platform/progress/common/progress.js';
export class ToggleDevToolsAction extends Action2 {
@@ -119,3 +122,42 @@ export class ShowGPUInfoAction extends Action2 {
nativeHostService.openGPUInfoWindow();
}
}
+
+export class StopTracing extends Action2 {
+
+ static readonly ID = 'workbench.action.stopTracing';
+
+ constructor() {
+ super({
+ id: StopTracing.ID,
+ title: localize2('stopTracing', 'Stop Tracing'),
+ category: Categories.Developer,
+ f1: true
+ });
+ }
+
+ override async run(accessor: ServicesAccessor): Promise {
+ const environmentService = accessor.get(INativeEnvironmentService);
+ const dialogService = accessor.get(IDialogService);
+ const nativeHostService = accessor.get(INativeHostService);
+ const progressService = accessor.get(IProgressService);
+
+ if (!environmentService.args.trace) {
+ const { confirmed } = await dialogService.confirm({
+ message: localize('stopTracing.message', "Tracing requires to launch with a '--trace' argument"),
+ primaryButton: localize({ key: 'stopTracing.button', comment: ['&& denotes a mnemonic'] }, "&&Relaunch and Enable Tracing"),
+ });
+
+ if (confirmed) {
+ return nativeHostService.relaunch({ addArgs: ['--trace'] });
+ }
+ }
+
+ await progressService.withProgress({
+ location: ProgressLocation.Dialog,
+ title: localize('stopTracing.title', "Creating trace file..."),
+ cancellable: false,
+ detail: localize('stopTracing.detail', "This can take up to one minute to complete.")
+ }, () => nativeHostService.stopTracing());
+ }
+}
diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts
index ad4a5fc72d3..e4b863b0b4a 100644
--- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts
+++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts
@@ -9,7 +9,7 @@ import { MenuRegistry, MenuId, registerAction2 } from '../../platform/actions/co
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../platform/configuration/common/configurationRegistry.js';
import { KeyMod, KeyCode } from '../../base/common/keyCodes.js';
import { isLinux, isMacintosh, isWindows } from '../../base/common/platform.js';
-import { ConfigureRuntimeArgumentsAction, ToggleDevToolsAction, ReloadWindowWithExtensionsDisabledAction, OpenUserDataFolderAction, ShowGPUInfoAction } from './actions/developerActions.js';
+import { ConfigureRuntimeArgumentsAction, ToggleDevToolsAction, ReloadWindowWithExtensionsDisabledAction, OpenUserDataFolderAction, ShowGPUInfoAction, StopTracing } from './actions/developerActions.js';
import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseWindowAction, SwitchWindowAction, QuickSwitchWindowAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler, ToggleWindowAlwaysOnTopAction, DisableWindowAlwaysOnTopAction, EnableWindowAlwaysOnTopAction } from './actions/windowActions.js';
import { ContextKeyExpr } from '../../platform/contextkey/common/contextkey.js';
import { KeybindingsRegistry, KeybindingWeight } from '../../platform/keybinding/common/keybindingsRegistry.js';
@@ -114,6 +114,7 @@ import { registerWorkbenchContribution2, WorkbenchPhase } from '../common/contri
registerAction2(ToggleDevToolsAction);
registerAction2(OpenUserDataFolderAction);
registerAction2(ShowGPUInfoAction);
+ registerAction2(StopTracing);
})();
// Menu
@@ -147,12 +148,7 @@ import { registerWorkbenchContribution2, WorkbenchPhase } from '../common/contri
'included': !isWindows,
'scope': ConfigurationScope.APPLICATION,
'markdownDescription': localize('application.shellEnvironmentResolutionTimeout', "Controls the timeout in seconds before giving up resolving the shell environment when the application is not already launched from a terminal. See our [documentation](https://go.microsoft.com/fwlink/?linkid=2149667) for more information.")
- },
- 'application.useNewProcessExplorer': {
- 'type': 'boolean',
- 'default': true, // TODO@bpasero remove me when done
- 'description': localize('useNewProcessExplorer', "Controls whether a the process explorer opens in a floating window."),
- },
+ }
}
});
diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/processMainService.ts b/src/vs/workbench/services/process/electron-sandbox/processService.ts
similarity index 75%
rename from src/vs/workbench/contrib/issue/electron-sandbox/processMainService.ts
rename to src/vs/workbench/services/process/electron-sandbox/processService.ts
index d2073829039..e47499664b7 100644
--- a/src/vs/workbench/contrib/issue/electron-sandbox/processMainService.ts
+++ b/src/vs/workbench/services/process/electron-sandbox/processService.ts
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { registerMainProcessRemoteService } from '../../../../platform/ipc/electron-sandbox/services.js';
-import { IProcessMainService } from '../../../../platform/process/common/process.js';
+import { IProcessService } from '../../../../platform/process/common/process.js';
-registerMainProcessRemoteService(IProcessMainService, 'process');
+registerMainProcessRemoteService(IProcessService, 'process');
diff --git a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts
index e7d0cb93e36..048a4e50179 100644
--- a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts
+++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts
@@ -149,6 +149,7 @@ export class TestNativeHostService implements INativeHostService {
async exit(code: number): Promise { }
async openDevTools(options?: Partial & INativeHostOptions | undefined): Promise { }
async toggleDevTools(): Promise { }
+ async stopTracing(): Promise { }
async openGPUInfoWindow(): Promise { }
async resolveProxy(url: string): Promise { return undefined; }
async lookupAuthorization(authInfo: AuthInfo): Promise { return undefined; }
diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts
index 3d4ab2566a9..b05c17aac15 100644
--- a/src/vs/workbench/workbench.desktop.main.ts
+++ b/src/vs/workbench/workbench.desktop.main.ts
@@ -87,6 +87,7 @@ import '../platform/userDataProfile/electron-sandbox/userDataProfileStorageServi
import './services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService.js';
import '../platform/extensionManagement/electron-sandbox/extensionsProfileScannerService.js';
import '../platform/webContentExtractor/electron-sandbox/webContentExtractorService.js';
+import './services/process/electron-sandbox/processService.js';
import { registerSingleton } from '../platform/instantiation/common/extensions.js';
import { IUserDataInitializationService, UserDataInitializationService } from './services/userData/browser/userDataInit.js';
@@ -121,8 +122,7 @@ import './contrib/extensions/electron-sandbox/extensions.contribution.js';
// Issues
import './contrib/issue/electron-sandbox/issue.contribution.js';
-// Process
-import './contrib/issue/electron-sandbox/process.contribution.js';
+// Process Explorer
import './contrib/processExplorer/electron-sandbox/processExplorer.contribution.js';
// Remote