pull/5370/head
filip mertens 7 months ago
parent f8d4857baa
commit 4c2aeae193
  1. 77
      apps/remixdesktop/src/plugins/xtermPlugin.ts

@ -13,8 +13,6 @@ import { findExecutable } from '../utils/findExecutable'
import { spawnSync } from 'child_process' import { spawnSync } from 'child_process'
import { stripAnsi } from '../lib' import { stripAnsi } from '../lib'
import { DataBatcher } from '../lib/databatcher' import { DataBatcher } from '../lib/databatcher'
import { Worker } from 'worker_threads'
import { utilityProcess } from 'electron'
export const detectDefaultShell = () => { export const detectDefaultShell = () => {
const { env } = process const { env } = process
@ -66,12 +64,6 @@ const parseEnv = (env: any) => {
return returnValue return returnValue
} }
export default defaultShell export default defaultShell
const profile: Profile = { const profile: Profile = {
@ -111,7 +103,7 @@ const clientProfile: Profile = {
} }
class XtermPluginClient extends ElectronBasePluginClient { class XtermPluginClient extends ElectronBasePluginClient {
terminals: Electron.UtilityProcess[] = [] terminals: pty.IPty[] = []
dataBatchers: DataBatcher[] = [] dataBatchers: DataBatcher[] = []
workingDir: string = '' workingDir: string = ''
parsedEnv: any = null parsedEnv: any = null
@ -125,18 +117,17 @@ class XtermPluginClient extends ElectronBasePluginClient {
this.workingDir = await this.call('fs' as any, 'getWorkingDir') this.workingDir = await this.call('fs' as any, 'getWorkingDir')
console.log('workingDir', this.workingDir) console.log('workingDir', this.workingDir)
}) })
if (!(process.platform === 'win32')) { if (!(process.platform === 'win32')) {
const { stdout } = spawnSync(defaultShell, getShellEnvArgs, { const { stdout } = spawnSync(defaultShell, getShellEnvArgs, {
encoding: 'utf8', encoding: 'utf8',
}) })
this.parsedEnv = parseEnv(stdout) this.parsedEnv = parseEnv(stdout)
} }
} }
async keystroke(key: string, pid: number): Promise<void> { async keystroke(key: string, pid: number): Promise<void> {
//this.terminals[pid].write(key) this.terminals[pid].write(key)
this.terminals[pid].postMessage({ type: 'write', data: key })
} }
async getShells(): Promise<string[]> { async getShells(): Promise<string[]> {
@ -157,57 +148,43 @@ class XtermPluginClient extends ElectronBasePluginClient {
async createTerminal(path?: string, shell?: string): Promise<number> { async createTerminal(path?: string, shell?: string): Promise<number> {
const start_time = Date.now() const start_time = Date.now()
return new Promise((resolve, reject) => { console.log('createTerminal', path, shell || defaultShell)
let mypy: Electron.UtilityProcess = utilityProcess.fork(__dirname + '/xtermWorker.js')
const end_time_fork = Date.now()
console.log(`fork took ${end_time_fork - start_time} ms`)
const env = this.parsedEnv || process.env
mypy.on('message', (message: any) => { const env = this.parsedEnv || process.env
//console.log('message', message)
if (message.type === 'spawned') {
const end_time_spawn = Date.now()
console.log(`spawn message took ${end_time_spawn - end_time_fork} ms`)
const pid = message.pid
const dataBatcher = new DataBatcher(pid)
this.dataBatchers[pid] = dataBatcher
dataBatcher.on('flush', (data: string, uid: number) => {
this.sendData(data, uid)
})
this.terminals[pid] = mypy
const end_time = Date.now()
console.log('spawned', pid, end_time - start_time)
resolve(pid)
}
if (message.type === 'data') {
this.dataBatchers[message.pid].write(Buffer.from(message.data))
}
if (message.type === 'exit') {
this.closeTerminal(message.pid)
}
})
mypy.postMessage({ const ptyProcess = pty.spawn(shell || defaultShell, [], {
type: 'spawn', shell, args: [], options:
{
name: 'xterm-color', name: 'xterm-color',
cols: 40, cols: 80,
rows: 10, rows: 20,
cwd: path || process.cwd(), cwd: path || process.cwd(),
env: env, env: env,
encoding: 'utf8', encoding: 'utf8',
} });
const dataBatcher = new DataBatcher(ptyProcess.pid)
this.dataBatchers[ptyProcess.pid] = dataBatcher
ptyProcess.onData((data: string) => {
//console.log('data', data)
dataBatcher.write(Buffer.from(data))
}) })
ptyProcess.onExit(() => {
const pid = ptyProcess.pid
this.closeTerminal(pid)
}) })
dataBatcher.on('flush', (data: string, uid: number) => {
this.sendData(data, uid)
})
this.terminals[ptyProcess.pid] = ptyProcess
const end_time = Date.now()
console.log('createTerminal', end_time - start_time)
return ptyProcess.pid
} }
async closeTerminal(pid: number): Promise<void> { async closeTerminal(pid: number): Promise<void> {
if (this.terminals) { if (this.terminals) {
if (this.terminals[pid]) { if (this.terminals[pid]) {
try { try {
this.terminals[pid].postMessage({ type: 'close' }) this.terminals[pid].kill()
//this.terminals[pid].kill()
} catch (err) { } catch (err) {
// ignore // ignore
} }
@ -222,7 +199,7 @@ class XtermPluginClient extends ElectronBasePluginClient {
async resize({ cols, rows }: { cols: number; rows: number }, pid: number) { async resize({ cols, rows }: { cols: number; rows: number }, pid: number) {
if (this.terminals[pid]) { if (this.terminals[pid]) {
try { try {
//this.terminals[pid].postMessage({ type: 'resize', cols, rows }) this.terminals[pid].resize(cols, rows)
} catch (_err) { } catch (_err) {
const err = _err as { stack: any } const err = _err as { stack: any }
console.error(err.stack) console.error(err.stack)
@ -234,7 +211,7 @@ class XtermPluginClient extends ElectronBasePluginClient {
async closeAll(): Promise<void> { async closeAll(): Promise<void> {
for (const pid in this.terminals) { for (const pid in this.terminals) {
this.terminals[pid].postMessage({ type: 'close' }) this.terminals[pid].kill()
delete this.terminals[pid] delete this.terminals[pid]
this.emit('close', pid) this.emit('close', pid)
} }

Loading…
Cancel
Save