Menu

#2137 Win32: Clear IME state in ScintillaWin::ImeEndComposition()

Bug
closed-fixed
5
2019-12-07
2019-11-02
Zufu Liu
No

This is remaining patch on [feature-requests:#1300].

I found one situation where the cleanup is needed:
1. Open IME in native inline mode and type some characters.
2. Click IME icon on statusbar, change to English mode, IME candidate window closed with WM_IME_ENDCOMPOSITION send to Scintilla. IME indicators still present Scintilla's window.
3. Type more characters in English mode, IME indicators still present.

Changes for WM_LBUTTONDOWN is copied from WM_KILLFOCUS.

After this change, tentative characters will be cleared from window. call TentativeCommit() seems has same effect as TentativeUndo(), i.e. tentative characters been cleared.

2 Attachments

Related

Bugs: #2135
Feature Requests: #1300

Discussion

1 2 > >> (Page 1 of 2)
  • Zufu Liu

    Zufu Liu - 2019-11-03

    Correct: step 2 is change to English (US) keyboard.

     
  • johnsonj

    johnsonj - 2019-11-08

    google or native win ime? or both?

     
    • Zufu Liu

      Zufu Liu - 2019-11-08

      Win10 x64, builtin MS Pinyin IME.

       
  • Zufu Liu

    Zufu Liu - 2019-11-08

    This is what I observed for MS Chinese, Japanese and Korean IMEs:

    Change to Chinese Pinyin
        WM_INPUTLANGCHANGE
    Type z
        WM_IME_STARTCOMPOSITION
        WM_IME_COMPOSITION
    Change to English America US Keyboard
        WM_IME_ENDCOMPOSITION
        ImeEndComposition
        WM_INPUTLANGCHANGE
    
    Change to Japanese Hiragana
        WM_IME_STARTCOMPOSITION
    Type z
        WM_IME_COMPOSITION
        WM_IME_COMPOSITION
        WM_IME_COMPOSITION
    Change to English America US Keyboard
        WM_IME_COMPOSITION
        WM_IME_ENDCOMPOSITION
        ImeEndComposition
        WM_INPUTLANGCHANGE
    
    Change to Korean IME
        WM_INPUTLANGCHANGE
    Type z
        WM_IME_STARTCOMPOSITION
        WM_IME_COMPOSITION
    Change to English America US Keyboard
        WM_IME_ENDCOMPOSITION
        ImeEndComposition
        WM_IME_COMPOSITION
        WM_INPUTLANGCHANGE
    

    note that WM_IME_COMPOSITION is not sent for Chinese IME when switching keyboard, and the order is also different for Japanese and Korean IME.

     
  • johnsonj

    johnsonj - 2019-11-09

    l use mouse to change input mode for chinese native ime
    It looks normal to me with mouse click.
    what key should be pressed to change to english mode?

    I also have seen a similiar need of clean up on wxWindows
    but no more work has been progressed due to my laziness
    .

     
  • Zufu Liu

    Zufu Liu - 2019-11-09

    I use mouse too, click second IME icon (with "拼") to change keyboard layout, select another IME ("ENG").
    The first icon (with "中" or "英" or "EN") is used to switch between English and native mode.

     
  • johnsonj

    johnsonj - 2019-11-09

    I see "complete composition" as I expect.
    tested under win 7 native chinese ime.

     
  • johnsonj

    johnsonj - 2019-11-09

    windows10! I will try it.

     
  • Zufu Liu

    Zufu Liu - 2019-11-10

    video for Simplified and Traditional IME.
    tested SciTE with ime.interaction=1.

     
  • johnsonj

    johnsonj - 2019-11-10

    No problem is observed with my environment on win 10.
    I will post my mpg in 4 hours.

     
  • johnsonj

    johnsonj - 2019-11-10

    My environments find "complete composition" when changing chinese input mode on win 10 native ime.
    Mpg attached: https://youtu.be/C5fGHrqg_AE

     
  • Neil Hodgson

    Neil Hodgson - 2019-11-10

    The problem can be seen on my system when changing from Simplified Chinese to English input on Windows 10.

    These are recorded using the primitive game recorder so don't show the IME elements. The keys/steps performed are, starting with Simplified Chinese, zhou[Space][Enter]zh[Choose English]ouEnglish:
    Original: https://www.youtube.com/watch?v=hbKDM543Dp8
    After patch: https://www.youtube.com/watch?v=evqiKxW8wT8

    The issue is that the dotted underlines persist in the original version.
    The patch contains 2 chunks and I think its only the second chunk that is relevant to this issue.

     
  • Zufu Liu

    Zufu Liu - 2019-11-10

    The first change (WM_LBUTTONDOWN) is copied from WM_KILLFOCUS, it seems hIMC is non-null even in English system with US keyboard (Change system locale to English, like https://www.isunshare.com/windows-10/change-system-locale-in-windows-10.html).

     
  • Neil Hodgson

    Neil Hodgson - 2019-11-11

    A concern I have with this change is that it is destroying input. I rarely use an IME but sometimes I accidentally leave it on and start typing some English text, often a programming language keyword or identifier. Eventually noticing the problem I switch the language input mode to English. With the change, this input text is removed whereas before it was left intact.

    Its likely the change is correct behaviour for those that are familiar with using an IME but it could annoy some users.

    If you search for WM_IME_ENDCOMPOSITION Korean you'll see some issues. For example, https://chromium.googlesource.com/chromium/src/+/a41b02b4659b3f7af32ed14c323f4316ead2f9ae

     
  • Zufu Liu

    Zufu Liu - 2019-11-12

    I hope already typed tentative characters can be added to document too, i.e. after type "zhw" then switch to English keyboard, "zhw" should re-added to document with CharacterSource::directInput.
    However I don't like Chrome's way (see the video, "zhw" is added twice).

    This change may affect Korean IME, since it sends WM_IME_COMPOSITION after WM_IME_ENDCOMPOSITION, but it seems has no effect with/without this change, 한 is correctly added to document. (tested G+K+S from https://docs.microsoft.com/en-us/windows/win32/dxtecharts/installing-and-using-input-method-editors).

    Video is recored by CamStudio, then converted to mp4 with ffmpeg.

     
    • Zufu Liu

      Zufu Liu - 2019-11-12

      add video.

       
    • Zufu Liu

      Zufu Liu - 2019-11-12

      Or with CharacterSource::imeResult like click first IME to switch to English mode.

       
  • Zufu Liu

    Zufu Liu - 2019-11-12

    The destroying of input can be reproduced without this change:
    1. change IME to native mode, and type some characters.
    2.1 change to English keyboard, then change back to original IME
    2.2 or directly change to another IME
    3. change IME to native mode, then type some characters.

    all previous typed characters (including those without IME indicators) is gone because TentativeUndo() in HandleCompositionInline().

    See my previous video (Chinese-IME-2137.mp4 at https://sourceforge.net/p/scintilla/bugs/2137/#853a) around 22 seconds, after switching to Traditional Chinese IME.

     
  • johnsonj

    johnsonj - 2019-11-12

    The first preposition of scintilla ime is that any comp string should be resulted with result messages.
    I think this is a rule of thumb to keep in mind for this patch.

     
  • Zufu Liu

    Zufu Liu - 2019-11-13

    Tentative input can be kept and IME indicators can be removed by loop cb.TentativeSteps() like Document::TentativeUndo(). Just tested Firefox with Chinese Pinyin "zhw", the result after changing to English keyboard is "zhwzh'w", while Chrome is "zh'wzhw", I don't known where they get the string "zhw" (composition string without Pinyin separator), GCS_RESULTSTR and GCS_COMPSTR are empty.

    However, this approach not works for Korean IME, 한 (G+K+S) is added twice.
    Attached the incomplete and bug prone changes,

     
    • Neil Hodgson

      Neil Hodgson - 2019-11-13

      I can see the problem with Korean.

      For the ime2137-1113.diff patch, Isn't it enough to call TentativeCommit and then remove any indicators?

       
  • Zufu Liu

    Zufu Liu - 2019-11-13

    Changes like this doesn't remove indicators for Chinese/Korean IMEs, and will add Korean character twice.

    void ScintillaWin::ImeEndComposition() {
        // clear IME composition state.
        view.imeCaretBlockOverride = false;
        pdoc->TentativeCommit();
        ShowCaretAtCurrentPosition();
    }
    

    The previous patch (as the last resort method) can be changed to don't remove undo history, only remove the indicators and tentative status. I think we may ignored some messages, it's unlikely Chrome/Firefox remove Pinyin separators (added by IME, not typed) from composition string them self.

     
  • Zufu Liu

    Zufu Liu - 2019-11-14

    I find a method to get Pinyin string without Pinyin separators: by change IME from native mode to English mode.

    // for WM_KILLFOCUS and WM_LBUTTONDOWN
    void ScintillaWin::CompleteCompositionExplicitly() {
        if (imeInComposition) {
            imeInComposition = false;
            IMContext imc(MainHWND());
            if (ChinesePinyinIME()) {
                DWORD dwConversion = IME_CMODE_ALPHANUMERIC;
                DWORD dwSentence = IME_SMODE_NONE;
                if (::ImmGetConversionStatus(imc.hIMC, &dwConversion, &dwSentence)) {
                    Platform::DebugPrintf("dwConversion=%04x\n", dwConversion);
                    if (::ImmSetConversionStatus(imc.hIMC, IME_CMODE_ALPHANUMERIC, dwSentence)) {
                        ::ImmSetConversionStatus(imc.hIMC, dwConversion, dwSentence);
                        return;
                    }
                }
            }
            Platform::DebugPrintf("NI_COMPOSITIONSTR\n");
            // set the composition string as the result string.
            ::ImmNotifyIME(imc.hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
        }
    }
    
    void ScintillaWin::CompleteCompositionExplicitly2() {
        if (imeInComposition) {
            imeInComposition = false;
            IMContext imc(MainHWND());
            if (ChinesePinyinIME()) {
                DWORD dwConversion = IME_CMODE_ALPHANUMERIC;
                DWORD dwSentence = IME_SMODE_NONE;
                if (::ImmGetConversionStatus(imc.hIMC, &dwConversion, &dwSentence)) {
                    Platform::DebugPrintf("dwConversion=%04x\n", dwConversion);
                    if (::ImmSetConversionStatus(imc.hIMC, IME_CMODE_ALPHANUMERIC, dwSentence)) {
                        ::ImmSetConversionStatus(imc.hIMC, dwConversion, dwSentence);
                        return;
                    }
                }
            }
        }
    
        if (KoreanIME()) {
            //pdoc->TentativeUndo();
        } else {
            // remove ime indicators
            //pdoc->TentativeCommmitEx()
        }
    }
    
    void ScintillaWin::ImeEndComposition() {
        CompleteCompositionExplicitly2()
        view.imeCaretBlockOverride = false;
        ShowCaretAtCurrentPosition();
    }
    

    For Pinyin IME, change IME mode to IME_CMODE_ALPHANUMERIC will commit composition string without Pinyin separators (in both inline mode or window mode), which behaviors same as click first IME icon ("英" or EN) or press Shift key.
    while NI_COMPOSITIONSTR+CPS_COMPLETE not works in WM_IME_ENDCOMPOSITION, and will commit composition string with Pinyin separators in WM_KILLFOCUS or WM_LBUTTONDOWN.

    ::ImmSetConversionStatus(imc.hIMC, IME_CMODE_ALPHANUMERIC, dwSentence) will cause
    WM_IME_COMPOSITION + GCS_RESULTSTR
    WM_IME_ENDCOMPOSITION

    The reliability for this method is unknown (for different Pinyin IMEs, non-Pinyin IMEs, Pinyin IME on different systems).

     
    • Neil Hodgson

      Neil Hodgson - 2019-11-14

      This looks like a bit of a hack to me. I hope flicking the mode doesn't cause any visible artefacts.

       
  • Zufu Liu

    Zufu Liu - 2019-11-14

    I think currently it's better for Document::TentativeCommmit() to remove IME indicators, with some change like (without change currentAction):

    void Document::TentativeCommmit() {
    if (cb.TentativeActive()) {
        const std::vector<const Action&> actions = cb.TentativeSteps();
        for (const Action& action : actions) {
            decorations->DeleteRange(action.position, action.lenData);
        }
        cb.TentativeCommmit();
    }
    }
    

    and call it for non-Korean IMEs in ImeEndComposition().

     

    Last edit: Zufu Liu 2019-11-14
1 2 > >> (Page 1 of 2)

Log in to post a comment.