[feat]: IPC support for uwp/metro apps

This commit is contained in:
fanlumaster committed 2025-05-06 05:44:00 +08:00
1 parent 29aeb8e291
commit 009f009905
6 files changed
+120 -70

No files matched your search

@@ -396,6 +396,30 @@ void CCompositionProcessorEngine::GetReadingStrings(_Inout_ CSampleImeArray<CStr
void CCompositionProcessorEngine::GetCandidateList(_Inout_ CSampleImeArray<CCandidateListItem> *pCandidateList,
BOOL isIncrementalWordSearch, BOOL isWildcardSearch)
{
//
// We don't use dictionary to get candidate list
//
const std::wstring keystrokeStr(_keystrokeBuffer.Get(), _keystrokeBuffer.GetLength());
CCandidateListItem *pLI = nullptr;
pLI = pCandidateList->Append();
if (pLI)
{
pLI->_ItemString.Set(keystrokeStr.c_str(), keystrokeStr.size());
pLI->_FindKeyCode.Set(keystrokeStr.c_str(), keystrokeStr.size());
}
for (UINT index = 0; index < pCandidateList->Count();)
{
CCandidateListItem *pLI = pCandidateList->GetAt(index);
CStringRange startItemString;
CStringRange endItemString;
startItemString.Set(pLI->_ItemString.Get(), 1);
endItemString.Set(pLI->_ItemString.Get() + pLI->_ItemString.GetLength() - 1, 1);
index++;
}
return;
if (!IsDictionaryAvailable())
{
return;
+6
View File
@@ -232,6 +232,10 @@ STDAPI CSampleIME::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, D
_tfClientId = tfClientId;
_dwActivateFlags = dwFlags;
OutputDebugString(L"CSampleIME::ActivateEx\n");
HWND hwnd = GetForegroundWindow();
GetWindowText(hwnd, Global::app_name, 512);
// Set up spdlog
// auto logger = spdlog::basic_logger_mt("file_logger", ::LogFilePath);
// spdlog::set_default_logger(logger);
@@ -326,6 +330,8 @@ STDAPI CSampleIME::Deactivate()
spdlog::info("Close IPC!");
#endif
OutputDebugString(L"CSampleIME::Deactivate\n");
// Clean spdlog
spdlog::drop("file_logger");
+70 -68
View File
@@ -1,17 +1,19 @@
#include "Ipc.h"
#include <debugapi.h>
#include <handleapi.h>
#include <minwindef.h>
#include <winnt.h>
#include <winuser.h>
#include "fmt/xchar.h"
#include "spdlog/spdlog.h"
#include "Globals.h"
static HANDLE hMapFile;
static HANDLE hMapFile = nullptr;
static void *pBuf;
static FanyImeSharedMemoryData *sharedData;
static bool canUseSharedMemory = true;
// static HANDLE hPipe;
static HANDLE hPipe = nullptr;
static bool canUseNamedPipe = true;
static FanyImeNamedpipeData namedpipeData;
@@ -19,50 +21,28 @@ static FanyImeNamedpipeData namedpipeData;
int InitIpc()
{
//
// Shared memory
// Shared memory, open here
//
hMapFile = CreateFileMappingW( //
INVALID_HANDLE_VALUE, //
nullptr, //
PAGE_READWRITE, //
0, //
static_cast<DWORD>(BUFFER_SIZE), //
FANY_IME_SHARED_MEMORY //
); //
hMapFile = OpenFileMappingW( //
FILE_MAP_ALL_ACCESS, //
FALSE, //
FANY_IME_SHARED_MEMORY //
);
/*
if (!hMapFile)
{
// Error handling
canUseSharedMemory = false;
spdlog::info("CreateFileMapping error: {}", GetLastError());
//
// Shared memory is not available, try to use namedpipe
//
InitNamedpipe();
//
// Shared memory is not available, try to use namedpipe
//
hPipe = CreateFile( //
FANY_IME_NAMED_PIPE, //
GENERIC_READ | GENERIC_WRITE, //
0, //
NULL, //
OPEN_EXISTING, //
0, //
NULL //
);
if (!hMapFile)
{
OutputDebugString(L"CreateFileMapping failed\n");
// Error handling
canUseSharedMemory = false;
spdlog::info("CreateFileMapping error: {}", GetLastError());
if (hPipe == INVALID_HANDLE_VALUE)
{
canUseNamedPipe = false;
spdlog::error("Failed to open pipe!");
return -1;
}
else
{
}
return 0;
}
*/
return 0;
}
bool alreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
@@ -90,22 +70,29 @@ int InitIpc()
sharedData->point[1] = 100;
}
//
// Events
//
for (const auto &eventName : FANY_IME_EVENT_ARRAY)
return 0;
}
int InitNamedpipe()
{
hPipe = CreateFile( //
FANY_IME_NAMED_PIPE, //
GENERIC_READ | GENERIC_WRITE, //
0, //
nullptr, //
OPEN_EXISTING, //
0, //
nullptr //
);
if (!hPipe)
{
canUseNamedPipe = false;
OutputDebugString(L"Connect to namedpipe failed\n");
return -1;
}
else
{
HANDLE hEvent = CreateEventW( //
nullptr, //
FALSE, //
FALSE, // Auto reset
eventName.c_str() //
); //
if (!hEvent)
{
// Error handling
spdlog::info("CreateEvent error: {}", Global::wstring_to_string(eventName));
}
}
return 0;
@@ -114,15 +101,9 @@ int InitIpc()
int CloseIpc()
{
//
// Named pipe
// Namedpipe
//
/*
if (hPipe)
{
CloseHandle(hPipe);
hPipe = nullptr;
}
*/
CloseNamedpipe();
if (!canUseSharedMemory)
{
@@ -163,6 +144,16 @@ int CloseIpc()
return 0;
}
int CloseNamedpipe()
{
if (hPipe)
{
CloseHandle(hPipe);
hPipe = nullptr;
}
return 0;
}
int WriteDataToSharedMemory( //
UINT keycode, //
UINT modifiers_down, //
@@ -269,10 +260,15 @@ int WriteDataToNamedPipe( //
int SendKeyEventToUIProcess()
{
// OutputDebugString(fmt::format(L"SendKeyEventToUIProcess, canUseSharedMemory = {}, canUseNamedPipe = {}\n",
// canUseSharedMemory, canUseNamedPipe)
// .c_str());
if (!canUseSharedMemory)
{
// OutputDebugString(L"SendKeyEventToUIProcessViaNamedPipe\n");
if (canUseNamedPipe)
{
// OutputDebugString(L"Really SendKeyEventToUIProcessViaNamedPipe \n");
return SendKeyEventToUIProcessViaNamedPipe();
}
}
@@ -402,8 +398,14 @@ int SendMoveCandidateWndEventToUIProcess()
void SendToNamedpipe()
{
HANDLE hPipe = CreateFileW(L"\\\\.\\pipe\\FanyImeNamedPipe", GENERIC_READ | GENERIC_WRITE, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
if (!canUseNamedPipe)
{
return;
}
if (!hPipe)
{
return;
}
DWORD bytesWritten = 0;
BOOL ret = WriteFile( //
hPipe, //
@@ -418,7 +420,6 @@ void SendToNamedpipe()
DWORD err = GetLastError();
spdlog::info("WriteFile error: {}", err);
}
CloseHandle(hPipe);
}
/**
@@ -430,6 +431,7 @@ void SendToNamedpipe()
*/
int SendKeyEventToUIProcessViaNamedPipe()
{
// OutputDebugString(L"first SendKeyEventToUIProcessViaNamedPipe\n");
if (!canUseNamedPipe)
{
return -1;
+11
View File
@@ -30,6 +30,12 @@ struct FanyImeSharedMemoryData
// For uwp/metro apps, here we do not need candidate_string and selected_candiate_string,
// just let server process to handle them
//
// event_type
// 0: FanyImeKeyEvent
// 1: FanyHideCandidateWndEvent
// 2: FanyShowCandidateWndEvent
// 3: FanyMoveCandidateWndEvent
//
struct FanyImeNamedpipeData
{
UINT event_type;
@@ -41,7 +47,10 @@ struct FanyImeNamedpipeData
};
int InitIpc();
int InitNamedpipe();
int CloseIpc();
int CloseNamedpipe();
//
// For shared memory
//
@@ -84,4 +93,6 @@ inline std::wstring PinyinString = L"";
inline int firefox_like_cnt = 0; // Apps like firefox, e.g. firefox, zen...
inline std::wstring current_process_name = L"";
inline wchar_t app_name[512] = {0};
} // namespace Global
+4 -1
View File
@@ -5,9 +5,11 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Ipc.h"
#include "Private.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
#include <debugapi.h>
//+---------------------------------------------------------------------------
//
@@ -32,7 +34,7 @@ STDAPI CSampleIME::OnSetThreadFocus()
pCandidateListDocumentMgr->Release();
}
}
InitNamedpipe();
return S_OK;
}
@@ -64,6 +66,7 @@ STDAPI CSampleIME::OnKillThreadFocus()
}
_pCandidateListUIPresenter->OnKillThreadFocus();
}
CloseNamedpipe();
return S_OK;
}
+5 -1
View File
@@ -6,6 +6,7 @@
#include "CompositionProcessorEngine.h"
#include "SampleIMEBaseStructure.h"
#include "define.h"
#include <debugapi.h>
#include <intsafe.h>
#include <minwindef.h>
#include <winuser.h>
@@ -833,7 +834,8 @@ HRESULT CCandidateListUIPresenter::_StartCandidateList(TfClientId tfClientId, _I
hr = MakeCandidateWindow(pContextDocument, wndWidth);
if (FAILED(hr))
{
goto Exit;
OutputDebugString(L"MakeCandidateWindow failed\n");
// goto Exit;
}
// Show(_isShowMode);
@@ -871,6 +873,7 @@ void CCandidateListUIPresenter::_EndCandidateList()
void CCandidateListUIPresenter::_NotifyUI()
{
// OutputDebugString(L"_NotifyUI\n");
CStringRange keyStringBuffer = _pTextService->GetCompositionProcessorEngine()->GetKeystrokeBuffer();
std::wstring pinyinString(keyStringBuffer.Get(), keyStringBuffer.GetLength());
Global::PinyinLength = pinyinString.length();
@@ -1073,6 +1076,7 @@ void CCandidateListUIPresenter::_MoveWindowToTextExt()
VOID CCandidateListUIPresenter::_LayoutChangeNotification(_In_ RECT *lpRect)
{
// OutputDebugStringW(L"LayoutChangeNotification\n");
#ifdef FANY_DEBUG
spdlog::info("_LayoutChangeNotification firefox cnt {}", Global::firefox_like_cnt);
#endif