Fix the issue where the candidate window cannot be pulled up when switching back from Microsoft's emoji panel, and deeply optimize the stability of IPC connections.

This commit is contained in:
fanlusky committed 2026-07-16 21:44:07 +08:00
1 parent 6555913a72
commit 4f2fe01dc4
23 files changed
+4534 -1074

No files matched your search

+116 -34
View File
@@ -42,22 +42,39 @@ STDAPI CMetasequoiaIME::OnUninitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr)
// focus document, or now no document holds the input focus.
//----------------------------------------------------------------------------
STDAPI CMetasequoiaIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus)
{
pDocMgrPrevFocus;
if (pDocMgrFocus && !Global::g_connected)
{
Global::g_connected = true;
PostMessage(_msgWndHandle, WM_ConnectNamedpipe, 0, 0);
}
else if (!pDocMgrFocus && Global::g_connected)
{
Global::g_connected = false;
PostMessage(_msgWndHandle, WM_DisconnectNamedpipe, 0, 0);
}
_InitTextEditSink(pDocMgrFocus);
STDAPI CMetasequoiaIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus)
{
if (!IsNamedpipeFocusStateOwner(this))
{
return S_OK;
}
pDocMgrPrevFocus;
const bool windowsTextInputHostTransition =
_focusLostToWindowsTextInputHost ||
_CaptureWindowsTextInputHostFocusLoss();
// bcaf34e used document focus as the authoritative reconnect boundary.
// The modern protocol preserves that behavior with a new activation epoch
// on the existing healthy transport; EnsureNamedpipeFocusSessionActivated
// physically reopens a channel as well when its health check fails.
if (pDocMgrFocus &&
(!Global::g_connected || windowsTextInputHostTransition))
{
Global::g_connected = true;
_workerCommitReady.store(false, std::memory_order_release);
RequireNamedpipeFocusActivation();
PostMessage(_msgWndHandle, WM_ConnectNamedpipe, 0, 0);
_focusLostToWindowsTextInputHost = false;
}
else if (!pDocMgrFocus && Global::g_connected)
{
MarkNamedpipeFocusLost();
Global::g_connected = false;
PostMessage(_msgWndHandle, WM_DisconnectNamedpipe, 0, 0);
}
_InitTextEditSink(pDocMgrFocus);
_UpdateLanguageBarOnSetFocus(pDocMgrFocus);
@@ -92,13 +109,13 @@ STDAPI CMetasequoiaIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDo
_pDocMgrLastFocused = pDocMgrFocus;
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->AddRef();
}
return S_OK;
}
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->AddRef();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
@@ -107,11 +124,10 @@ STDAPI CMetasequoiaIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDo
// Sink called by the framework when a context is pushed.
//----------------------------------------------------------------------------
STDAPI CMetasequoiaIME::OnPushContext(_In_ ITfContext *pContext)
{
pContext;
return E_NOTIMPL;
STDAPI CMetasequoiaIME::OnPushContext(_In_ ITfContext *pContext)
{
_HandleFocusedContextStackChange(pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
@@ -121,12 +137,78 @@ STDAPI CMetasequoiaIME::OnPushContext(_In_ ITfContext *pContext)
// Sink called by the framework when a context is popped.
//----------------------------------------------------------------------------
STDAPI CMetasequoiaIME::OnPopContext(_In_ ITfContext *pContext)
{
pContext;
return E_NOTIMPL;
}
STDAPI CMetasequoiaIME::OnPopContext(_In_ ITfContext *pContext)
{
_HandleFocusedContextStackChange(pContext);
return S_OK;
}
void CMetasequoiaIME::_HandleFocusedContextStackChange(_In_opt_ ITfContext *changedContext)
{
if (!IsNamedpipeFocusStateOwner(this) || changedContext == nullptr ||
_pThreadMgr == nullptr)
{
return;
}
ITfDocumentMgr *changedDocument = nullptr;
ITfDocumentMgr *focusedDocument = nullptr;
if (FAILED(changedContext->GetDocumentMgr(&changedDocument)) ||
changedDocument == nullptr ||
FAILED(_pThreadMgr->GetFocus(&focusedDocument)) ||
focusedDocument == nullptr || changedDocument != focusedDocument)
{
if (changedDocument)
{
changedDocument->Release();
}
if (focusedDocument)
{
focusedDocument->Release();
}
return;
}
ITfContext *newTopContext = nullptr;
if (FAILED(focusedDocument->GetTop(&newTopContext)) || newTopContext == nullptr)
{
focusedDocument->Release();
changedDocument->Release();
return;
}
const bool topContextChanged = newTopContext != _pTextEditSinkContext;
newTopContext->Release();
if (!topContextChanged)
{
focusedDocument->Release();
changedDocument->Release();
return;
}
// Capture the old composition owner before rebinding the text-edit sink.
// A pushed modal/context (or a popped editor context) must never inherit
// replies or queued edit sessions that belonged to the previous top.
ITfContext *resetContext = _pContext ? _pContext : _pTextEditSinkContext;
if (resetContext)
{
resetContext->AddRef();
}
else
{
resetContext = changedContext;
resetContext->AddRef();
}
_ClearDeferredKeyDowns();
MarkNamedpipeSessionDirtyForOwner(this);
const UINT resetToken = _localSessionResetToken.load(std::memory_order_acquire);
_RequestLocalSessionReset(resetContext, resetToken);
_InitTextEditSink(focusedDocument);
resetContext->Release();
focusedDocument->Release();
changedDocument->Release();
}
//+---------------------------------------------------------------------------
//