fix: terminal input reaches the shell in the order it was typed
This commit is contained in:
1 parent
cb2673d941
commit
225b7ecfcc
3 files changed
+56
-7
No files matched your search
@@ -162,11 +162,42 @@
|
||||
term.write('\r\n\x1b[33m' + msg + '\x1b[0m\r\n');
|
||||
}
|
||||
|
||||
function send(data) {
|
||||
// Input goes out one request at a time, so on a slow link a keystroke can
|
||||
// never overtake the one before it; what is typed meanwhile is sent together
|
||||
// next. A request that fails goes again under the same number, and the
|
||||
// server drops one it already has.
|
||||
let inSeq = 0, inBusy = false;
|
||||
const inQueue = [];
|
||||
function queueIn(m) {
|
||||
if (closed || !sid) return;
|
||||
const bytes = new TextEncoder().encode(data);
|
||||
post(base + sid + '/in', { t: 'i', d: bytesToB64(bytes) });
|
||||
const last = inQueue[inQueue.length - 1];
|
||||
if (last && last.t === 'i' && m.t === 'i') last.text += m.text;
|
||||
else if (last && last.t === 'r' && m.t === 'r') inQueue[inQueue.length - 1] = m;
|
||||
else inQueue.push(m);
|
||||
pumpIn();
|
||||
}
|
||||
async function pumpIn() {
|
||||
if (inBusy || !inQueue.length) return;
|
||||
inBusy = true;
|
||||
while (inQueue.length && !closed) {
|
||||
const m = inQueue.shift();
|
||||
const body = m.t === 'i'
|
||||
? { t: 'i', d: bytesToB64(new TextEncoder().encode(m.text)), seq: ++inSeq }
|
||||
: { t: 'r', cols: m.cols, rows: m.rows, seq: ++inSeq };
|
||||
for (let wait = 300; !closed; wait = Math.min(wait * 2, 5000)) {
|
||||
let r = null;
|
||||
try {
|
||||
r = await fetch(base + sid + '/in', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body)
|
||||
});
|
||||
} catch (e) { /* no answer: send it again */ }
|
||||
if (r && r.status < 500) break; // taken, or refused for good
|
||||
await new Promise(res => setTimeout(res, wait));
|
||||
}
|
||||
}
|
||||
inBusy = false;
|
||||
}
|
||||
function send(data) { queueIn({ t: 'i', text: data }); }
|
||||
// What the keyboard types gets the CTRL / ALT of the extra keys, if armed.
|
||||
term.onData(function (data) { send(withMods(data)); });
|
||||
|
||||
@@ -240,10 +271,7 @@
|
||||
b.addEventListener('contextmenu', function (e) { e.preventDefault(); });
|
||||
});
|
||||
|
||||
function sendResize() {
|
||||
if (closed || !sid) return;
|
||||
post(base + sid + '/in', { t: 'r', cols: term.cols, rows: term.rows });
|
||||
}
|
||||
function sendResize() { queueIn({ t: 'r', cols: term.cols, rows: term.rows }); }
|
||||
function refit() {
|
||||
if (touch && window.visualViewport) {
|
||||
// Follow the visible area, so the extra keys sit right above the
|
||||
|
||||
Reference in new issue
Block a user