mirror of
https://github.com/HeyPuter/puter.git
synced 2025-02-02 23:28:39 +08: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
|
- update the command to use the new implementation
|
||||||
- Once all commands are updated, the XDocumentPuterShell class will
|
- Once all commands are updated, the XDocumentPuterShell class will
|
||||||
be dormant and can safely be removed.
|
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.ioctl_listeners = {};
|
||||||
|
|
||||||
this.readableStream = new ReadableStream({
|
this.readableStream = new ReadableStream({
|
||||||
@ -91,4 +103,19 @@ export class XDocumentPTT {
|
|||||||
listener(evt);
|
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
|
// NEXT
|
||||||
ptt.TIOCGWINSZ();
|
ptt.TIOCGWINSZ();
|
||||||
|
ptt.termios.echo = false;
|
||||||
|
|
||||||
const fire = (text) => {
|
const fire = (text) => {
|
||||||
// Define fire-like colors (ANSI 256-color codes)
|
// Define fire-like colors (ANSI 256-color codes)
|
||||||
|
@ -88,6 +88,15 @@ export class PuterAppCommandProvider {
|
|||||||
if (message.$ === 'stdout') {
|
if (message.$ === 'stdout') {
|
||||||
ctx.externs.out.write(decoder.decode(message.data));
|
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.
|
// Repeatedly copy data from stdin to the child, while it's running.
|
||||||
@ -108,6 +117,7 @@ export class PuterAppCommandProvider {
|
|||||||
setTimeout(next_data, 0);
|
setTimeout(next_data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: propagate sigint to the app
|
||||||
return Promise.race([ app_close_promise, sigint_promise ]);
|
return Promise.race([ app_close_promise, sigint_promise ]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user