mirror of
https://github.com/HeyPuter/puter
synced 2024-11-13 21:52:23 +00:00
fix: double-echo in phoenix
This commit is contained in:
parent
a33d721e21
commit
6bdcae769d
@ -1150,3 +1150,43 @@ This change can be made incrementally as follows:
|
||||
- update the command to use the new implementation
|
||||
- Once all commands are updated, the XDocumentPuterShell class will
|
||||
be dormant and can safely be removed.
|
||||
|
||||
## 2024-09-04
|
||||
|
||||
### Terminal I/O
|
||||
|
||||
Prior to recent changes it was not possible to run phoenix shell inside
|
||||
another instance of phoenix shell. The following had to be resolved for
|
||||
this to work:
|
||||
- Phoenix was waiting for a configuration object from the parent app,
|
||||
under the assumption that this parent app is a terminal. Phoenix now
|
||||
does not require this configuration object.
|
||||
- Initial terminal size had to be requested for by Phoenix after some
|
||||
initialization to avoid a race condition.
|
||||
- Apps called by an application under a terminal were not able to control
|
||||
`echo` behavior.
|
||||
|
||||
The new IO functionality follows the
|
||||
[Selective Layer Implementation Pattern](https://puter.com/@ed/documentation/glossary.md##Selective-Layer-Implementation-Pattern)
|
||||
with the following implemented:
|
||||
- IOCTL: `TIOCGWINSZ`, sent via postMessage
|
||||
- signal: `ioctl.set` event to simulate "SIGWINCH",
|
||||
but this should be merged with existing code that
|
||||
implements the concept of signals.
|
||||
- ptt.termios: a high-level mimic of termios
|
||||
(currently only echo control is implemented)
|
||||
|
||||
XDocumentPTT now implements `TIOCGWINSZ` (named after the POSIX equivalent)
|
||||
which requests the window size. This function calls `postMessage` on the
|
||||
AppConnection with the following
|
||||
[type-tagged object](../../../doc/api/type-tagged.md):
|
||||
`{ $: 'ioctl.request', requestCode: 104 }`.
|
||||
|
||||
The window size information is still provided
|
||||
by the badly-named `ioctl.set` event, which should later be changed to
|
||||
a similar convention, like `{ $: 'signal', code: 28 }`.
|
||||
|
||||
The termios implementation is a high-level mimic and does not actually
|
||||
use the underlying IOCTL implementation. Instead it sends a type-tagged
|
||||
object that looks like `{ $: 'chtermios', termios: { echo: false } }`,
|
||||
where `echo` can be `true` or `false`.
|
||||
|
@ -41,6 +41,18 @@ export class XDocumentPTT {
|
||||
};
|
||||
}
|
||||
|
||||
this.termios = new Proxy({}, {
|
||||
set (target, k, v) {
|
||||
terminalConnection.postMessage({
|
||||
$: 'chtermios',
|
||||
termios: {
|
||||
[k]: v,
|
||||
}
|
||||
});
|
||||
return Reflect.set(target, k, v);
|
||||
}
|
||||
});
|
||||
|
||||
this.ioctl_listeners = {};
|
||||
|
||||
this.readableStream = new ReadableStream({
|
||||
@ -91,4 +103,19 @@ export class XDocumentPTT {
|
||||
listener(evt);
|
||||
}
|
||||
}
|
||||
|
||||
once (name, listener) {
|
||||
const wrapper = evt => {
|
||||
listener(evt);
|
||||
this.off(name, wrapper);
|
||||
};
|
||||
this.on(name, wrapper);
|
||||
}
|
||||
|
||||
off (name, listener) {
|
||||
if ( ! this.ioctl_listeners.hasOwnProperty(name) ) return;
|
||||
this.ioctl_listeners[name] = this.ioctl_listeners[name].filter(
|
||||
l => l !== listener
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ export const launchPuterShell = async (ctx) => {
|
||||
|
||||
// NEXT
|
||||
ptt.TIOCGWINSZ();
|
||||
ptt.termios.echo = false;
|
||||
|
||||
const fire = (text) => {
|
||||
// Define fire-like colors (ANSI 256-color codes)
|
||||
|
@ -88,6 +88,15 @@ export class PuterAppCommandProvider {
|
||||
if (message.$ === 'stdout') {
|
||||
ctx.externs.out.write(decoder.decode(message.data));
|
||||
}
|
||||
if (message.$ === 'chtermios') {
|
||||
if ( message.termios.echo !== undefined ) {
|
||||
if ( message.termios.echo ) {
|
||||
ctx.externs.echo.on();
|
||||
} else {
|
||||
ctx.externs.echo.off();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Repeatedly copy data from stdin to the child, while it's running.
|
||||
@ -108,6 +117,7 @@ export class PuterAppCommandProvider {
|
||||
setTimeout(next_data, 0);
|
||||
}
|
||||
|
||||
// TODO: propagate sigint to the app
|
||||
return Promise.race([ app_close_promise, sigint_promise ]);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user