Skip to content

iOS Chinese IMEs cannot input punctuation (including space) #5835

@someonegg

Description

@someonegg

Details

  • Browser and browser version: Safari (iOS 26), Chrome (iOS 26)
  • OS version: iOS 26
  • xterm.js version: master (upstream/master)

Steps to reproduce

  1. On iOS, use a Chinese IME.
  2. Focus an xterm.js terminal.
  3. Input punctuation and spaces (for example: , , ).
  4. Observe keyboard/input events and terminal output.

Expected result: punctuation/space should be sent to the terminal as normal input.

Actual behavior: punctuation/space is often not sent to the terminal (dropped), even though corresponding beforeinput/input/keyup events occur on iOS.

Special case

When pressing Space twice consecutively, iOS IME may transform it into via a delete-then-insert sequence:

  • beforeinput/input with deleteContentBackward
  • then beforeinput/input with insertText data=

Additionally, this sequence can hit the last branch of _handleAnyTextareaChanges (same length but different value), which sends the whole newValue (entire textarea content) instead of a minimal diff. That may cause duplicated or over-sent data.

Root cause

For iOS Chinese IMEs, punctuation (including space-triggered conversion) is produced via non-composition paths and is not reliably available at keydown time. Keydown-only handling can miss these inputs; keyup/input stage is where the final character is reliably observable.

Raw event sequence

[09:08:04.163] #151 keydown len=0 sel=[0,0,none] textArea="" key=" " code="Space" keyCode=229 which=229 isComposing=false
[09:08:04.170] #152 beforeinput len=0 sel=[0,0,none] textArea="" inputType="insertText" data=" " isComposing=false composed=true
[09:08:04.173] #153 input len=1 sel=[1,1,none] textArea=" " inputType="insertText" data=" " isComposing=false composed=true
[09:08:04.174] #154 selectionchange(document) len=1 sel=[1,1,none] textArea=" "
[09:08:04.175] #155 keyup len=1 sel=[1,1,none] textArea=" " key=" " code="Space" keyCode=32 which=32 isComposing=false
[09:08:06.806] #156 keydown len=1 sel=[1,1,none] textArea=" " key="," code="Unidentified" keyCode=229 which=229 isComposing=false
[09:08:06.816] #157 beforeinput len=1 sel=[1,1,none] textArea=" " inputType="insertText" data="," isComposing=false composed=true
[09:08:06.818] #158 input len=2 sel=[2,2,none] textArea=" ," inputType="insertText" data="," isComposing=false composed=true
[09:08:06.820] #159 keyup len=2 sel=[2,2,none] textArea=" ," key="," code="Unidentified" keyCode=0 which=0 isComposing=false
[09:08:06.820] #160 selectionchange(document) len=2 sel=[2,2,none] textArea=" ,"
[09:08:09.552] #161 keydown len=2 sel=[2,2,none] textArea=" ," key="!" code="Unidentified" keyCode=229 which=229 isComposing=false
[09:08:09.561] #162 beforeinput len=2 sel=[2,2,none] textArea=" ," inputType="insertText" data="!" isComposing=false composed=true
[09:08:09.563] #163 input len=3 sel=[3,3,none] textArea=" ,!" inputType="insertText" data="!" isComposing=false composed=true
[09:08:09.566] #164 selectionchange(document) len=3 sel=[3,3,none] textArea=" ,!"
[09:08:09.569] #165 keyup len=3 sel=[3,3,none] textArea=" ,!" key="!" code="Unidentified" keyCode=0 which=0 isComposing=false
[09:08:11.266] #166 keydown len=3 sel=[3,3,none] textArea=" ,!" key=" " code="Space" keyCode=229 which=229 isComposing=false
[09:08:11.275] #167 beforeinput len=3 sel=[3,3,none] textArea=" ,!" inputType="insertText" data=" " isComposing=false composed=true
[09:08:11.281] #168 input len=4 sel=[4,4,none] textArea=" ,! " inputType="insertText" data=" " isComposing=false composed=true
[09:08:11.287] #169 keyup len=4 sel=[4,4,none] textArea=" ,! " key=" " code="Space" keyCode=32 which=32 isComposing=false
[09:08:11.293] #170 selectionchange(document) len=4 sel=[4,4,none] textArea=" ,! "
[09:08:11.866] #171 keydown len=4 sel=[4,4,none] textArea=" ,! " key=" " code="Space" keyCode=229 which=229 isComposing=false
[09:08:11.877] #172 beforeinput len=4 sel=[4,4,none] textArea=" ,! " inputType="deleteContentBackward" data="" isComposing=false composed=true
[09:08:11.884] #173 input len=3 sel=[3,3,none] textArea=" ,!" inputType="deleteContentBackward" data="" isComposing=false composed=true
[09:08:11.890] #174 beforeinput len=3 sel=[3,3,none] textArea=" ,!" inputType="insertText" data="。" isComposing=false composed=true
[09:08:11.896] #175 input len=4 sel=[4,4,none] textArea=" ,!。" inputType="insertText" data="。" isComposing=false composed=true
[09:08:11.900] #176 keyup len=4 sel=[4,4,none] textArea=" ,!。" key=" " code="Space" keyCode=32 which=32 isComposing=false

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions