termites 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server.js +36 -8
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -953,6 +953,13 @@ class TermitesServer {
|
|
|
953
953
|
'ArrowRight': '\\x1b[1;5C',
|
|
954
954
|
'ArrowLeft': '\\x1b[1;5D'
|
|
955
955
|
};
|
|
956
|
+
// Alt + key sequences
|
|
957
|
+
const altKeyMap = {
|
|
958
|
+
'ArrowUp': '\\x1b[1;3A',
|
|
959
|
+
'ArrowDown': '\\x1b[1;3B',
|
|
960
|
+
'ArrowRight': '\\x1b[1;3C',
|
|
961
|
+
'ArrowLeft': '\\x1b[1;3D'
|
|
962
|
+
};
|
|
956
963
|
|
|
957
964
|
toolbar.querySelectorAll('button').forEach(btn => {
|
|
958
965
|
// Use touchstart to prevent losing focus on terminal
|
|
@@ -966,7 +973,14 @@ class TermitesServer {
|
|
|
966
973
|
if (mod) {
|
|
967
974
|
modifiers[mod] = !modifiers[mod];
|
|
968
975
|
btn.classList.toggle('active', modifiers[mod]);
|
|
969
|
-
|
|
976
|
+
// Set timeout to auto-reset Ctrl after 10 seconds (for IME users)
|
|
977
|
+
if (mod === 'ctrl' && modifiers.ctrl) {
|
|
978
|
+
if (window.ctrlTimeout) clearTimeout(window.ctrlTimeout);
|
|
979
|
+
window.ctrlTimeout = setTimeout(() => {
|
|
980
|
+
modifiers.ctrl = false;
|
|
981
|
+
btn.classList.remove('active');
|
|
982
|
+
}, 10000);
|
|
983
|
+
}
|
|
970
984
|
// Don't focus terminal when toggling modifier, keep keyboard open
|
|
971
985
|
return;
|
|
972
986
|
}
|
|
@@ -985,6 +999,16 @@ class TermitesServer {
|
|
|
985
999
|
} else {
|
|
986
1000
|
data = keyMap[key] || '';
|
|
987
1001
|
}
|
|
1002
|
+
} else if (modifiers.alt) {
|
|
1003
|
+
// Alt + key
|
|
1004
|
+
if (altKeyMap[key]) {
|
|
1005
|
+
data = altKeyMap[key];
|
|
1006
|
+
} else if (key.length === 1) {
|
|
1007
|
+
// Alt + letter sends ESC + letter
|
|
1008
|
+
data = '\\x1b' + key;
|
|
1009
|
+
} else {
|
|
1010
|
+
data = keyMap[key] || '';
|
|
1011
|
+
}
|
|
988
1012
|
} else {
|
|
989
1013
|
data = keyMap[key] || '';
|
|
990
1014
|
}
|
|
@@ -995,6 +1019,7 @@ class TermitesServer {
|
|
|
995
1019
|
// Reset modifiers after use
|
|
996
1020
|
modifiers.ctrl = false;
|
|
997
1021
|
modifiers.alt = false;
|
|
1022
|
+
if (window.ctrlTimeout) { clearTimeout(window.ctrlTimeout); window.ctrlTimeout = null; }
|
|
998
1023
|
toolbar.querySelectorAll('.mod-btn').forEach(b => b.classList.remove('active'));
|
|
999
1024
|
}
|
|
1000
1025
|
// Only focus terminal for non-modifier buttons
|
|
@@ -1057,20 +1082,23 @@ class TermitesServer {
|
|
|
1057
1082
|
term.loadAddon(fitAddon);
|
|
1058
1083
|
term.open(document.getElementById('terminal-container'));
|
|
1059
1084
|
fitAddon.fit();
|
|
1085
|
+
let ctrlTimeout = null;
|
|
1060
1086
|
term.onData(data => {
|
|
1061
1087
|
if (ws?.readyState === WebSocket.OPEN && selectedClientId) {
|
|
1062
1088
|
let sendData = data;
|
|
1063
|
-
console.log('Input received:', data, 'Ctrl active:', modifiers.ctrl);
|
|
1064
1089
|
// Apply Ctrl modifier to keyboard input
|
|
1065
|
-
if (modifiers.ctrl
|
|
1066
|
-
|
|
1090
|
+
if (modifiers.ctrl) {
|
|
1091
|
+
// Handle single character or IME input
|
|
1092
|
+
const char = data.length >= 1 ? data[0] : '';
|
|
1093
|
+
const code = char.toUpperCase().charCodeAt(0);
|
|
1067
1094
|
if (code >= 65 && code <= 90) { // A-Z
|
|
1068
1095
|
sendData = String.fromCharCode(code - 64);
|
|
1069
|
-
console.log('Sending Ctrl+' +
|
|
1096
|
+
console.log('Sending Ctrl+' + char.toUpperCase());
|
|
1097
|
+
// Reset Ctrl after successful use
|
|
1098
|
+
modifiers.ctrl = false;
|
|
1099
|
+
if (ctrlTimeout) { clearTimeout(ctrlTimeout); ctrlTimeout = null; }
|
|
1100
|
+
document.querySelectorAll('.mod-btn[data-mod="ctrl"]').forEach(b => b.classList.remove('active'));
|
|
1070
1101
|
}
|
|
1071
|
-
// Reset Ctrl after use
|
|
1072
|
-
modifiers.ctrl = false;
|
|
1073
|
-
document.querySelectorAll('.mod-btn').forEach(b => b.classList.remove('active'));
|
|
1074
1102
|
}
|
|
1075
1103
|
ws.send(JSON.stringify({ type: 'input', clientId: selectedClientId, text: sendData }));
|
|
1076
1104
|
term.scrollToBottom();
|