From b25281ff46027bb04446a162a0e979ee7dcbbacc Mon Sep 17 00:00:00 2001 From: fanlusky <1730976608@qq.com> Date: Mon, 6 Jul 2026 00:57:02 +0800 Subject: [PATCH] [Regression]: Fix the timeout issue when reading pipe reply packets for committing cloud candidates and newly created words. --- src/IPC/Ipc.cpp | 4 +--- src/Key/KeyEventSink.cpp | 19 +++++-------------- src/Key/KeyHandler.cpp | 10 ++++++++++ src/UI/CandidateListUIPresenter.cpp | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/IPC/Ipc.cpp b/src/IPC/Ipc.cpp index 00c0b060..3aa0dde0 100644 --- a/src/IPC/Ipc.cpp +++ b/src/IPC/Ipc.cpp @@ -652,7 +652,7 @@ void ClearNamedpipeDataIfExists(bool force) struct FanyImeNamedpipeDataToTsf *TryReadDataFromServerPipeWithTimeout() { std::pair ret = {0, L""}; - int timeoutMs = 10; // Default timeout 10ms + int timeoutMs = 50; // Default timeout 50ms if (!hFromServerPipe || hFromServerPipe == INVALID_HANDLE_VALUE) // Try to reconnect { @@ -707,8 +707,6 @@ struct FanyImeNamedpipeDataToTsf *TryReadDataFromServerPipeWithTimeout() } } - FANY_IPC_LOGF(L"[msime]: [ipc] TryReadDataFromServerPipeWithTimeout timeout after {} ms", timeoutMs); - namedpipeDataFromServer.msg_type = Global::DataFromServerMsgType::Normal; // Pipe timeout error wcscpy_s(namedpipeDataFromServer.candidate_string, L"T"); diff --git a/src/Key/KeyEventSink.cpp b/src/Key/KeyEventSink.cpp index 39b5966e..6715139e 100644 --- a/src/Key/KeyEventSink.cpp +++ b/src/Key/KeyEventSink.cpp @@ -414,10 +414,6 @@ STDAPI CMetasequoiaIME::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lP if (code == VK_SPACE && KeystrokeState.Function == FUNCTION_CONVERT) { - PerfTimer prefetchTimer; - FanyImeNamedpipeDataToTsf *receivedData = TryReadDataFromServerPipeWithTimeout(); - _QueuePendingServerCandidate(receivedData->msg_type, receivedData->candidate_string); - if (_msgWndHandle) { PostMessage(_msgWndHandle, WM_AsyncFinalizeCandidate, 0, 0); @@ -430,18 +426,13 @@ STDAPI CMetasequoiaIME::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lP std::wstring punctuationCommitText; const WCHAR *punctuation = _pCompositionProcessorEngine->GetPunctuation(wch); punctuationCommitText = punctuation ? punctuation : L""; - - double prefetchElapsedMs = 0; - if (_candidateMode != CANDIDATE_NONE && _pCandidateListUIPresenter && - Global::CommitWithFirstCandPunc.count(wch) > 0) + const bool shouldFinalizeFirstCandidateWithPunctuation = + _candidateMode != CANDIDATE_NONE && _pCandidateListUIPresenter && + Global::CommitWithFirstCandPunc.count(wch) > 0; + if (!shouldFinalizeFirstCandidateWithPunctuation) { - PerfTimer prefetchTimer; - FanyImeNamedpipeDataToTsf *receivedData = TryReadDataFromServerPipeWithTimeout(); - prefetchElapsedMs = prefetchTimer.ElapsedMs(); - punctuationCommitText = std::wstring(receivedData->candidate_string) + punctuationCommitText; + _QueuePendingPunctuationCommitText(punctuationCommitText.c_str()); } - - _QueuePendingPunctuationCommitText(punctuationCommitText.c_str()); PostMessage(_msgWndHandle, WM_AsyncPunctuationCommit, 0, 0); return S_OK; } diff --git a/src/Key/KeyHandler.cpp b/src/Key/KeyHandler.cpp index 6cd0ef00..59a89fc7 100644 --- a/src/Key/KeyHandler.cpp +++ b/src/Key/KeyHandler.cpp @@ -17,6 +17,12 @@ namespace { std::wstring g_toggleImeFallbackBuffer; + +bool IsTimeoutSentinelCandidate(UINT msgType, const WCHAR *pCandidateString) +{ + return msgType == Global::DataFromServerMsgType::Normal && pCandidateString != nullptr && + wcscmp(pCandidateString, L"T") == 0; +} } ////////////////////////////////////////////////////////////////////// @@ -801,6 +807,10 @@ HRESULT CMetasequoiaIME::_HandleCompositionPunctuation(TfEditCookie ec, _In_ ITf PerfTimer pipeReadTimer; struct FanyImeNamedpipeDataToTsf *receivedData = TryReadDataFromServerPipeWithTimeout(); pipeReadElapsedMs = pipeReadTimer.ElapsedMs(); + if (IsTimeoutSentinelCandidate(receivedData->msg_type, receivedData->candidate_string)) + { + receivedData = TryReadDataFromServerPipeWithTimeout(); + } punctuationStr = std::wstring(receivedData->candidate_string) + punctuationStr; } } diff --git a/src/UI/CandidateListUIPresenter.cpp b/src/UI/CandidateListUIPresenter.cpp index ec47d80a..fbef55ce 100644 --- a/src/UI/CandidateListUIPresenter.cpp +++ b/src/UI/CandidateListUIPresenter.cpp @@ -26,6 +26,14 @@ const int MOVEDOWN_ONE = 1; const int MOVETO_TOP = 0; const int MOVETO_BOTTOM = -1; +namespace +{ +bool IsTimeoutSentinelCandidate(UINT msgType, const std::wstring &candidateString) +{ + return msgType == Global::DataFromServerMsgType::Normal && candidateString == L"T"; +} +} + //+--------------------------------------------------------------------------- // // _HandleCandidateFinalize @@ -82,6 +90,12 @@ HRESULT CMetasequoiaIME::_HandleCandidateFinalize(TfEditCookie ec, _In_ ITfConte _TakePendingServerCandidate(&serverMsgType, &serverCandidateString); if (hasPrefetchedServerCandidate) { + if (IsTimeoutSentinelCandidate(serverMsgType, serverCandidateString)) + { + struct FanyImeNamedpipeDataToTsf *retryData = TryReadDataFromServerPipeWithTimeout(); + serverMsgType = retryData->msg_type; + serverCandidateString = retryData->candidate_string; + } } else { @@ -89,6 +103,12 @@ HRESULT CMetasequoiaIME::_HandleCandidateFinalize(TfEditCookie ec, _In_ ITfConte struct FanyImeNamedpipeDataToTsf *receivedData = TryReadDataFromServerPipeWithTimeout(); serverMsgType = receivedData->msg_type; serverCandidateString = receivedData->candidate_string; + if (IsTimeoutSentinelCandidate(serverMsgType, serverCandidateString)) + { + struct FanyImeNamedpipeDataToTsf *retryData = TryReadDataFromServerPipeWithTimeout(); + serverMsgType = retryData->msg_type; + serverCandidateString = retryData->candidate_string; + } } if (serverMsgType == Global::DataFromServerMsgType::OutofRange) // Candidate index out of range