admin管理员组

文章数量:1405374

Description

I'm encountering a peculiar issue with my TSF implementation on Windows 11. My custom IME generally works well with multiple input methods when implemented in a separate thread isolated from the main thread's message loop. Specifically:

The IME creates an invisible window running in a dedicated thread

Handles keyboard input capture through ::SetFocus and AssociateFocus when needed

Problem

  1. When using Microsoft Pinyin(During candidate selection phase), Pressing Shift to switch conversion mode to English;
  2. Results in complete loss of keyboard events (WM_KEYUP/DOWN)in the IME thread.
  3. And Shift key stops toggling conversion mode.

Contrastingly, iFly IME:

Doesn't send conversion status changes to TSF/IMM. Shows no issues under identical test conditions.

Debug Findings:

After the deadlock occurs, AssociateFocus with empty document will restores event flow, all blocked events flood in simultaneously.

Implementation Details

Full TextStoreAPC, IElementSink, ITfContextOwnerCompositionSink interfaces implemented.

Key Questions

  1. What TSF internal state could block keyboard event propagation?
  2. How might document focus ownership affect this behavior?
  3. Recommended patterns to prevent event pipeline blockage?

Description

I'm encountering a peculiar issue with my TSF implementation on Windows 11. My custom IME generally works well with multiple input methods when implemented in a separate thread isolated from the main thread's message loop. Specifically:

The IME creates an invisible window running in a dedicated thread

Handles keyboard input capture through ::SetFocus and AssociateFocus when needed

Problem

  1. When using Microsoft Pinyin(During candidate selection phase), Pressing Shift to switch conversion mode to English;
  2. Results in complete loss of keyboard events (WM_KEYUP/DOWN)in the IME thread.
  3. And Shift key stops toggling conversion mode.

Contrastingly, iFly IME:

Doesn't send conversion status changes to TSF/IMM. Shows no issues under identical test conditions.

Debug Findings:

After the deadlock occurs, AssociateFocus with empty document will restores event flow, all blocked events flood in simultaneously.

Implementation Details

Full TextStoreAPC, IElementSink, ITfContextOwnerCompositionSink interfaces implemented.

Key Questions

  1. What TSF internal state could block keyboard event propagation?
  2. How might document focus ownership affect this behavior?
  3. Recommended patterns to prevent event pipeline blockage?
Share Improve this question edited Mar 22 at 15:57 jamie asked Mar 22 at 15:56 jamiejamie 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

I've identified the root cause: the ITfMessagePump interface is blocked. Previously, my message loop implementation was referenced from the Windows-classic-samples/winui/tsfpad codebase. Through extensive debugging, I've confirmed this issue stems from an implementation flaw in the TSF ITfMessagePump component.

Currently, my message loop:

bool done = false;
while (!done)
{
    BOOL fResult = 0;
    if (pMessagePump->PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE, &fResult) != S_OK)
    {
        done = true;
    }

    if (fResult != FALSE)
    {
        continue;
    }

    if (::GetMessageW(&msg, nullptr, 0, 0) <= 0)
    {
        break;
    }
    if (IsImeWantMessage(msg, pKeystrokeMgr)) // use ITfKeystrokeMgr test message is consumed by IME
    {
        continue;
    }

    TranslateMessage(&msg);
    DispatchMessage(&msg);
    if (msg.message == WM_QUIT)
    {
        done = true;
    }
    if (done)
    {
        break;
    }
}

本文标签: cTSF prevent keyboard event when use Microsoft PinyinStack Overflow