fix: toolbar buttons now send actual control chars via xterm _core API
Buttons were sending literal 'n'/'p' instead of Ctrl-A+n/p because the hex escape decode was failing. Now uses real control characters in data-k attributes and sends via triggerDataEvent() which hooks directly into ttyd's websocket transport.
This commit is contained in:
+30
-25
@@ -28,37 +28,46 @@
|
|||||||
bar.id='mb';
|
bar.id='mb';
|
||||||
bar.innerHTML=
|
bar.innerHTML=
|
||||||
'<div class="row">'+
|
'<div class="row">'+
|
||||||
'<button class="hi" data-k="\\x01c">+Tab</button>'+
|
'<button class="hi" data-k="\x01c">+Tab</button>'+
|
||||||
'<button data-k="\\x01n">Next</button>'+
|
'<button data-k="\x01n">Next</button>'+
|
||||||
'<button data-k="\\x01p">Prev</button>'+
|
'<button data-k="\x01p">Prev</button>'+
|
||||||
'<div class="sep"></div>'+
|
'<div class="sep"></div>'+
|
||||||
'<button data-k="\\x03">^C</button>'+
|
'<button data-k="\x03">^C</button>'+
|
||||||
'<button data-k="\\x04">^D</button>'+
|
'<button data-k="\x04">^D</button>'+
|
||||||
'<button data-k="\\x0c">Clr</button>'+
|
'<button data-k="\x0c">Clr</button>'+
|
||||||
'<div class="sep"></div>'+
|
'<div class="sep"></div>'+
|
||||||
'<button data-k="\\x1b">Esc</button>'+
|
'<button data-k="\x1b">Esc</button>'+
|
||||||
'<button data-k="\\t">Tab</button>'+
|
'<button data-k="\t">Tab</button>'+
|
||||||
'<button data-k="\\x1bOA">\u25B2</button>'+
|
'<button data-k="\x1bOA">\u25B2</button>'+
|
||||||
'<button data-k="\\x1bOB">\u25BC</button>'+
|
'<button data-k="\x1bOB">\u25BC</button>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div class="row">'+
|
'<div class="row">'+
|
||||||
'<button class="hi" id="selbtn" data-sel="1">Sel</button>'+
|
'<button class="hi" id="selbtn" data-sel="1">Sel</button>'+
|
||||||
'<button class="hi" id="pastebtn" data-paste="1">Paste</button>'+
|
'<button class="hi" id="pastebtn" data-paste="1">Paste</button>'+
|
||||||
'<button data-k="\\x01z">Zoom</button>'+
|
'<button data-k="\x01z">Zoom</button>'+
|
||||||
'<button class="grn" data-save="1">Save</button>'+
|
'<button class="grn" data-save="1">Save</button>'+
|
||||||
'<div class="sep"></div>'+
|
'<div class="sep"></div>'+
|
||||||
'<button data-k="\\x01v">V.Spl</button>'+
|
'<button data-k="\x01v">V.Spl</button>'+
|
||||||
'<button data-k="\\x01s">H.Spl</button>'+
|
'<button data-k="\x01s">H.Spl</button>'+
|
||||||
'<button data-k="\\x01o">Pane</button>'+
|
'<button data-k="\x01o">Pane</button>'+
|
||||||
'<button data-k="\\x01x">Kill</button>'+
|
'<button data-k="\x01x">Kill</button>'+
|
||||||
'</div>';
|
'</div>';
|
||||||
document.body.appendChild(bar);
|
document.body.appendChild(bar);
|
||||||
|
|
||||||
|
// Send data to terminal via xterm's _core (bypasses any .input() issues)
|
||||||
function send(k){
|
function send(k){
|
||||||
if(document.body.classList.contains('selmode')) toggleSel();
|
if(document.body.classList.contains('selmode')) toggleSel();
|
||||||
k=k.replace(/\\x([0-9a-f]{2})/gi,function(_,h){return String.fromCharCode(parseInt(h,16));});
|
var t=window.term;
|
||||||
k=k.replace(/\\t/g,'\t');
|
if(!t) return;
|
||||||
if(window.term){window.term.input(k);window.term.focus();}
|
// Try _core.triggerDataEvent first (fires onData which ttyd hooks)
|
||||||
|
if(t._core && t._core.coreService && t._core.coreService.triggerDataEvent){
|
||||||
|
t._core.coreService.triggerDataEvent(k);
|
||||||
|
} else if(t._core && t._core._onData){
|
||||||
|
t._core._onData.fire(k);
|
||||||
|
} else if(t.input){
|
||||||
|
t.input(k);
|
||||||
|
}
|
||||||
|
t.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleSel(){
|
function toggleSel(){
|
||||||
@@ -79,18 +88,14 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
navigator.clipboard.readText().then(function(text){
|
navigator.clipboard.readText().then(function(text){
|
||||||
if(text && window.term){
|
if(text) send(text);
|
||||||
window.term.input(text);
|
|
||||||
window.term.focus();
|
|
||||||
}
|
|
||||||
}).catch(function(e){
|
}).catch(function(e){
|
||||||
alert('Clipboard read failed: '+e.message);
|
alert('Clipboard read failed: '+e.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSave(){
|
function doSave(){
|
||||||
// Trigger tmux capture-pane via the keybinding Ctrl-A S
|
send('\x01S');
|
||||||
send('\\x01S');
|
|
||||||
var btn=document.querySelector('[data-save]');
|
var btn=document.querySelector('[data-save]');
|
||||||
btn.classList.add('on');
|
btn.classList.add('on');
|
||||||
btn.textContent='\u2713';
|
btn.textContent='\u2713';
|
||||||
@@ -106,7 +111,7 @@
|
|||||||
if(btn.dataset.k) send(btn.dataset.k);
|
if(btn.dataset.k) send(btn.dataset.k);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Shrink terminal for toolbar on mobile (2 rows now)
|
// Shrink terminal for toolbar on mobile (2 rows)
|
||||||
var obs=new MutationObserver(function(){
|
var obs=new MutationObserver(function(){
|
||||||
var el=document.querySelector('.xterm');
|
var el=document.querySelector('.xterm');
|
||||||
if(el && window.innerWidth<=900){
|
if(el && window.innerWidth<=900){
|
||||||
|
|||||||
Reference in New Issue
Block a user