Skip to content

Fix search box losing characters typed through an IME - #1137

Open
xiaoxidashen wants to merge 1 commit into
sabrogden:masterfrom
xiaoxidashen:fix/ime-search-lost-chars
Open

Fix search box losing characters typed through an IME#1137
xiaoxidashen wants to merge 1 commit into
sabrogden:masterfrom
xiaoxidashen:fix/ime-search-lost-chars

Conversation

@xiaoxidashen

Copy link
Copy Markdown

Problem

Open the paste window with the hotkey and type into it with an IME active. Type
abcd, let the IME hold the composition, then press Enter to commit. Only a
reaches the search box — bcd are silently dropped. Typing abcd a second time
works, because the search box now already has focus.

Cause

When the paste window opens, focus is on the list control. Committing a string
from an IME queues the whole string as a burst of WM_CHAR messages that all
carry the list control in pMsg->hwnd.

CQPasteWnd::PreTranslateMessage gated the search-box redirect on
GetFocus() == m_lstHeader. The first character passed that check and called
m_search.SetFocus(). From the second character on the check no longer matched,
so those messages fell through to DispatchMessage, which routes by
pMsg->hwnd — back to the list control, where they were consumed as incremental
search.

Typing without an IME hides the bug: each keystroke's message is generated at the
moment the key goes down, by which time the previous character has already moved
focus.

Fix

  • Key the check on pMsg->hwnd instead of GetFocus(), so the whole burst is
    captured no matter where focus has moved.
  • Append instead of overwrite — only the first character of a run clears the box,
    preserving the "typing in the list starts a new search" behaviour.
  • Place the caret at the end of the text. The old SetSel(1, 1) hardcoded offset
    1, which is wrong as soon as the text is longer than one character.

SetWindowText is kept rather than ReplaceSel so the existing manual
OnSearchEditChange() call still fires exactly once per character —
ReplaceSel would raise EN_CHANGE and search twice for every keystroke.

Testing

Built Release x64 and ran it as the installed Ditto. With an IME active, abcd

  • Enter now lands all four characters, with the caret at the end. Plain ASCII
    typing and the existing "start typing in the list to search" behaviour are
    unchanged.

When the paste window opens, focus is on the list control. Committing a
string from an IME queues the whole string as a burst of WM_CHAR
messages that all carry the list control in pMsg->hwnd. The first
character moved focus to the search box, after which the GetFocus()
check no longer matched, so the remaining characters were dispatched to
the list control's incremental search and lost. Typing without an IME
did not show this, because each keystroke's message is generated after
the previous one has already moved focus.

Key the check on pMsg->hwnd so the whole burst is captured, append
rather than overwrite (only the first character of a run clears the
box), and place the caret at the end of the text instead of a hardcoded
offset.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant