diff --git a/com/codemirror.js b/com/codemirror.js
new file mode 100644
index 0000000..0d36726
--- /dev/null
+++ b/com/codemirror.js
@@ -0,0 +1,120 @@
+AFRAME.registerComponent('codemirror', {
+ schema: {
+ foo: { type:"string"}
+ },
+
+ init: function () {
+ this.el.object3D.visible = false
+ //this.el.innerHTML = ` `
+ this.requireAll()
+ },
+
+ requireAll: async function(){
+ let s = await AFRAME.utils.require(this.requires)
+ setTimeout( () => this.el.setAttribute("dom",""), 300 )
+ },
+
+ requires:{
+ window: "com/window.js",
+ htmltexture: "com/html-as-texture-in-xr.js",
+ codemirror: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js",
+ codemirrorcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css",
+ cmtheme: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css"
+ },
+
+ dom: {
+ scale: 0.5,
+ events: ['click','keydown'],
+ html: (me) => `
+
`,
+
+ css: (me) => `.codemirror{
+ width:100%;
+ }
+ .wb-body + .codemirror{ overflow:hidden; }
+ .CodeMirror {
+ margin-top:18px;
+ }
+ .cm-s-shadowfox.CodeMirror {
+ background:transparent !important;
+ }
+ `
+ },
+
+ events:{
+
+ // component events
+ DOMready: function(e){
+ console.log(`title: codemirror; uid: ${this.el.dom.id}; attach: #overlay; dom: #${this.el.dom.id};`)
+ this.el.setAttribute("window", `title: codemirror; uid: ${this.el.dom.id}; attach: #overlay; dom: #${this.el.dom.id};`)
+ this.el.setAttribute("html-as-texture-in-xr", `domid: #${this.el.dom.id}`) // only show aframe-html in xr
+ this.editor = CodeMirror( this.el.dom, {
+ value: "function myScript(){return 100;}\n",
+ mode: "javascript",
+ lineNumbers: true,
+ styleActiveLine: true,
+ matchBrackets: true,
+ Tab: "indentMore",
+ defaultTab: function(cm) {
+ if (cm.somethingSelected()) cm.indentSelection("add");
+ else cm.replaceSelection(" ", "end");
+ }
+ })
+ this.editor.setOption("theme", "shadowfox")
+ },
+ },
+
+
+ manifest: { // HTML5 manifest to identify app to xrsh
+ "short_name": "Paste",
+ "name": "Paste",
+ "icons": [
+ {
+ "src": "https://css.gg/clipboard.svg",
+ "type": "image/svg+xml",
+ "sizes": "512x512"
+ }
+ ],
+ "id": "/?source=pwa",
+ "start_url": "/?source=pwa",
+ "background_color": "#3367D6",
+ "display": "standalone",
+ "scope": "/",
+ "theme_color": "#3367D6",
+ "shortcuts": [
+ {
+ "name": "What is the latest news?",
+ "cli":{
+ "usage": "helloworld [options]",
+ "example": "helloworld news",
+ "args":{
+ "--latest": {type:"string"}
+ }
+ },
+ "short_name": "Today",
+ "description": "View weather information for today",
+ "url": "/today?source=pwa",
+ "icons": [{ "src": "/images/today.png", "sizes": "192x192" }]
+ }
+ ],
+ "description": "Paste the clipboard",
+ "screenshots": [
+ {
+ "src": "/images/screenshot1.png",
+ "type": "image/png",
+ "sizes": "540x720",
+ "form_factor": "narrow"
+ }
+ ],
+ "help":`
+Helloworld application
+
+This is a help file which describes the application.
+It will be rendered thru troika text, and will contain
+headers based on non-punctualized lines separated by linebreaks,
+in above's case "\nHelloworld application\n" will qualify as header.
+ `
+ }
+
+});
+
diff --git a/com/isoterminal.js b/com/isoterminal.js
index c943522..77dd088 100644
--- a/com/isoterminal.js
+++ b/com/isoterminal.js
@@ -1,7 +1,9 @@
-function ISOTerminal(){
+function ISOTerminal(instance,opts){
// create a neutral isoterminal object which can be decorated
// with prototype functions and has addListener() and dispatchEvent()
- let obj = new EventTarget()
+ let obj = new EventTarget()
+ obj.instance = instance
+ obj.opts = opts
// register default event listeners (enable file based features like isoterminal/jsconsole.js e.g.)
for( let event in ISOTerminal.listener )
for( let cb in ISOTerminal.listener[event] )
@@ -30,12 +32,16 @@ if( typeof AFRAME != 'undefined '){
AFRAME.registerComponent('isoterminal', {
schema: {
- iso: { type:"string", "default":"com/isoterminal/images/buildroot-bzimage.bin" },
- cols: { type: 'number',"default": 120 },
- rows: { type: 'number',"default": 30 },
- padding:{ type: 'number',"default": 18 },
- transparent: { type:'boolean', "default":false } // need good gpu
- },
+ iso: { type:"string", "default":"com/isoterminal/images/buildroot-bzimage.bin" },
+ overlayfs: { type:"string"},
+ cols: { type: 'number',"default": 120 },
+ rows: { type: 'number',"default": 30 },
+ padding: { type: 'number',"default": 18 },
+ maximized: { type: 'boolean',"default":true},
+ transparent: { type:'boolean', "default":false }, // need good gpu
+ xterm: { type: 'boolean', "default":true }, // use xterm.js (slower)
+ memory: { type: 'number', "default":32 } // VM memory (in MB)
+ },
init: async function(){
this.el.object3D.visible = false
@@ -45,8 +51,6 @@ if( typeof AFRAME != 'undefined '){
requires:{
com: "com/dom.js",
window: "com/window.js",
- xtermjs: "https://unpkg.com/@xterm/xterm@5.5.0/lib/xterm.js",
- xtermcss: "https://unpkg.com/@xterm/xterm@5.5.0/css/xterm.css",
v86: "com/isoterminal/libv86.js",
// allow xrsh to selfcontain scene + itself
xhook: "https://jpillora.com/xhook/dist/xhook.min.js",
@@ -57,16 +61,20 @@ if( typeof AFRAME != 'undefined '){
core: "com/isoterminal/core.js",
utils_9p: "com/isoterminal/feat/9pfs_utils.js",
boot: "com/isoterminal/feat/boot.js",
- xterm: "com/isoterminal/feat/xterm.js",
jsconsole: "com/isoterminal/feat/jsconsole.js",
javascript: "com/isoterminal/feat/javascript.js",
- index: "com/isoterminal/feat/index.html.js",
+ indexhtml: "com/isoterminal/feat/index.html.js",
+ indexjs: "com/isoterminal/feat/index.js.js",
},
dom: {
scale: 0.5,
events: ['click','keydown'],
- html: (me) => ``,
+ html: (me) => ``,
css: (me) => `.isoterminal{
padding: ${me.com.data.padding}px;
@@ -77,7 +85,9 @@ if( typeof AFRAME != 'undefined '){
white-space: pre;
font-size: 14px;
font-family: Liberation Mono,DejaVu Sans Mono,Courier New,monospace;
- font-weight:700;
+ font-weight:900 !important;
+ letter-spacing: 0 !important;
+ line-height:16px;
display:inline;
overflow: hidden;
}
@@ -85,7 +95,7 @@ if( typeof AFRAME != 'undefined '){
.isoterminal style{ display:none }
.wb-body:has(> .isoterminal){
- background: #000F;
+ background: #000C;
overflow:hidden;
}
@@ -113,6 +123,12 @@ if( typeof AFRAME != 'undefined '){
initTerminal: async function(singleton){
+ if( this.data.xterm ){
+ this.requires.xtermjs = "https://unpkg.com/@xterm/xterm@5.5.0/lib/xterm.js"
+ this.requires.xtermcss = "https://unpkg.com/@xterm/xterm@5.5.0/css/xterm.css"
+ this.requires.xterm = "com/isoterminal/feat/xterm.js"
+ }
+
let s = await AFRAME.utils.require(this.requires)
this.el.setAttribute("selfcontainer","")
@@ -132,10 +148,13 @@ if( typeof AFRAME != 'undefined '){
}
// init isoterminal
- this.isoterminal = new ISOTerminal()
+ this.isoterminal = new ISOTerminal(instance,this.data)
instance.addEventListener('DOMready', () => {
- instance.setAttribute("window", `title: xrsh [booting linux iso..]; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}`)
+ //instance.winbox.resize(720,380)
+ let size = this.data.xterm ? 'width: 1024px; height:600px'
+ : 'width: 720px; height:455px'
+ instance.setAttribute("window", `title: xrsh.iso; uid: ${instance.uid}; attach: #overlay; dom: #${instance.dom.id}; ${size}`)
})
instance.addEventListener('window.oncreate', (e) => {
@@ -146,9 +165,18 @@ if( typeof AFRAME != 'undefined '){
this.isoterminal.runISO(opts)
})
- this.isoterminal.addEventListener('ready', function(e){
+ instance.setAttribute("dom", "")
+
+
+ this.isoterminal.addEventListener('postReady', (e)=>{
+ // bugfix: send window dimensions to xterm (xterm.js does that from dom-sizechange to xterm via escape codes)
+ if( this.data.maximized ) instance.winbox.maximize()
+ else instance.winbox.resize()
+ })
+
+ this.isoterminal.addEventListener('ready', (e)=>{
instance.dom.classList.remove('blink')
- instance.winbox.maximize()
+ this.isoterminal.emit('status',"running")
setTimeout( () => { // important: after window maximize animation to get true size
instance.setAttribute("html-as-texture-in-xr", `domid: #${instance.uid}`) // only show aframe-html in xr
},1500)
@@ -159,34 +187,26 @@ if( typeof AFRAME != 'undefined '){
const w = instance.winbox
if(!w) return
w.titleBak = w.titleBak || w.title
- instance.winbox.setTitle( `${w.titleBak} [${msg}]` )
+ w.setTitle( `${w.titleBak} [${msg}]` )
})
instance.addEventListener('window.onclose', (e) => {
if( !confirm('do you want to kill this virtual machine and all its processes?') ) e.halt = true
})
- const resize = (w,h) => {
- if( this.isoterminal.emulator && this.isoterminal.emulator.serial_adapter ){
- setTimeout( () => {
- this.isoterminal.xtermAutoResize(this.isoterminal.emulator.serial_adapter.term,instance,-5)
- },800) // wait for resize anim
- }
- }
+ const resize = (w,h) => { }
instance.addEventListener('window.onresize', resize )
instance.addEventListener('window.onmaximize', resize )
- instance.setAttribute("dom", "")
-
- const focus = () => {
+ const focus = (e) => {
if( this.isoterminal?.emulator?.serial_adapter?.focus ){
this.isoterminal.emulator.serial_adapter.term.focus()
}
}
- instance.addEventListener('obbcollisionstarted', focus )
+ //instance.addEventListener('obbcollisionstarted', focus )
this.el.sceneEl.addEventListener('enter-vr', focus )
this.el.sceneEl.addEventListener('enter-ar', focus )
-
+
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
},
diff --git a/com/isoterminal/core.js b/com/isoterminal/core.js
index 1b3e97e..790be71 100644
--- a/com/isoterminal/core.js
+++ b/com/isoterminal/core.js
@@ -2,8 +2,23 @@
// // exec(['lua'] "print \"hello\") ---> cat /dev/browser/js/stdin | lua > /dev/browser/js/stdout
//}
-ISOTerminal.prototype.send = function(ttyNr, str){
- this.toUint8Array( str ).map( (c) => this.emulator.bus.send(`serial${ttyNr}-input`, c ) )
+ISOTerminal.prototype.serial_input = undefined; // can be set to 0,1,2,3 to define stdinput tty (xterm plugin)
+
+ISOTerminal.prototype.exec = function(shellscript){
+ //let ts = String(Date.now())+".job"
+ //this.emulator.create_file(ts, this.toUint8Array(shellscript) )
+ this.send(shellscript+"\n",1)
+}
+
+ISOTerminal.prototype.send = function(str, ttyNr){
+ if( !ttyNr ) ttyNr = this.serial_input
+ if( !ttyNr ){
+ if( this.emulator.serial_adapter ){
+ this.emulator.serial_adapter.term.paste(str)
+ }else this.emulator.keyboard_send_text(str) // vga screen
+ }else{
+ this.toUint8Array( str ).map( (c) => this.emulator.bus.send(`serial${ttyNr}-input`, c ) )
+ }
}
ISOTerminal.prototype.toUint8Array = function(str) {
@@ -19,28 +34,31 @@ ISOTerminal.prototype.toUint8Array = function(str) {
},
ISOTerminal.prototype.runISO = function(opts){
- this.opts = opts
+
+ let me = this
+ this.opts = {...this.opts, ...opts}
let image = {}
if( opts.iso.match(/\.iso$/) ) image.cdrom = { url: opts.iso }
if( opts.iso.match(/\.bin$/) ) image.bzimage = { url: opts.iso }
- let emulator = this.emulator = new V86({ ...image,
+ opts = { ...image,
uart1:true, // /dev/ttyS1
uart2:true, // /dev/ttyS2
uart3:true, // /dev/ttyS3
wasm_path: "com/isoterminal/v86.wasm",
- memory_size: 32 * 1024 * 1024,
- vga_memory_size: 2 * 1024 * 1024,
- serial_container_xtermjs: opts.dom,
- //screen_container: dom, //this.canvas.parentElement,
+ memory_size: opts.memory * 1024 * 1024,
+ vga_memory_size: 1024, //2 * 1024 * 1024,
+ screen_container: opts.dom,
+ //serial_container: opts.dom,
bios: {
url: "com/isoterminal/bios/seabios.bin",
},
vga_bios: {
url: "com/isoterminal/bios/vgabios.bin",
+ //urg|: "com/isoterminal/bios/VGABIOS-lgpl-latest.bin",
},
network_relay_url: "wss://relay.widgetry.org/",
- cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_free=on",
+ cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_freg|=on vga=ask", //vga=0x122",
//bzimage_initrd_from_filesystem: true,
//filesystem: {
// baseurl: "com/isoterminal/v86/images/alpine-rootfs-flat",
@@ -50,8 +68,9 @@ ISOTerminal.prototype.runISO = function(opts){
//disable_jit: false,
filesystem: {},
autostart: true,
- });
-
+ };
+ this.emit('runISO',opts)
+ let emulator = this.emulator = new V86(opts)
const loading = [
'loading quantum bits and bytes',
@@ -77,51 +96,39 @@ ISOTerminal.prototype.runISO = function(opts){
'Transcending earthly limits'
]
- let loadmsg = loading[ Math.floor(Math.random()*1000) % loading.length-1 ]
+ let loadmsg = loading[ Math.floor(Math.random()*1000) % loading.length ]
this.emit('status',loadmsg)
// replace welcome message https://github.com/copy/v86/blob/3c77b98bc4bc7a5d51a2056ea73d7666ca50fc9d/src/browser/serial.js#L231
let welcome = "This is the serial console. Whatever you type or paste here will be sent to COM1"
-
let motd = "\r[38;5;129m"
let msg = `${loadmsg}, please wait..`
while( msg.length < welcome.length ) msg += " "
msg += "\n"
- motd += msg+"\033[0m"
-
- const files = [
- "com/isoterminal/mnt/js",
- "com/isoterminal/mnt/jsh",
- "com/isoterminal/mnt/xrsh",
- "com/isoterminal/mnt/profile",
- "com/isoterminal/mnt/profile.sh",
- "com/isoterminal/mnt/profile.xrsh",
- "com/isoterminal/mnt/profile.js",
- "com/isoterminal/mnt/motd",
- "com/isoterminal/mnt/v86pipe"
- ]
+ motd += msg+"\033[0m"
emulator.bus.register("emulator-started", async (e) => {
this.emit('emulator-started',e)
- emulator.serial_adapter.term.clear()
- emulator.serial_adapter.term.write(motd)
- let p = files.map( (f) => fetch(f) )
- Promise.all(p)
- .then( (files) => {
- files.map( (f) => {
+ if( emulator.serial_adapter ){
+ emulator.serial_adapter.term.clear()
+ emulator.serial_adapter.term.write(motd)
+ }
+
+
+ if( me.opts.overlayfs ){
+ fetch(me.opts.overlayfs)
+ .then( (f) => {
f.arrayBuffer().then( (buf) => {
- emulator.create_file( f.url.replace(/.*mnt\//,''), new Uint8Array(buf) )
+ emulator.create_file('overlayfs.zip', new Uint8Array(buf) )
})
})
- })
+ }
- //emulator.serial0_send('chmod +x /mnt/js')
- //emulator.serial0_send()
let line = ''
let ready = false
- emulator.add_listener("serial0-output-byte", async (byte) => {
- this.emit('serial0-output-byte',byte)
+ emulator.add_listener(`serial0-output-byte`, async (byte) => {
+ this.emit('${this.serial}-output-byte',byte)
var chr = String.fromCharCode(byte);
if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~")
{
@@ -137,12 +144,10 @@ ISOTerminal.prototype.runISO = function(opts){
{
line += chr;
}
-
- if( !ready && line.match(/^(\/ #|~%)/) ){
- this.emit('ready')
+ if( !ready && line.match(/^(\/ #|~%|\[.*\]>)/) ){
+ this.emit('postReady')
+ setTimeout( () => this.emit('ready'), 500 )
ready = true
- //emulator.serial0_send("root\n")
- //emulator.serial0_send("mv /mnt/js . && chmod +x js\n")
}
});
});
diff --git a/com/isoterminal/feat/boot.js b/com/isoterminal/feat/boot.js
index d0c0ad5..357c1af 100644
--- a/com/isoterminal/feat/boot.js
+++ b/com/isoterminal/feat/boot.js
@@ -10,12 +10,15 @@ ISOTerminal.prototype.boot = async function(){
env.push( 'export '+String(i).toUpperCase()+'="'+document.location[i]+'"')
}
await this.emulator.create_file("profile.browser", this.toUint8Array( env.join('\n') ) )
- let boot = `clear ; echo 'preparing xrsh env..'; source /mnt/profile`
- // exec hash as extra boot cmd
- if( document.location.hash.length > 1 ){
- boot += ` ; cmd='${decodeURI(document.location.hash.substr(1))}' && $cmd`
+ if( this.serial_input == 0 ){
+ let boot = "source /etc/profile\n"
+ this.send(boot+"\n")
+ }
+
+ if( this.emulator.serial_adapter ) this.emulator.serial_adapter.term.focus()
+ else{
+ let els = [...document.querySelectorAll("div#screen")]
+ els.map( (el) => el.focus() )
}
- this.emulator.serial0_send(boot+"\n")
- this.emulator.serial_adapter.term.focus()
}
diff --git a/com/isoterminal/feat/index.html.js b/com/isoterminal/feat/index.html.js
index c6765aa..b36220c 100644
--- a/com/isoterminal/feat/index.html.js
+++ b/com/isoterminal/feat/index.html.js
@@ -1,10 +1,29 @@
-ISOTerminal.addEventListener('ready', function(){
- this.addEventListener('file-read', (e) => {
- const data = e.detail
- if( data.file == 'index.html'){
- data.promise = new Promise( (resolve,reject) => {
- resolve( this.toUint8Array(document.documentElement.outerHTML) )
- })
- }
- })
+ISOTerminal.addEventListener('init', function(){
+
+ this.addEventListener('emulator-started', function(e){
+
+ const emulator = this.emulator
+
+ // unix to js device
+ this.readFromPipe( '/mnt/index.html', async (data) => {
+ const buf = await emulator.read_file("index.html")
+ const decoder = new TextDecoder('utf-8');
+ const html = decoder.decode(buf)
+ try{
+ let $scene = document.querySelector("a-scene")
+ let $root = document.querySelector("a-entity#root")
+ if( !$root ){
+ $root = document.createElement("a-entity")
+ $root.id = "root"
+ $scene.appendChild($root)
+ }
+ $root.innerHTML = html
+ }catch(e){
+ console.error(e)
+ }
+ })
+
+ })
+
})
+
diff --git a/com/isoterminal/feat/index.js.js b/com/isoterminal/feat/index.js.js
new file mode 100644
index 0000000..4482d0e
--- /dev/null
+++ b/com/isoterminal/feat/index.js.js
@@ -0,0 +1,28 @@
+ISOTerminal.addEventListener('init', function(){
+
+ this.addEventListener('emulator-started', function(e){
+
+ const emulator = this.emulator
+
+ // unix to js device
+ this.readFromPipe( '/mnt/index.js', async (data) => {
+ const buf = await emulator.read_file("index.js")
+ const decoder = new TextDecoder('utf-8');
+ const js = decoder.decode(buf)
+ try{
+ let $root = document.querySelector("script#root")
+ if( !$root ){
+ $root = document.createElement("script")
+ $root.id = "root"
+ document.body.appendChild($root)
+ }
+ $root.innerHTML = js
+ }catch(e){
+ console.error(e)
+ }
+ })
+
+ })
+
+})
+
diff --git a/com/isoterminal/feat/javascript.js b/com/isoterminal/feat/javascript.js
index 0b4ad67..960918f 100644
--- a/com/isoterminal/feat/javascript.js
+++ b/com/isoterminal/feat/javascript.js
@@ -6,7 +6,7 @@ ISOTerminal.addEventListener('init', function(){
// unix to js device
this.readFromPipe( '/mnt/js', async (data) => {
- const buf = await emulator.read_file("dev/browser/js")
+ const buf = await emulator.read_file("js")
const decoder = new TextDecoder('utf-8');
const script = decoder.decode(buf)
let PID="?"
diff --git a/com/isoterminal/feat/jsconsole.js b/com/isoterminal/feat/jsconsole.js
index 1986339..84c6dfa 100644
--- a/com/isoterminal/feat/jsconsole.js
+++ b/com/isoterminal/feat/jsconsole.js
@@ -30,14 +30,12 @@ ISOTerminal.addEventListener('emulator-started', function(){
let emulator = this.emulator
this.redirectConsole( (str,prefix) => {
- if( emulator.log_to_tty ){
- prefix = prefix ? prefix+' ' : ' '
- str.trim().split("\n").map( (line) => {
- emulator.serial_adapter.term.write( '\r\x1b[38;5;165m/dev/browser: \x1b[0m'+prefix+line+'\n' )
- })
- emulator.serial_adapter.term.write( '\r' )
- }
- emulator.fs9p.append_file( "console", str )
+ let finalStr = ""
+ prefix = prefix ? prefix+' ' : ' '
+ str.trim().split("\n").map( (line) => {
+ finalStr += '\x1b[38;5;165m/dev/browser: \x1b[0m'+prefix+line+'\n'
+ })
+ emulator.fs9p.append_file( "console", finalStr )
})
window.addEventListener('error', function(event) {
diff --git a/com/isoterminal/feat/screenbuttons.js b/com/isoterminal/feat/screenbuttons.js
new file mode 100644
index 0000000..595b28e
--- /dev/null
+++ b/com/isoterminal/feat/screenbuttons.js
@@ -0,0 +1,13 @@
+ISOTerminal.addEventListener('ready', function(){
+ this.screenButtonsCreate()
+})
+
+ISOTerminal.prototype.screenButtonsCreate = function(){
+ let el = document.createElement("a-plane")
+ el.setAttribute("height","1")
+ el.setAttribute("width","1")
+ el.setAttribute("scale","0.1 0.07 1")
+ el.setAttribute("position", "-0.326 -0.270 0")
+ this.instance.appendChild(el)
+}
+
diff --git a/com/isoterminal/feat/xterm.js b/com/isoterminal/feat/xterm.js
index 9df0d3f..6342887 100644
--- a/com/isoterminal/feat/xterm.js
+++ b/com/isoterminal/feat/xterm.js
@@ -2,7 +2,14 @@ ISOTerminal.addEventListener('init', function(){
if( typeof Terminal != 'undefined' ) this.xtermInit()
})
+ISOTerminal.addEventListener('runISO', function(e){
+ let opts = e.detail
+ opts.serial_container_xtermjs = opts.screen_container
+ delete opts.screen_container
+})
+
ISOTerminal.prototype.xtermInit = function(){
+ this.serial_input = 0 // set input to serial line 0
let isoterm = this
// monkeypatch Xterm (which V86 initializes) so we can add our own constructor args
window._Terminal = window.Terminal
@@ -11,7 +18,8 @@ ISOTerminal.prototype.xtermInit = function(){
cursorBlink:true,
onSelectionChange: function(e){
debugger
- }
+ },
+ letterSpacing: 0
})
term.onSelectionChange( () => {
@@ -27,6 +35,14 @@ ISOTerminal.prototype.xtermInit = function(){
// toggle immersive with ESCAPE
//document.body.addEventListener('keydown', (e) => e.key == 'Escape' && this.emulator.serial_adapter.term.blur() )
})
+
+ const resize = (w,h) => {
+ setTimeout( () => {
+ isoterm.xtermAutoResize(isoterm.emulator.serial_adapter.term, isoterm.instance,-2)
+ },800) // wait for resize anim
+ }
+ isoterm.instance.addEventListener('window.onresize', resize )
+ isoterm.instance.addEventListener('window.onmaximize', resize )
}
ISOTerminal.prototype.xtermAutoResize = function(term,instance,rowoffset){
diff --git a/com/isoterminal/mnt/xrsh b/com/isoterminal/mnt/xrsh
deleted file mode 100755
index f3867e8..0000000
--- a/com/isoterminal/mnt/xrsh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/sh
-#
-# a minimalistic terminal muxer
-
-# Save the original stdout and stderr file descriptors for later restoration
-exec 3>&1 4>&2
-
-# Function to check if a session is already running on the given VT
-is_session_running() {
- vt_number=$1
-
- # Check if any process is running on /dev/tty
- fuser /dev/tty"$vt_number" >/dev/null 2>&1
- return $?
-}
-
-# Function to mute the output of a session
-mute_session() {
- vt_number=$1
- if is_session_running "$vt_number"; then
- # Redirect stdout and stderr of the session to /dev/null
- exec > /dev/null 2>&1
- fi
-}
-
-# Function to unmute the current session (restore stdout and stderr)
-unmute_session() {
- exec 1>&3 2>&4 # Restore stdout and stderr from file descriptors 3 and 4
-}
-
-# Function to start a new session if not already running
-start_or_switch_session() {
- vt_number=$1
-
- # Mute all other sessions except the one we're switching to
- for vt in $(seq 1 12); do # Assuming you have up to 12 VTs, adjust as needed
- if [ "$vt" != "$vt_number" ]; then
- mute_session "$vt"
- fi
- done
-
- if is_session_running "$vt_number"; then
- echo "Switching to existing session on VT$vt_number"
- unmute_session # Unmute the session we're switching to
- chvt "$vt_number"
- else
- echo "Starting a new session on VT$vt_number"
- openvt -c "$vt_number" -- /bin/sh &
- sleep 1 # Give the session a moment to start
- unmute_session # Unmute the new session
- chvt "$vt_number"
- fi
-}
-
-# Ensure a session number is provided
-if [ "$#" -ne 1 ]; then
- echo "Usage: $0 "
- exit 1
-fi
-
-# Start or switch to the session
-start_or_switch_session $1
diff --git a/com/window.js b/com/window.js
index 846d8d6..f6d6d1d 100644
--- a/com/window.js
+++ b/com/window.js
@@ -1,13 +1,14 @@
AFRAME.registerComponent('window', {
schema:{
- title: {type:'string',"default":"title"},
- width: {type:'string'}, // wrap
- height: {type:'string',"default":'260px'},
- uid: {type:'string'},
- attach: {type:'selector'},
- dom: {type:'selector'},
- x: {type:'string',"default":"center"},
- y: {type:'string',"default":"center"}
+ title: {type:'string',"default":"title"},
+ width: {type:'string'}, // wrap
+ height: {type:'string',"default":'260px'},
+ uid: {type:'string'},
+ attach: {type:'selector'},
+ dom: {type:'selector'},
+ max: {type:'boolean',"default":false},
+ x: {type:'string',"default":"center"},
+ y: {type:'string',"default":"center"}
},
dependencies:{
@@ -33,13 +34,14 @@ AFRAME.registerComponent('window', {
id: this.data.uid || String(Math.random()).substr(4), // important hint for html-mesh
root: this.data.attach || document.body,
mount: this.data.dom,
+ max: this.data.max,
onresize: () => this.el.emit('window.onresize',{}),
onmaximize: () => this.el.emit('window.onmaximize',{}),
- oncreate: () => {
+ oncreate: (e) => {
this.el.emit('window.oncreate',{})
// resize after the dom content has been rendered & updated
setTimeout( () => {
- winbox.resize( this.el.dom.offsetWidth+'px', this.el.dom.offsetHeight+'px' )
+ if( !this.data.max ) winbox.resize( this.el.dom.offsetWidth+'px', this.el.dom.offsetHeight+'px' )
// hint grabbable's obb-collider to track the window-object
this.el.components['obb-collider'].data.trackedObject3D = 'components.html.el.object3D.children.0'
this.el.components['obb-collider'].update()