Release Preview 20 shared desktop, Android and Sargo updates
Restore Gaia settings and media workflows, extend native network adapters, and align the APK payload. Generate French/English changelogs and website entries from the simplified JSON source. Validation: shared JS and Tundra unit tests; desktop workflows and persistence; signed APK payload parity; Sargo RAM and installed startup with boot readback. Android runtime qualification is recorded separately.
This commit is contained in:
parent
be2cdce823
commit
1311bed5e9
170 changed files with 19698 additions and 2495 deletions
36
services/input.mjs
Normal file
36
services/input.mjs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Only the bundled keyboard can edit the field reported by a content actor.
|
||||
export class Input {
|
||||
constructor(runtime) { this.runtime=runtime; this.focus=null; this.sequence=0; }
|
||||
changed(actor, state) {
|
||||
const app=this.runtime.identity(actor);
|
||||
if (!app || app.id==='keyboard') return;
|
||||
if (!state) { if(this.focus?.actor===actor) this.hide(); return; }
|
||||
this.focus={actor,state:{...state,id:++this.sequence}};
|
||||
this.runtime.broadcast('input-focus',this.focus.state,'system');
|
||||
this.runtime.broadcast('input-focus',this.focus.state,'keyboard');
|
||||
}
|
||||
hide() {
|
||||
this.focus=null;
|
||||
this.runtime.broadcast('input-focus',null,'system');
|
||||
this.runtime.broadcast('input-focus',null,'keyboard');
|
||||
}
|
||||
cleanup(actor) { if(this.focus?.actor===actor) this.hide(); }
|
||||
async request(actor, p) {
|
||||
const app=this.runtime.identity(actor);
|
||||
if (!app || !['keyboard','system'].includes(app.id)) throw Error('PERMISSION_DENIED');
|
||||
if (p.operation==='hide') { this.hide();return null; }
|
||||
if(app.id!=='keyboard') throw Error('PERMISSION_DENIED');
|
||||
if(p.operation==='state') return this.focus?.state || null;
|
||||
if(p.operation==='height') {
|
||||
if(!Number.isFinite(p.height) || p.height<0 || p.height>600) throw Error('INVALID_VALUE');
|
||||
this.runtime.broadcast('input-height',{height:p.height},'system');return null;
|
||||
}
|
||||
if(!this.focus || p.id!==this.focus.state.id) throw Error('INPUT_CONTEXT_EXPIRED');
|
||||
const context=this.focus;
|
||||
const result=await context.actor.sendQuery('Vulpes:Edit',p);
|
||||
// An application can close or focus another field while the edit is pending.
|
||||
if(this.focus!==context) throw Error('INPUT_CONTEXT_EXPIRED');
|
||||
Object.assign(context.state,result);
|
||||
return context.state;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue