xterm repaint improvements (still not great)
This commit is contained in:
parent
44f79ac02a
commit
9d69ef9c57
|
@ -59,7 +59,6 @@ if( !AFRAME.components.dom ){
|
|||
.assignUniqueID()
|
||||
.scaleDOMvsXR()
|
||||
.triggerKeyboardForInputs()
|
||||
.stubRequestAnimationFrame()
|
||||
|
||||
document.querySelector('#overlay').appendChild(this.el.dom)
|
||||
this.el.emit('DOMready',{el: this.el.dom})
|
||||
|
@ -131,10 +130,5 @@ if( !AFRAME.components.dom ){
|
|||
return this
|
||||
},
|
||||
|
||||
stubRequestAnimationFrame: async function(){
|
||||
let s = await AFRAME.utils.require(this.requires)
|
||||
this.el.setAttribute("requestAnimationFrameXR","")
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
|
|
@ -38,13 +38,13 @@ if( typeof AFRAME != 'undefined '){
|
|||
rows: { type: 'number',"default": 30 },
|
||||
padding: { type: 'number',"default": 18 },
|
||||
minimized: { type: 'boolean',"default":false},
|
||||
maximized: { type: 'boolean',"default":true},
|
||||
maximized: { type: 'boolean',"default":false},
|
||||
transparent: { type:'boolean', "default":false }, // need good gpu
|
||||
xterm: { type: 'boolean', "default":true }, // use xterm.js? (=slower)
|
||||
memory: { type: 'number', "default":48 } // VM memory (in MB)
|
||||
},
|
||||
|
||||
init: async function(){
|
||||
init: function(){
|
||||
this.el.object3D.visible = false
|
||||
fetch(this.data.iso,{method: 'HEAD'})
|
||||
.then( (res) => {
|
||||
|
@ -125,6 +125,7 @@ if( typeof AFRAME != 'undefined '){
|
|||
.wb-body:has(> .isoterminal){
|
||||
background: #000C;
|
||||
overflow:hidden;
|
||||
border-radius:7px;
|
||||
}
|
||||
|
||||
.XR .wb-body:has(> .isoterminal){
|
||||
|
@ -159,6 +160,7 @@ if( typeof AFRAME != 'undefined '){
|
|||
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"
|
||||
// xterm relies on window.requestAnimationFrame which is not called in XR (xrSession.requestAnimationFrame is)
|
||||
}
|
||||
|
||||
let s = await AFRAME.utils.require(this.requires)
|
||||
|
@ -199,7 +201,6 @@ if( typeof AFRAME != 'undefined '){
|
|||
|
||||
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)
|
||||
let wb = instance.winbox
|
||||
|
@ -246,7 +247,6 @@ if( typeof AFRAME != 'undefined '){
|
|||
instance.object3D.quaternion.copy( AFRAME.scenes[0].camera.quaternion ) // face towards camera
|
||||
},
|
||||
|
||||
|
||||
events:{
|
||||
|
||||
// combined AFRAME+DOM reactive events
|
||||
|
|
|
@ -25,9 +25,30 @@ ISOTerminal.prototype.xtermInit = function(){
|
|||
term.select(0, 0, 0)
|
||||
isoterm.emit('status','copied to clipboard')
|
||||
})
|
||||
|
||||
term.onRender( () => {
|
||||
console.log("render")
|
||||
// xterm relies on requestAnimationFrame (which does not called in immersive mode)
|
||||
const _window = term._core._coreBrowserService._window
|
||||
const requestAnimationFrame = _window.requestAnimationFrame
|
||||
// luckily xterm allows a swappable window object
|
||||
let newWindow = function(){}.bind(window)
|
||||
for( var i in window ) newWindow[i] = window[i]
|
||||
newWindow.requestAnimationFrame = (cb) => {
|
||||
if( term.tid != null ) return
|
||||
setTimeout( () => {
|
||||
cb()
|
||||
term.tid = null
|
||||
},200)
|
||||
}
|
||||
term._core._coreBrowserService._window = newWindow
|
||||
|
||||
})
|
||||
|
||||
return term
|
||||
}
|
||||
|
||||
|
||||
this.addEventListener('emulator-started', function(){
|
||||
this.emulator.serial_adapter.term.element.querySelector('.xterm-viewport').style.background = 'transparent'
|
||||
// toggle immersive with ESCAPE
|
||||
|
@ -36,7 +57,9 @@ ISOTerminal.prototype.xtermInit = function(){
|
|||
|
||||
const resize = (w,h) => {
|
||||
setTimeout( () => {
|
||||
if( isoterm?.emulator?.serial_adapter?.term ){
|
||||
isoterm.xtermAutoResize(isoterm.emulator.serial_adapter.term, isoterm.instance,-3)
|
||||
}
|
||||
},800) // wait for resize anim
|
||||
}
|
||||
isoterm.instance.addEventListener('window.onresize', resize )
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* ## requestAnimationFrameXR
|
||||
*
|
||||
* reroutes requestAnimationFrame-calls to xrSession.requestAnimationFrame
|
||||
* reason: in immersive mode this function behaves differently
|
||||
* (causing HTML apps like xterm.js not getting updated due to relying
|
||||
* on window.requestAnimationFrame)
|
||||
*
|
||||
* ```html
|
||||
* <a-entity requestAnimationFrameXR dom/>
|
||||
* ```
|
||||
*/
|
||||
|
||||
if( !AFRAME.systems.requestAnimationFrameXR ){
|
||||
|
||||
AFRAME.registerSystem('requestAnimationFrameXR',{
|
||||
|
||||
init: function init(){
|
||||
if( document.location.hostname.match(/localhost/) ) return // allow webxr polyfill during development (they hang in XR)
|
||||
AFRAME.systems.requestAnimationFrameXR.q = []
|
||||
this.sceneEl.addEventListener('enter-vr', this.enable )
|
||||
this.sceneEl.addEventListener('enter-ar', this.enable )
|
||||
this.sceneEl.addEventListener('exit-vr', this.disable )
|
||||
this.sceneEl.addEventListener('exit-ar', this.disable )
|
||||
},
|
||||
|
||||
enable: function enable(){
|
||||
this.requestAnimationFrame = window.requestAnimationFrame
|
||||
// NOTE: we don't call xrSession.requestAnimationFrame directly like this:
|
||||
//
|
||||
// window.requestAnimationFrame = AFRAME.utils.throttleTick( (cb) => this.sceneEl.xrSession.requestAnimationFrame(cb), 50 )
|
||||
//
|
||||
// as that breaks webxr polyfill (for in-browser testing)
|
||||
// instead we defer calls to tick() (which is called both in XR and non-XR)
|
||||
//
|
||||
window.requestAnimationFrame = (cb) => AFRAME.systems.requestAnimationFrameXR.q.push(cb)
|
||||
const q = AFRAME.systems.requestAnimationFrameXR.q
|
||||
this.tick = AFRAME.utils.throttleTick( () => {
|
||||
while( q.length != 0 ) (q.pop())()
|
||||
},50)
|
||||
},
|
||||
|
||||
disable: function disable(){
|
||||
delete this.tick
|
||||
window.requestAnimationFrame = this.requestAnimationFrame
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
AFRAME.registerComponent('xrfragments', {
|
||||
schema: {
|
||||
url: { type:"string"}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
},
|
||||
|
||||
events:{
|
||||
|
||||
launcher: async function(){
|
||||
let url = prompt('enter URL to glb/fbx/json/obj/usdz asset', 'https://xrfragment.org/index.glb')
|
||||
if( !url ) return
|
||||
await AFRAME.utils.require({
|
||||
xrfragments: "https://xrfragment.org/dist/xrfragment.aframe.js",
|
||||
})
|
||||
|
||||
// remove objects which are marked to be removed from scene (with noxrf)
|
||||
let els = [...document.querySelectorAll('[noxrf]') ]
|
||||
els.map( (el) => el.remove() )
|
||||
|
||||
if( !this.el.getAttribute("xrf") ){
|
||||
this.el.setAttribute("xrf", url )
|
||||
let ARbutton = document.querySelector('.a-enter-ar-button')
|
||||
if( ARbutton ){
|
||||
ARbutton.addEventListener('click', () => {
|
||||
AFRAME.XRF.reset()
|
||||
})
|
||||
}
|
||||
}else AFRAME.XRF.navigator.to(url)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
manifest: { // HTML5 manifest to identify app to xrsh
|
||||
"short_name": "XRF",
|
||||
"name": "XR Fragment URL",
|
||||
"icons": [ ],
|
||||
"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 <type> [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": "Hello world information",
|
||||
"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.
|
||||
`
|
||||
}
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue