"""Start an isolated window manager and a loopback-to-Unix extension proxy before Blender.""" import ctypes as C import json import os from pathlib import Path import select import socket import socketserver import subprocess import sys import threading import time import xml.etree.ElementTree as ET workspace=Path(sys.argv[1]);command=sys.argv[2:] runtime=Path(__file__).resolve().parents[2]/'build_blender_native'/'desktop-runtime' binary=runtime/'usr/bin/openbox' if not binary.is_file():raise RuntimeError('NATIVE_WINDOW_MANAGER_MISSING: run /usr/bin/python3 tools/web/prepare-native-desktop.py') class Forward(socketserver.BaseRequestHandler): def handle(self): upstream=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM) try: upstream.settimeout(15);directory=os.open(workspace,os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW) try:upstream.connect(f'/proc/self/fd/{directory}/extension-proxy.sock') finally:os.close(directory) self.request.settimeout(15) peers={self.request:upstream,upstream:self.request};deadline=time.monotonic()+240 while time.monotonic()0 if data.value:x.XFree(data) if ready:break if time.monotonic()>deadline:raise RuntimeError('NATIVE_WINDOW_MANAGER_START_TIMEOUT') time.sleep(.025) finally:x.XCloseDisplay(display) (workspace/'desktop-host.json').write_text(json.dumps({'windowManager':'Openbox','network':'REPOSITORY_HTTPS_PROXY'})) blender=subprocess.Popen(command,env=environment) sys.exit(blender.wait()) finally: if blender and blender.poll() is None:blender.terminate() wm.terminate();proxy.shutdown();proxy.server_close() try:wm.wait(timeout=2) except subprocess.TimeoutExpired:wm.kill();wm.wait()