Skip to content

Commit e1c0ba0

Browse files
authored
Desktop SDK: set global DISPLAY env variable (#79)
* set DISPLAY global property in env * added changeset
1 parent b00403b commit e1c0ba0

3 files changed

Lines changed: 71 additions & 87 deletions

File tree

.changeset/lucky-eyes-end.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@e2b/desktop-python': patch
3+
'@e2b/desktop': patch
4+
---
5+
6+
set DISPLAY env variable on Sandbox start

packages/js-sdk/src/sandbox.ts

Lines changed: 38 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ export interface SandboxOpts extends SandboxOptsBase {
119119
export class Sandbox extends SandboxBase {
120120
protected static override readonly defaultTemplate: string = 'desktop'
121121
private lastXfce4Pid: number | null = null
122-
readonly display: string
123-
readonly stream: VNCServer
122+
public display: string = ':0'
123+
public stream: VNCServer = new VNCServer(this)
124124

125125
/**
126126
* Use {@link Sandbox.create} to create a new Sandbox instead.
@@ -131,15 +131,12 @@ export class Sandbox extends SandboxBase {
131131
* @access protected
132132
*/
133133
constructor(
134-
opts: Omit<SandboxOpts, 'timeoutMs' | 'envs' | 'metadata'> & {
134+
opts: Omit<SandboxOpts, 'timeoutMs' | 'metadata'> & {
135135
sandboxId: string
136136
envdVersion?: string
137137
}
138138
) {
139139
super(opts)
140-
this.display = opts.display || ':0'
141-
this.lastXfce4Pid = null
142-
this.stream = new VNCServer(this)
143140
}
144141
/**
145142
* Create a new sandbox from the default `desktop` sandbox template.
@@ -189,26 +186,40 @@ export class Sandbox extends SandboxBase {
189186

190187
const config = new ConnectionConfig(sandboxOpts)
191188

189+
// Add DISPLAY environment variable if not already set
190+
const display = opts?.display || ':0'
191+
const sandboxOptsWithDisplay = {
192+
...sandboxOpts,
193+
envs: {
194+
...sandboxOpts?.envs,
195+
DISPLAY: display,
196+
},
197+
}
198+
192199
let sbx
193200
if (config.debug) {
194201
sbx = new this({
195202
sandboxId: 'desktop',
196-
...sandboxOpts,
203+
...sandboxOptsWithDisplay,
197204
...config,
198205
}) as InstanceType<S>
199206
} else {
200207
const sandbox = await this.createSandbox(
201208
template,
202-
sandboxOpts?.timeoutMs ?? this.defaultSandboxTimeoutMs,
203-
sandboxOpts
209+
sandboxOptsWithDisplay?.timeoutMs ?? this.defaultSandboxTimeoutMs,
210+
sandboxOptsWithDisplay
204211
)
205212
sbx = new this({
206213
...sandbox,
207-
...sandboxOpts,
214+
...sandboxOptsWithDisplay,
208215
...config,
209216
}) as InstanceType<S>
210217
}
211218

219+
sbx.display = display
220+
sbx.lastXfce4Pid = null
221+
sbx.stream = new VNCServer(sbx)
222+
212223
const [width, height] = sandboxOpts?.resolution ?? [1024, 768]
213224
await sbx.commands.run(
214225
`Xvfb ${sbx.display} -ac -screen 0 ${width}x${height}x24 ` +
@@ -279,7 +290,6 @@ export class Sandbox extends SandboxBase {
279290
.includes('[xfce4-session] <defunct>')
280291
) {
281292
const result = await this.commands.run('startxfce4', {
282-
envs: { DISPLAY: this.display },
283293
background: true,
284294
timeoutMs: 0,
285295
})
@@ -311,9 +321,7 @@ export class Sandbox extends SandboxBase {
311321
async screenshot(format: 'stream'): Promise<ReadableStream<Uint8Array>>
312322
async screenshot(format: 'bytes' | 'blob' | 'stream' = 'bytes') {
313323
const path = `/tmp/screenshot-${generateRandomString()}.png`
314-
await this.commands.run(`scrot --pointer ${path}`, {
315-
envs: { DISPLAY: this.display },
316-
})
324+
await this.commands.run(`scrot --pointer ${path}`)
317325

318326
// @ts-expect-error
319327
const file = await this.files.read(path, { format })
@@ -329,9 +337,7 @@ export class Sandbox extends SandboxBase {
329337
await this.moveMouse(x, y)
330338
}
331339

332-
await this.commands.run('xdotool click 1', {
333-
envs: { DISPLAY: this.display },
334-
})
340+
await this.commands.run('xdotool click 1')
335341
}
336342

337343
/**
@@ -342,9 +348,7 @@ export class Sandbox extends SandboxBase {
342348
await this.moveMouse(x, y)
343349
}
344350

345-
await this.commands.run('xdotool click --repeat 2 1', {
346-
envs: { DISPLAY: this.display },
347-
})
351+
await this.commands.run('xdotool click --repeat 2 1')
348352
}
349353

350354
/**
@@ -355,9 +359,7 @@ export class Sandbox extends SandboxBase {
355359
await this.moveMouse(x, y)
356360
}
357361

358-
await this.commands.run('xdotool click 3', {
359-
envs: { DISPLAY: this.display },
360-
})
362+
await this.commands.run('xdotool click 3')
361363
}
362364

363365
/**
@@ -368,9 +370,7 @@ export class Sandbox extends SandboxBase {
368370
await this.moveMouse(x, y)
369371
}
370372

371-
await this.commands.run('xdotool click 2', {
372-
envs: { DISPLAY: this.display },
373-
})
373+
await this.commands.run('xdotool click 2')
374374
}
375375

376376
/**
@@ -383,9 +383,7 @@ export class Sandbox extends SandboxBase {
383383
amount: number = 1
384384
): Promise<void> {
385385
const button = direction === 'up' ? '4' : '5'
386-
await this.commands.run(`xdotool click --repeat ${amount} ${button}`, {
387-
envs: { DISPLAY: this.display },
388-
})
386+
await this.commands.run(`xdotool click --repeat ${amount} ${button}`)
389387
}
390388

391389
/**
@@ -394,9 +392,7 @@ export class Sandbox extends SandboxBase {
394392
* @param y - The y coordinate.
395393
*/
396394
async moveMouse(x: number, y: number): Promise<void> {
397-
await this.commands.run(`xdotool mousemove --sync ${x} ${y}`, {
398-
envs: { DISPLAY: this.display },
399-
})
395+
await this.commands.run(`xdotool mousemove --sync ${x} ${y}`)
400396
}
401397

402398
/**
@@ -405,9 +401,7 @@ export class Sandbox extends SandboxBase {
405401
async mousePress(
406402
button: 'left' | 'right' | 'middle' = 'left'
407403
): Promise<void> {
408-
await this.commands.run(`xdotool mousedown ${MOUSE_BUTTONS[button]}`, {
409-
envs: { DISPLAY: this.display },
410-
})
404+
await this.commands.run(`xdotool mousedown ${MOUSE_BUTTONS[button]}`)
411405
}
412406

413407
/**
@@ -416,9 +410,7 @@ export class Sandbox extends SandboxBase {
416410
async mouseRelease(
417411
button: 'left' | 'right' | 'middle' = 'left'
418412
): Promise<void> {
419-
await this.commands.run(`xdotool mouseup ${MOUSE_BUTTONS[button]}`, {
420-
envs: { DISPLAY: this.display },
421-
})
413+
await this.commands.run(`xdotool mouseup ${MOUSE_BUTTONS[button]}`)
422414
}
423415

424416
/**
@@ -427,9 +419,7 @@ export class Sandbox extends SandboxBase {
427419
* @throws Error if cursor position cannot be determined
428420
*/
429421
async getCursorPosition(): Promise<CursorPosition> {
430-
const result = await this.commands.run('xdotool getmouselocation', {
431-
envs: { DISPLAY: this.display },
432-
})
422+
const result = await this.commands.run('xdotool getmouselocation')
433423

434424
const match = result.stdout.match(/x:(\d+)\s+y:(\d+)/)
435425
if (!match) {
@@ -452,9 +442,7 @@ export class Sandbox extends SandboxBase {
452442
* @throws Error if screen size cannot be determined
453443
*/
454444
async getScreenSize(): Promise<ScreenSize> {
455-
const result = await this.commands.run('xrandr', {
456-
envs: { DISPLAY: this.display },
457-
})
445+
const result = await this.commands.run('xrandr')
458446

459447
const match = result.stdout.match(/(\d+x\d+)/)
460448
if (!match) {
@@ -509,8 +497,7 @@ export class Sandbox extends SandboxBase {
509497

510498
for (const chunk of chunks) {
511499
await this.commands.run(
512-
`xdotool type --delay ${options.delayInMs} ${this.quoteString(chunk)}`,
513-
{ envs: { DISPLAY: this.display } }
500+
`xdotool type --delay ${options.delayInMs} ${this.quoteString(chunk)}`
514501
)
515502
}
516503
}
@@ -526,9 +513,7 @@ export class Sandbox extends SandboxBase {
526513
key = mapKey(key)
527514
}
528515

529-
await this.commands.run(`xdotool key ${key}`, {
530-
envs: { DISPLAY: this.display },
531-
})
516+
await this.commands.run(`xdotool key ${key}`)
532517
}
533518

534519
/**
@@ -551,9 +536,7 @@ export class Sandbox extends SandboxBase {
551536
* @param ms - The amount of time to wait in milliseconds.
552537
*/
553538
async wait(ms: number): Promise<void> {
554-
await this.commands.run(`sleep ${ms / 1000}`, {
555-
envs: { DISPLAY: this.display },
556-
})
539+
await this.commands.run(`sleep ${ms / 1000}`)
557540
}
558541

559542
/**
@@ -563,7 +546,6 @@ export class Sandbox extends SandboxBase {
563546
async open(fileOrUrl: string): Promise<void> {
564547
await this.commands.run(`xdg-open ${fileOrUrl}`, {
565548
background: true,
566-
envs: { DISPLAY: this.display },
567549
})
568550
}
569551

@@ -572,9 +554,7 @@ export class Sandbox extends SandboxBase {
572554
* @returns The ID of the current window.
573555
*/
574556
async getCurrentWindowId(): Promise<string> {
575-
const result = await this.commands.run('xdotool getwindowfocus', {
576-
envs: { DISPLAY: this.display },
577-
})
557+
const result = await this.commands.run('xdotool getwindowfocus')
578558
return result.stdout.trim()
579559
}
580560

@@ -585,10 +565,7 @@ export class Sandbox extends SandboxBase {
585565
*/
586566
async getApplicationWindows(application: string): Promise<string[]> {
587567
const result = await this.commands.run(
588-
`xdotool search --onlyvisible --class ${application}`,
589-
{
590-
envs: { DISPLAY: this.display },
591-
}
568+
`xdotool search --onlyvisible --class ${application}`
592569
)
593570

594571
return result.stdout.trim().split('\n')
@@ -600,12 +577,7 @@ export class Sandbox extends SandboxBase {
600577
* @returns The title of the window.
601578
*/
602579
async getWindowTitle(windowId: string): Promise<string> {
603-
const result = await this.commands.run(
604-
`xdotool getwindowname ${windowId}`,
605-
{
606-
envs: { DISPLAY: this.display },
607-
}
608-
)
580+
const result = await this.commands.run(`xdotool getwindowname ${windowId}`)
609581

610582
return result.stdout.trim()
611583
}

0 commit comments

Comments
 (0)