@@ -345,29 +345,42 @@ export class Terminal implements ITerminalCore {
345345 this . canvas . style . display = 'block' ;
346346 parent . appendChild ( this . canvas ) ;
347347
348- // Create hidden textarea for clipboard operations (xterm.js pattern)
349- // This textarea will be positioned under the mouse cursor during right-clicks
350- // to enable the browser's native context menu with Copy/Paste options
348+ // Create hidden textarea for keyboard input (must be inside parent for event bubbling)
351349 this . textarea = document . createElement ( 'textarea' ) ;
352350 this . textarea . setAttribute ( 'autocorrect' , 'off' ) ;
353351 this . textarea . setAttribute ( 'autocapitalize' , 'off' ) ;
354352 this . textarea . setAttribute ( 'spellcheck' , 'false' ) ;
355- this . textarea . setAttribute ( 'tabindex' , '-1 ' ) ; // Don't interfere with tab navigation
353+ this . textarea . setAttribute ( 'tabindex' , '0 ' ) ; // Allow focus for mobile keyboard
356354 this . textarea . setAttribute ( 'aria-label' , 'Terminal input' ) ;
355+ // Use clip-path to completely hide the textarea and its caret
357356 this . textarea . style . position = 'absolute' ;
358357 this . textarea . style . left = '0' ;
359358 this . textarea . style . top = '0' ;
360- this . textarea . style . width = '0' ;
361- this . textarea . style . height = '0' ;
362- this . textarea . style . zIndex = '-10' ;
359+ this . textarea . style . width = '1px' ;
360+ this . textarea . style . height = '1px' ;
361+ this . textarea . style . padding = '0' ;
362+ this . textarea . style . border = 'none' ;
363+ this . textarea . style . margin = '0' ;
363364 this . textarea . style . opacity = '0' ;
365+ this . textarea . style . clipPath = 'inset(50%)' ; // Clip everything including caret
364366 this . textarea . style . overflow = 'hidden' ;
365- this . textarea . style . pointerEvents = 'none' ; // Don't interfere with mouse events normally
367+ this . textarea . style . whiteSpace = 'nowrap' ;
366368 this . textarea . style . resize = 'none' ;
367- this . textarea . style . border = 'none' ;
368- this . textarea . style . outline = 'none' ;
369369 parent . appendChild ( this . textarea ) ;
370370
371+ // Focus textarea on interaction - preventDefault before focus
372+ const textarea = this . textarea ;
373+ // Desktop: mousedown
374+ this . canvas . addEventListener ( 'mousedown' , ( ev ) => {
375+ ev . preventDefault ( ) ;
376+ textarea . focus ( ) ;
377+ } ) ;
378+ // Mobile: touchend with preventDefault to suppress iOS caret
379+ this . canvas . addEventListener ( 'touchend' , ( ev ) => {
380+ ev . preventDefault ( ) ;
381+ textarea . focus ( ) ;
382+ } ) ;
383+
371384 // Create renderer
372385 this . renderer = new CanvasRenderer ( this . canvas , {
373386 fontSize : this . options . fontSize ,
0 commit comments