mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-02 06:14:15 +01:00
Move pty to shared process
This commit is contained in:
@@ -81,6 +81,10 @@ import { DeprecatedExtensionsCleaner } from 'vs/code/electron-browser/sharedProc
|
||||
import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { LocalPtyChannel } from 'vs/platform/terminal/electron-browser/terminalIpc';
|
||||
import { TerminalIpcChannels } from 'vs/platform/terminal/common/terminal';
|
||||
import { LocalPtyService } from 'vs/platform/terminal/electron-browser/localPtyService';
|
||||
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||
|
||||
class SharedProcessMain extends Disposable {
|
||||
|
||||
@@ -259,6 +263,10 @@ class SharedProcessMain extends Disposable {
|
||||
services.set(IUserDataSyncResourceEnablementService, new SyncDescriptor(UserDataSyncResourceEnablementService));
|
||||
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
|
||||
|
||||
// Terminal
|
||||
// TODO: Move out of electron-main
|
||||
services.set(ILocalPtyService, new SyncDescriptor(LocalPtyService));
|
||||
|
||||
return new InstantiationService(services);
|
||||
}
|
||||
|
||||
@@ -304,6 +312,11 @@ class SharedProcessMain extends Disposable {
|
||||
const userDataAutoSync = this._register(accessor.get(IInstantiationService).createInstance(UserDataAutoSyncService));
|
||||
const userDataAutoSyncChannel = new UserDataAutoSyncChannel(userDataAutoSync);
|
||||
this.server.registerChannel('userDataAutoSync', userDataAutoSyncChannel);
|
||||
|
||||
// Terminal
|
||||
const localPtyMainService = accessor.get(ILocalPtyService);
|
||||
const localPtyMainChannel = new LocalPtyChannel(localPtyMainService);
|
||||
this.server.registerChannel(TerminalIpcChannels.LocalPty, localPtyMainChannel);
|
||||
}
|
||||
|
||||
private registerErrorHandler(logService: ILogService): void {
|
||||
|
||||
@@ -89,7 +89,6 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { ILocalPtyMainService, LocalPtyMainService } from 'vs/platform/terminal/electron-main/localPtyMainService';
|
||||
|
||||
export class CodeApplication extends Disposable {
|
||||
private windowsMainService: IWindowsMainService | undefined;
|
||||
@@ -528,7 +527,6 @@ export class CodeApplication extends Disposable {
|
||||
services.set(ILaunchMainService, new SyncDescriptor(LaunchMainService));
|
||||
services.set(IDiagnosticsService, ProxyChannel.toService(getDelayedChannel(sharedProcessReady.then(client => client.getChannel('diagnostics')))));
|
||||
|
||||
services.set(ILocalPtyMainService, new SyncDescriptor(LocalPtyMainService));
|
||||
services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv]));
|
||||
services.set(IEncryptionMainService, new SyncDescriptor(EncryptionMainService, [machineId]));
|
||||
services.set(IKeyboardLayoutMainService, new SyncDescriptor(KeyboardLayoutMainService));
|
||||
@@ -616,10 +614,6 @@ export class CodeApplication extends Disposable {
|
||||
const updateChannel = new UpdateChannel(updateService);
|
||||
electronIpcServer.registerChannel('update', updateChannel);
|
||||
|
||||
const localPtyMainService = accessor.get(ILocalPtyMainService);
|
||||
const localPtyChannel = createChannelReceiver(localPtyMainService);
|
||||
electronIpcServer.registerChannel('localPty', localPtyChannel);
|
||||
|
||||
const issueMainService = accessor.get(IIssueMainService);
|
||||
const issueChannel = ProxyChannel.fromService(issueMainService);
|
||||
electronIpcServer.registerChannel('issue', issueChannel);
|
||||
|
||||
@@ -7,15 +7,19 @@ import { Event } from 'vs/base/common/event';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export interface ICommonLocalPtyService {
|
||||
export enum TerminalIpcChannels {
|
||||
LocalPty = 'localPty'
|
||||
}
|
||||
|
||||
export interface ILocalPtyService {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
readonly onProcessData: Event<{ id: number, event: IProcessDataEvent | string }>;
|
||||
readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
|
||||
readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string } }>;
|
||||
readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
|
||||
readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
|
||||
readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
|
||||
// readonly onProcessData: Event<{ id: number, event: IProcessDataEvent | string }>;
|
||||
// readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
|
||||
// readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string } }>;
|
||||
// readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
|
||||
// readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
|
||||
// readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
|
||||
|
||||
createProcess(
|
||||
shellLaunchConfig: IShellLaunchConfig,
|
||||
|
||||
+25
-30
@@ -3,37 +3,31 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ICommonLocalPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensionsOverride, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
||||
import { ILocalPtyService, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError } from 'vs/platform/terminal/common/terminal';
|
||||
import { TerminalProcess } from 'vs/platform/terminal/node/terminalProcess';
|
||||
|
||||
export const ILocalPtyMainService = createDecorator<ILocalPtyMainService>('localPtyMainService');
|
||||
|
||||
export interface ILocalPtyMainService extends ICommonLocalPtyService { }
|
||||
|
||||
let currentLocalPtyId = 0;
|
||||
|
||||
export class LocalPtyMainService extends Disposable implements ICommonLocalPtyService {
|
||||
export class LocalPtyService extends Disposable implements ILocalPtyService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _localPtys: Map<number, ITerminalChildProcess> = new Map();
|
||||
|
||||
private readonly _onProcessData = this._register(new Emitter<{ id: number, event: IProcessDataEvent | string }>());
|
||||
readonly onProcessData = this._onProcessData.event;
|
||||
private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
|
||||
readonly onProcessExit = this._onProcessExit.event;
|
||||
private readonly _onProcessReady = this._register(new Emitter<{ id: number, event: { pid: number, cwd: string } }>());
|
||||
readonly onProcessReady = this._onProcessReady.event;
|
||||
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
||||
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
||||
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
||||
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
||||
readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
|
||||
// private readonly _onProcessData = this._register(new Emitter<{ id: number, event: IProcessDataEvent | string }>());
|
||||
// readonly onProcessData = this._onProcessData.event;
|
||||
// private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
|
||||
// readonly onProcessExit = this._onProcessExit.event;
|
||||
// private readonly _onProcessReady = this._register(new Emitter<{ id: number, event: { pid: number, cwd: string } }>());
|
||||
// readonly onProcessReady = this._onProcessReady.event;
|
||||
// private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
|
||||
// readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
|
||||
// private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
|
||||
// readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
|
||||
// private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
|
||||
// readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly _logService: ILogService
|
||||
@@ -43,17 +37,18 @@ export class LocalPtyMainService extends Disposable implements ICommonLocalPtySe
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, executableEnv: IProcessEnvironment, windowsEnableConpty: boolean): Promise<number> {
|
||||
const id = ++currentLocalPtyId;
|
||||
console.log('LocalPtyMainService#createProcess ' + id, shellLaunchConfig, cwd, cols);
|
||||
const process = new TerminalProcess(shellLaunchConfig, cwd, cols, rows, env, executableEnv, windowsEnableConpty, this._logService);
|
||||
process.onProcessData(event => this._onProcessData.fire({ id, event }));
|
||||
process.onProcessExit(event => this._onProcessExit.fire({ id, event }));
|
||||
process.onProcessReady(event => this._onProcessReady.fire({ id, event }));
|
||||
process.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
|
||||
if (process.onProcessOverrideDimensions) {
|
||||
process.onProcessOverrideDimensions(event => this._onProcessOverrideDimensions.fire({ id, event }));
|
||||
}
|
||||
if (process.onProcessResolvedShellLaunchConfig) {
|
||||
process.onProcessResolvedShellLaunchConfig(event => this._onProcessResolvedShellLaunchConfig.fire({ id, event }));
|
||||
}
|
||||
// process.onProcessData(event => this._onProcessData.fire({ id, event }));
|
||||
// process.onProcessExit(event => this._onProcessExit.fire({ id, event }));
|
||||
// process.onProcessReady(event => this._onProcessReady.fire({ id, event }));
|
||||
// process.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
|
||||
// if (process.onProcessOverrideDimensions) {
|
||||
// process.onProcessOverrideDimensions(event => this._onProcessOverrideDimensions.fire({ id, event }));
|
||||
// }
|
||||
// if (process.onProcessResolvedShellLaunchConfig) {
|
||||
// process.onProcessResolvedShellLaunchConfig(event => this._onProcessResolvedShellLaunchConfig.fire({ id, event }));
|
||||
// }
|
||||
this._localPtys.set(id, process);
|
||||
return id;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { ILocalPtyService } from 'vs/platform/terminal/common/terminal';
|
||||
|
||||
export class LocalPtyChannel extends Disposable implements IServerChannel {
|
||||
constructor(
|
||||
private readonly _localPtyMainService: ILocalPtyService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
listen(_: unknown, event: string): Event<any> {
|
||||
throw new Error(`Event not found: ${event}`);
|
||||
}
|
||||
|
||||
async call(_: unknown, command: string, arg?: any): Promise<any> {
|
||||
switch (command) {
|
||||
case '$createProcess': return this._localPtyMainService.createProcess(...arg as [any, any, any, any, any, any, any]);
|
||||
case '$start': return this._localPtyMainService.start(...(arg as [any]));
|
||||
// TODO: Fill in other calls
|
||||
|
||||
default:
|
||||
throw new Error(`Call not found: ${command}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommonLocalPtyService } from 'vs/platform/terminal/common/terminal';
|
||||
import { ILocalPtyService as ICommonLocalPtyService } from 'vs/platform/terminal/common/terminal';
|
||||
|
||||
export const ILocalPtyService = createDecorator<ILocalPtyService>('localPtyService');
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ export class TerminalProcessMainProxy extends Disposable implements ITerminalChi
|
||||
@ILocalPtyService private readonly _localPtyService: ILocalPtyService
|
||||
) {
|
||||
super();
|
||||
this._localPtyService.onProcessData(e => e.id === this._localPtyId && this._onProcessData.fire(e.event));
|
||||
this._localPtyService.onProcessExit(e => e.id === this._localPtyId && this._onProcessExit.fire(e.event));
|
||||
this._localPtyService.onProcessReady(e => e.id === this._localPtyId && this._onProcessReady.fire(e.event));
|
||||
this._localPtyService.onProcessTitleChanged(e => e.id === this._localPtyId && this._onProcessTitleChanged.fire(e.event));
|
||||
this._localPtyService.onProcessOverrideDimensions(e => e.id === this._localPtyId && this._onProcessOverrideDimensions.fire(e.event));
|
||||
this._localPtyService.onProcessResolvedShellLaunchConfig(e => e.id === this._localPtyId && this._onProcessResolvedShellLaunchConfig.fire(e.event));
|
||||
// this._localPtyService.onProcessData(e => e.id === this._localPtyId && this._onProcessData.fire(e.event));
|
||||
// this._localPtyService.onProcessExit(e => e.id === this._localPtyId && this._onProcessExit.fire(e.event));
|
||||
// this._localPtyService.onProcessReady(e => e.id === this._localPtyId && this._onProcessReady.fire(e.event));
|
||||
// this._localPtyService.onProcessTitleChanged(e => e.id === this._localPtyId && this._onProcessTitleChanged.fire(e.event));
|
||||
// this._localPtyService.onProcessOverrideDimensions(e => e.id === this._localPtyId && this._onProcessOverrideDimensions.fire(e.event));
|
||||
// this._localPtyService.onProcessResolvedShellLaunchConfig(e => e.id === this._localPtyId && this._onProcessResolvedShellLaunchConfig.fire(e.event));
|
||||
}
|
||||
|
||||
start(): Promise<ITerminalLaunchError | { remoteTerminalId: number; } | undefined> {
|
||||
|
||||
@@ -1,18 +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 { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
|
||||
// @ts-ignore: interface is implemented via proxy
|
||||
export class LocalPtyService implements ILocalPtyService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
constructor(@IMainProcessService mainProcessService: IMainProcessService) {
|
||||
return createChannelSender<ILocalPtyService>(mainProcessService.getChannel('localPty'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||
import { IShellLaunchConfig, ITerminalLaunchError, TerminalIpcChannels } from 'vs/platform/terminal/common/terminal';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/sharedProcessService';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
|
||||
export class LocalPtyServiceProxy implements ILocalPtyService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly _channel: IChannel;
|
||||
|
||||
constructor(
|
||||
@ISharedProcessService sharedProcessService: ISharedProcessService
|
||||
) {
|
||||
this._channel = sharedProcessService.getChannel(TerminalIpcChannels.LocalPty);
|
||||
}
|
||||
|
||||
// onProcessData: Event<{ id: number; event: string | IProcessDataEvent; }>;
|
||||
// onProcessExit: Event<{ id: number; event: number | undefined; }>;
|
||||
// onProcessReady: Event<{ id: number; event: { pid: number; cwd: string; }; }>;
|
||||
// onProcessTitleChanged: Event<{ id: number; event: string; }>;
|
||||
// onProcessOverrideDimensions: Event<{ id: number; event: ITerminalDimensionsOverride | undefined; }>;
|
||||
// onProcessResolvedShellLaunchConfig: Event<{ id: number; event: IShellLaunchConfig; }>;
|
||||
|
||||
createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, executableEnv: IProcessEnvironment, windowsEnableConpty: boolean): Promise<number> {
|
||||
return this._channel.call('$createProcess', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
start(id: number): Promise<ITerminalLaunchError | { remoteTerminalId: number; } | undefined> {
|
||||
return this._channel.call('$start', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
shutdown(id: number, immediate: boolean): Promise<void> {
|
||||
return this._channel.call('$shutdown', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
input(id: number, data: string): Promise<void> {
|
||||
return this._channel.call('$input', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
resize(id: number, cols: number, rows: number): Promise<void> {
|
||||
return this._channel.call('$resize', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
acknowledgeDataEvent(id: number, charCount: number): Promise<void> {
|
||||
return this._channel.call('$acknowledgeDataEvents', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
getInitialCwd(id: number): Promise<string> {
|
||||
return this._channel.call('$getInitialCwd', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
getCwd(id: number): Promise<string> {
|
||||
return this._channel.call('$getCwd', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
getLatency(id: number): Promise<number> {
|
||||
return this._channel.call('$getLatency', Array.prototype.slice.call(arguments));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
|
||||
import { LocalPtyService } from 'vs/workbench/contrib/terminal/electron-sandbox/localPtyService';
|
||||
import { LocalPtyServiceProxy } from 'vs/workbench/contrib/terminal/electron-sandbox/localPtyServiceProxy';
|
||||
|
||||
registerSingleton(ILocalPtyService, LocalPtyService, true);
|
||||
registerSingleton(ILocalPtyService, LocalPtyServiceProxy, true);
|
||||
|
||||
Reference in New Issue
Block a user