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