Open maboroshin opened 4 years ago
What's the steps (which character typed, which key pressed) to reproduce the undesired caret position?
Modern Japanese hiragana order: あいうえお A I U E O かきこけこ KA KI KU KE KO さしすせそ SA SI SU SE ...continue...
Thus, I often used "A" or "I" . あああああああ = key input : "AAAAAAAA[SPACE]" いいいい = "IIII"
The difference between VS Code and Notepad2:
window mode
caret is always at the end of composition string
Notepad2 inline mode
put caret at the end of composition string on typing
あああああああ
^
move caret to the beginning of ATTR_TARGET_CONVERTED on converting, before 嗚呼
which is the caret position retrieved from GCS_CURSORPOS
嗚呼ああああ
^
VS Code inline mode
always has a caret at end of composition string
あああああああ
^
put another caret at the end of ATTR_TARGET_CONVERTED on converting, after 嗚呼
嗚呼ああああ
^ ^
Changes to log caret position and composition text attributes.
diff --git a/scintilla/win32/ScintillaWin.cxx b/scintilla/win32/ScintillaWin.cxx
index 17742138..5c552b06 100644
--- a/scintilla/win32/ScintillaWin.cxx
+++ b/scintilla/win32/ScintillaWin.cxx
@@ -1269,22 +1269,31 @@ std::vector<int> MapImeIndicators(const std::vector<BYTE> &inputStyle, int &indi
std::vector<int> imeIndicator(attrLen, SC_INDICATOR_UNKNOWN);
int mask = 0;
+ printf("inputStyle %d:\n", (int)attrLen);
for (size_t i = 0; i < attrLen; i++) {
switch (inputStyle.at(i)) {
case ATTR_INPUT:
imeIndicator[i] = SC_INDICATOR_INPUT;
mask |= 1 << (SC_INDICATOR_INPUT - INDICATOR_IME);
+ printf("\tinputStyle[%d] = %s\n", (int)i, "ATTR_INPUT");
break;
case ATTR_TARGET_NOTCONVERTED:
+ printf("\tinputStyle[%d] = %s\n", (int)i, "ATTR_TARGET_NOTCONVERTED");
+ imeIndicator[i] = SC_INDICATOR_TARGET;
+ mask |= 1 << (SC_INDICATOR_TARGET - INDICATOR_IME);
+ break;
case ATTR_TARGET_CONVERTED:
+ printf("\tinputStyle[%d] = %s\n", (int)i, "ATTR_TARGET_CONVERTED");
imeIndicator[i] = SC_INDICATOR_TARGET;
mask |= 1 << (SC_INDICATOR_TARGET - INDICATOR_IME);
break;
case ATTR_CONVERTED:
+ printf("\tinputStyle[%d] = %s\n", (int)i, "ATTR_CONVERTED");
imeIndicator[i] = SC_INDICATOR_CONVERTED;
mask |= 1 << (SC_INDICATOR_CONVERTED - INDICATOR_IME);
break;
default:
+ printf("\tinputStyle[%d] = %d/%s\n", (int)i, inputStyle[i], "SC_INDICATOR_UNKNOWN");
imeIndicator[i] = SC_INDICATOR_UNKNOWN;
mask |= 1 << (SC_INDICATOR_UNKNOWN - INDICATOR_IME);
break;
@@ -1393,6 +1402,7 @@ sptr_t ScintillaWin::HandleCompositionInline(uptr_t, sptr_t lParam) {
// GCS_CURSORPOS value if it's available.
Sci::Position imeEndToImeCaretU16 = -static_cast<Sci::Position>(wcs.size());
if (!(lParam & CS_NOMOVECARET) && (lParam & GCS_CURSORPOS)) {
+ printf("\tGetImeCaretPos: %d\n", imc.GetImeCaretPos());
imeEndToImeCaretU16 += imc.GetImeCaretPos();
}
if (imeEndToImeCaretU16 != 0) {
diff --git a/src/Notepad2.c b/src/Notepad2.c
index 8cb8f1f1..d181cd81 100644
--- a/src/Notepad2.c
+++ b/src/Notepad2.c
@@ -452,7 +452,7 @@ static void CleanUpResources(BOOL initialized) {
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
-#if 0 // used for Clang UBSan or printing debug message on console.
+#if 1 // used for Clang UBSan or printing debug message on console.
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
After apply above changes, build Notepad, run it from command prompt or powershell, you will get following logs. I think current implementation is OK, at least works as what the IME suggested.
1. after typing six A
inputStyle 6:
inputStyle[0] = ATTR_INPUT
inputStyle[1] = ATTR_INPUT
inputStyle[2] = ATTR_INPUT
inputStyle[3] = ATTR_INPUT
inputStyle[4] = ATTR_INPUT
inputStyle[5] = ATTR_INPUT
GetImeCaretPos: 6
2. press Space
inputStyle 6:
inputStyle[0] = ATTR_TARGET_CONVERTED
inputStyle[1] = ATTR_TARGET_CONVERTED
inputStyle[2] = ATTR_CONVERTED
inputStyle[3] = ATTR_CONVERTED
inputStyle[4] = ATTR_CONVERTED
inputStyle[5] = ATTR_CONVERTED
GetImeCaretPos: 0
3. press right arrow
inputStyle 6:
inputStyle[0] = ATTR_CONVERTED
inputStyle[1] = ATTR_CONVERTED
inputStyle[2] = ATTR_TARGET_CONVERTED
inputStyle[3] = ATTR_TARGET_CONVERTED
inputStyle[4] = ATTR_CONVERTED
inputStyle[5] = ATTR_CONVERTED
GetImeCaretPos: 2
I have already reported this in Scintilla's talk group. Zufuliu is also active in improving the IME's behavior.
(Default Windows notepad.exe, no inline IME)
(Notepad2, no inline IME)
(each 2nd images are converting the next section)
(Notepad2, Red line is inline IME)
In the inline IME, the caret is at the beginning. Originally, the last seems to be correct.
(VSCode, inline IME)
(Notepad2, Green is Ideal caret position in inline IME )
It is the standard. The last caret in its initial state. It's the same as VSCode if caret is the last in the conversion. I think this is a good.
But it is also useful in the green position during conversion. It is not a standard.