fix: clear mobile keyboard modifiers after Enter/Backspace/Delete
Modifiers (Ctrl/Shift) were staying active ('sticky') after pressing
Enter, Backspace, or Delete keys on the mobile soft keyboard.
The beforeinput event handler was sending the key sequences but not
calling deactivateModifiers(), unlike the input handler (for regular
text) and keydown handler (for arrow keys).
This caused modifiers to remain highlighted and active until the user
typed a regular letter, making the keyboard feel unresponsive.
Now modifiers are properly cleared after all soft keyboard keys.
This commit is contained in:
@@ -25,7 +25,7 @@ For tests, pass a Ghostty instance directly:
|
||||
resize: none;
|
||||
font-size: 16px;
|
||||
caret-color: transparent;
|
||||
`,this.element.style.position="relative",this.element.appendChild(V),this.mobileInput=V,V.addEventListener("beforeinput",(j)=>{let $=null;switch(j.inputType){case"insertLineBreak":$="\r";break;case"deleteContentBackward":$="";break;case"deleteContentForward":$="\x1B[3~";break}if($)j.preventDefault(),this.send(["stdin",$])}),V.addEventListener("input",()=>{let j=V.value;if(j){let $=j;if(this.shiftActive&&j.length===1)$=j.toUpperCase();if(this.ctrlActive&&j.length===1){let P=$.toUpperCase().charCodeAt(0);if(P>=65&&P<=90)$=String.fromCharCode(P-64)}this.send(["stdin",$]),V.value="",this.deactivateModifiers()}}),V.addEventListener("keydown",(j)=>{let $=j.ctrlKey||this.ctrlActive,P=j.shiftKey||this.shiftActive;if(j.ctrlKey&&j.key.length===1&&!j.altKey&&!j.metaKey){let R=j.key.toUpperCase().charCodeAt(0);if(R>=65&&R<=90){j.preventDefault(),this.send(["stdin",String.fromCharCode(R-64)]);return}}let X=null,K=!1;switch(j.key){case"Escape":X="\x1B",K=!0;break;case"ArrowUp":case"ArrowDown":case"ArrowRight":case"ArrowLeft":{let R=j.key==="ArrowUp"?"A":j.key==="ArrowDown"?"B":j.key==="ArrowRight"?"C":"D";if($&&P)X=`\x1B[1;6${R}`;else if($)X=`\x1B[1;5${R}`;else if(P)X=`\x1B[1;2${R}`;else X=`\x1B[${R}`;K=!0;break}case"Tab":if(P)X="\x1B[Z";else X="\t";j.preventDefault(),K=!0;break}if(X){if(j.preventDefault(),this.send(["stdin",X]),K)this.deactivateModifiers()}});let Z=()=>{this.mobileInput?.focus()};this.element.addEventListener("touchend",Z,{passive:!0}),this.element.addEventListener("click",Z)}setupMobileKeybar(){let V=document.createElement("div");V.className="mobile-keybar",V.innerHTML=`
|
||||
`,this.element.style.position="relative",this.element.appendChild(V),this.mobileInput=V,V.addEventListener("beforeinput",(j)=>{let $=null;switch(j.inputType){case"insertLineBreak":$="\r";break;case"deleteContentBackward":$="";break;case"deleteContentForward":$="\x1B[3~";break}if($)j.preventDefault(),this.send(["stdin",$]),this.deactivateModifiers()}),V.addEventListener("input",()=>{let j=V.value;if(j){let $=j;if(this.shiftActive&&j.length===1)$=j.toUpperCase();if(this.ctrlActive&&j.length===1){let P=$.toUpperCase().charCodeAt(0);if(P>=65&&P<=90)$=String.fromCharCode(P-64)}this.send(["stdin",$]),V.value="",this.deactivateModifiers()}}),V.addEventListener("keydown",(j)=>{let $=j.ctrlKey||this.ctrlActive,P=j.shiftKey||this.shiftActive;if(j.ctrlKey&&j.key.length===1&&!j.altKey&&!j.metaKey){let R=j.key.toUpperCase().charCodeAt(0);if(R>=65&&R<=90){j.preventDefault(),this.send(["stdin",String.fromCharCode(R-64)]);return}}let X=null,K=!1;switch(j.key){case"Escape":X="\x1B",K=!0;break;case"ArrowUp":case"ArrowDown":case"ArrowRight":case"ArrowLeft":{let R=j.key==="ArrowUp"?"A":j.key==="ArrowDown"?"B":j.key==="ArrowRight"?"C":"D";if($&&P)X=`\x1B[1;6${R}`;else if($)X=`\x1B[1;5${R}`;else if(P)X=`\x1B[1;2${R}`;else X=`\x1B[${R}`;K=!0;break}case"Tab":if(P)X="\x1B[Z";else X="\t";j.preventDefault(),K=!0;break}if(X){if(j.preventDefault(),this.send(["stdin",X]),K)this.deactivateModifiers()}});let Z=()=>{this.mobileInput?.focus()};this.element.addEventListener("touchend",Z,{passive:!0}),this.element.addEventListener("click",Z)}setupMobileKeybar(){let V=document.createElement("div");V.className="mobile-keybar",V.innerHTML=`
|
||||
<button class="keybar-drag" title="Drag to move">⋮⋮</button>
|
||||
<button data-key="\\x1b" title="Escape">Esc</button>
|
||||
<button data-modifier="ctrl" title="Ctrl modifier">Ctrl</button>
|
||||
|
||||
@@ -654,6 +654,8 @@ class WebTerminal {
|
||||
if (seq) {
|
||||
e.preventDefault();
|
||||
this.send(["stdin", seq]);
|
||||
// Clear modifiers after sending special keys from soft keyboard
|
||||
this.deactivateModifiers();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user