xtermjs / xterm.js

A terminal for the web
https://xtermjs.org/
MIT License
17.04k stars 1.6k forks source link

Duplicate input when using Chinese input methods #5023

Closed ksqsf closed 3 months ago

ksqsf commented 3 months ago

There was a previous report at #3191 but the linked PR does not fix this problem.

I'll begin with a description of how a certain kind of Chinese input methods work (including the Wubi method, which is very popular in China):

  1. The user inputs something, and the IME updates the candidate list accordingly (compositionstart and compositionupdate)
  2. Until now, nothing is committed or inserted into the text area
  3. Then, the user hits another key, which bears dual functions: (1) confirms the last selection (compositionupdate and compositionend), and then (2) the key itself is considered as input for the next input session.

In the following screencast, I typed "qtqtq", and at the final "q", the problem occurs:

  1. 狠狠 is inserted, which is expected
  2. q is inserted, which is NOT expected

https://github.com/xtermjs/xterm.js/assets/23358293/d20db910-65ee-408a-910f-07c036a1b964

From the console log, you can see that the problem is in _compositionPosition.end: when I typed the final "q", the end position was not correctly set: it thinks the end position is 4, while the correct position should be 2. However, at this point, the composition contains the new input "q", therefore "狠狠q" is inserted.

The root cause is in that xterm.js assumed that when a new composition starts, the length of the committed input remains the same, which is not true in this case. Or it could also be a Chromium bug, when it should update composition BEFORE compositionend.

Details

This bug is also reproducible in Visual Studio Code.

Steps to reproduce

  1. Install Qingg, add "清歌五笔" from Chinese (Simplified), and select it (Qingg is a popular implementation of the Wubi method in macOS)
  2. In the web demo, type "qtqtx"
  3. Get "狠狠" and "x" both inserted into the terminal