Skip to content

Commit

Permalink
1、添加强制关闭游戏模式的逻辑
Browse files Browse the repository at this point in the history
2、托盘右键菜单位置调整
3、修复Firefox设置搜索框点叉号应用崩溃
  • Loading branch information
Techince committed Nov 23, 2023
1 parent 66d83ea commit 86245ec
Show file tree
Hide file tree
Showing 24 changed files with 306 additions and 96 deletions.
8 changes: 6 additions & 2 deletions WeaselTSF/CandidateList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,10 +388,13 @@ void CCandidateList::StartUI()
{
_ui->ctx().cinfo.candies.push_back(std::wstring(L" "));
pUIElementMgr->UpdateUIElement(uiid);
}
_ui->ctx().cinfo.candies.clear();
}
#ifdef TEST
LOG(INFO) << std::format("From CCandidateList::StartUI. _pbShow = {}, hr = 0x{:X}, id = 0x{:X}", _pbShow, (unsigned)hr, (unsigned)uiid);
#endif // TEST
if (_tsf.GetBit(WeaselFlag::GAME_MODE_SELF_REDRAW))
_pbShow = true;
if (_pbShow)
{
if (_tsf.GetBit(WeaselFlag::GAME_MODE))
Expand Down Expand Up @@ -422,7 +425,8 @@ void CCandidateList::EndUI()
return;
if (emgr != NULL)
{
if (SUCCEEDED(emgr->EndUIElement(uiid)))
emgr->EndUIElement(uiid);
if (_tsf.GetBit(WeaselFlag::GAME_WAR3))
_tsf.SetBit(WeaselFlag::CLEAR_CAND_LIST);
}
#ifdef TEST
Expand Down
46 changes: 46 additions & 0 deletions WeaselTSF/CleanupContextDurationSink.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module;
#include "stdafx.h"
#include "test.h"
#ifdef TEST
#define WEASEL_ENABLE_LOGGING
#include "logging.h"
#endif // TEST
module WeaselTSF;

STDMETHODIMP WeaselTSF::OnStartCleanupContext()
{
#ifdef TEST
LOG(INFO) << std::format("From WeaselTSF::OnStartCleanupContext.");
#endif // TEST
return S_OK;
}

STDMETHODIMP WeaselTSF::OnEndCleanupContext()
{
#ifdef TEST
LOG(INFO) << std::format("From WeaselTSF::OnEndCleanupContext.");
#endif // TEST
return S_OK;
}

BOOL WeaselTSF::_InitCleanupContextDurationSink()
{
HRESULT hr{E_FAIL};
com_ptr<ITfSourceSingle> pSourceSingle;

if (SUCCEEDED(_pThreadMgr->QueryInterface(&pSourceSingle)))
{
hr = pSourceSingle->AdviseSingleSink(_tfClientId, IID_ITfCleanupContextDurationSink, (ITfCleanupContextDurationSink*)this);
}
return SUCCEEDED(hr);
}

void WeaselTSF::_UninitCleanupContextDurationSink()
{
com_ptr<ITfSourceSingle> pSourceSingle;

if (SUCCEEDED(_pThreadMgr->QueryInterface(&pSourceSingle)))
{
pSourceSingle->UnadviseSingleSink(_tfClientId, IID_ITfCleanupContextDurationSink);
}
}
107 changes: 76 additions & 31 deletions WeaselTSF/Composition.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import ResponseParser;
import CandidateList;
import WeaselUtility;

// #pragma comment(lib, "Oleacc.lib")

export
{
/* Start Composition */
Expand Down Expand Up @@ -63,6 +65,8 @@ export

/* ITfEditSession */
STDMETHODIMP DoEditSession(TfEditCookie ec);
// RECT GetOleAccLocation(HWND hwnd);
void CalculatePosition(_Inout_opt_ RECT& rc);

private:
com_ptr<ITfContextView> _pContextView;
Expand Down Expand Up @@ -109,10 +113,20 @@ STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)
HRESULT hr = E_FAIL;
com_ptr<ITfInsertAtSelection> pInsertAtSelection;
com_ptr<ITfRange> pRangeComposition;
if (FAILED(_pContext->QueryInterface(&pInsertAtSelection)))
if (FAILED(hr = _pContext->QueryInterface(&pInsertAtSelection)))
{
#ifdef TEST
LOG(INFO) << std::format("From CStartCompositionEditSession::DoEditSession. QueryInterface: hr = 0x{:X}", (unsigned)hr);
#endif // TEST
return hr;
if (FAILED(pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeComposition)))
}
if (FAILED(hr = pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeComposition)))
{
#ifdef TEST
LOG(INFO) << std::format("From CStartCompositionEditSession::DoEditSession. InsertTextAtSelection: hr = 0x{:X}", (unsigned)hr);
#endif // TEST
return hr;
}

com_ptr<ITfContextComposition> pContextComposition;
com_ptr<ITfComposition> pComposition;
Expand Down Expand Up @@ -196,10 +210,19 @@ STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec)
hr = _pContext->GetEnd(ec, &pRangeComposition);
}

HWND hwnd;
_pContextView->GetWnd(&hwnd);
_pTextService->SetHWND(hwnd);

std::wstring name{};
name.reserve(512);
GetClassName(hwnd, name.data(), name.capacity());
name = name.data();

hr = _pContextView->GetTextExt(ec, pRangeComposition, &rc, &fClipped);
#ifdef TEST
LOG(INFO) << std::format("From CGetTextExtentEditSession::DoEditSession. rc.left = {}, rc.top = {}, hr = {:#x}, fClipped = {:s}",
rc.left, rc.top, (unsigned)hr, (bool)fClipped);
LOG(INFO) << std::format("From CGetTextExtentEditSession::DoEditSession. rc.left = {}, rc.top = {}, hr = {:#x}, fClipped = {:s}, className = {}",
rc.left, rc.top, (unsigned)hr, (bool)fClipped, to_string(name, CP_UTF8));
#endif // TEST
if (hr == 0x80040057)
{
Expand All @@ -209,33 +232,7 @@ STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec)

if (SUCCEEDED(hr) && (rc.left != 0 && rc.top != 0))
{
_pTextService->SetRect(rc);

if (_pTextService->GetBit(WeaselFlag::INLINE_PREEDIT)) // 仅嵌入式候选框记录首码坐标
{
static RECT rcFirst{};
if (_pTextService->GetBit(WeaselFlag::FIRST_KEY_COMPOSITION)) // 记录首码坐标
{
rcFirst = rc;
}
else if (_pTextService->GetBit(WeaselFlag::FOCUS_CHANGED)) // 焦点变化时记录坐标
{
rcFirst = rc;
_pTextService->ResetBit(WeaselFlag::FOCUS_CHANGED);
}
else if (5 < abs(rcFirst.top - rc.top)) // 个别应用获取坐标时文交替出现Y轴坐标相差±5,需要过滤掉
{
rcFirst = rc;
}
else if (rc.left < rcFirst.left) // 换行时更新坐标
{
rcFirst = rc;
}
else // 非首码时用首码坐标替换
{
rc = rcFirst;
}
}
CalculatePosition(rc);
_pTextService->_SetCompositionPosition(rc);
#ifdef TEST
LOG(INFO) << std::format("From CGetTextExtentEditSession::DoEditSession. rc.left = {}, rc.top = {}", rc.left, rc.top);
Expand All @@ -249,6 +246,54 @@ STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec)
return hr;
}

void CGetTextExtentEditSession::CalculatePosition(RECT& rc)
{
// 保存实时坐标,作为下一次坐标的备用方案
_pTextService->SetRect(rc);

if (_pTextService->GetBit(WeaselFlag::INLINE_PREEDIT)) // 仅嵌入式候选框记录首码坐标
{
static RECT rcFirst{};
if (_pTextService->GetBit(WeaselFlag::FIRST_KEY_COMPOSITION)) // 记录首码坐标
{
rcFirst = rc;
}
else if (_pTextService->GetBit(WeaselFlag::FOCUS_CHANGED)) // 焦点变化时记录坐标
{
rcFirst = rc;
_pTextService->ResetBit(WeaselFlag::FOCUS_CHANGED);
}
else if (5 < abs(rcFirst.top - rc.top)) // 个别应用获取坐标时文交替出现Y轴坐标相差±5,需要过滤掉
{
rcFirst = rc;
}
else if (rc.left < rcFirst.left) // 换行时更新坐标
{
rcFirst = rc;
}
else // 非首码时用首码坐标替换
{
rc = rcFirst;
}
}
}

//RECT CGetTextExtentEditSession::GetOleAccLocation(HWND hwnd)
//{
// RECT rc{};
// com_ptr<IAccessible> pAccessible;
// if (SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_CARET, IID_IAccessible, (VOID**)&pAccessible)) && pAccessible)
// {
// LONG x, y, cx, cy;
// VARIANT var{};
// if (SUCCEEDED(pAccessible->accLocation(&x, &y, &cx, &cy, var)))
// {
// SetRect(&rc, x, y, x + cx, y + cy);
// }
// }
// return rc;
//}

STDAPI CInlinePreeditEditSession::DoEditSession(TfEditCookie ec)
{
std::wstring preedit = _context->preedit.str;
Expand Down
80 changes: 79 additions & 1 deletion WeaselTSF/CompositionTSF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ void WeaselTSF::_StartComposition(ITfContext* pContext, bool not_inline_preedit)
auto ret = pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr);
SetBit(WeaselFlag::FIRST_KEY_COMPOSITION);
#ifdef TEST
LOG(INFO) << std::format("From _StartComposition. hr = {:#x}, ret = {:#x}", (unsigned)hr, (unsigned)ret);
LOG(INFO) << std::format("From _StartComposition. hr = {:#x}, ret = {:#x}", (unsigned)hr, (unsigned)ret);
#endif // TEST

if (SUCCEEDED(ret) && FAILED(hr))
{
m_client.ClearComposition();
_cand->Destroy();
_FinalizeComposition();
RetryFailedEvent();
}
}
}

Expand Down Expand Up @@ -212,4 +220,74 @@ bool WeaselTSF::RetryKey()
send = SendInput(inputs.size(), inputs.data(), sizeof(INPUT));

return send == 1;
}

//获取程序当前所在显示器的分辨率大小,可以动态的获取程序所在显示器的分辨率
SIZE WeaselTSF::GetScreenResolution() {
SIZE size{};
if (!m_hwnd)
return size;

//MONITOR_DEFAULTTONEAREST 返回值是最接近该点的屏幕句柄
//MONITOR_DEFAULTTOPRIMARY 返回值是主屏幕的句柄
//如果其中一个屏幕包含该点,则返回值是该屏幕的HMONITOR句柄。如果没有一个屏幕包含该点,则返回值取决于dwFlags的值
HMONITOR hMonitor = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFOEX miex;
miex.cbSize = sizeof(miex);
if (!GetMonitorInfo(hMonitor, &miex))
return size;

DEVMODE dm;
dm.dmSize = sizeof(dm);
dm.dmDriverExtra = 0;

//ENUM_CURRENT_SETTINGS 检索显示设备的当前设置
//ENUM_REGISTRY_SETTINGS 检索当前存储在注册表中的显示设备的设置
if (!EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm))
return size;

size.cx = dm.dmPelsWidth;
size.cy = dm.dmPelsHeight;
return size;
}


void WeaselTSF::RetryFailedEvent()
{
SIZE size = GetScreenResolution();
if (size.cx == 0 && size.cy == 0)
return;

std::array<INPUT, 5> inputs;
POINT ptCursor{};
GetCursorPos(&ptCursor);

inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dx = m_rcFallback.left / static_cast<double>(size.cx) * 65535;
inputs[0].mi.dy = m_rcFallback.top / static_cast<double>(size.cy) * 65535;
inputs[0].mi.mouseData = 0;
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
inputs[0].mi.time = 0;

inputs[1].type = INPUT_MOUSE;
inputs[1].mi.mouseData = 0;
inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
inputs[1].mi.time = 0;

inputs[2].type = INPUT_MOUSE;
inputs[2].mi.mouseData = 0;
inputs[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
inputs[2].mi.time = 0;

inputs[3].type = INPUT_MOUSE;
inputs[3].mi.dx = ptCursor.x / static_cast<double>(size.cx) * 65535;
inputs[3].mi.dy = ptCursor.y / static_cast<double>(size.cy) * 65535;
inputs[3].mi.mouseData = 0;
inputs[3].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
inputs[3].mi.time = 0;

inputs[4].type = INPUT_KEYBOARD;
inputs[4].ki = { _lastKey, _lastKey, 0, 0, 0 };

SendInput(inputs.size(), inputs.data(), sizeof(INPUT));
}
2 changes: 1 addition & 1 deletion WeaselTSF/EditSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ STDAPI WeaselTSF::DoEditSession(TfEditCookie ec)
_EndComposition(_pEditSessionContext, false);

// 消除War3打字上屏后残留的空白框
if (GetBit(WeaselFlag::GAME_WAR3) && GetBit(WeaselFlag::CLEAR_CAND_LIST) && context->cinfo.candies.empty())
if (GetBit(WeaselFlag::CLEAR_CAND_LIST) && context->cinfo.candies.empty())
{
ResetBit(WeaselFlag::CLEAR_CAND_LIST);
unsigned send{};
Expand Down
30 changes: 15 additions & 15 deletions WeaselTSF/KeyEventSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ STDAPI WeaselTSF::OnTestKeyUp(ITfContext* pContext, WPARAM wParam, LPARAM lParam
*pfEaten = TRUE;
return S_OK;
}
if (GetBit(WeaselFlag::GAME_MODE) && wParam == 0x0C)
if (GetBit(WeaselFlag::GAME_WAR3) && wParam == VK_CLEAR)
{
ResetBit(WeaselFlag::CLEAR_DOWN);
_UpdateComposition(pContext);
Expand Down Expand Up @@ -211,29 +211,29 @@ STDAPI WeaselTSF::OnPreservedKey(ITfContext* pContext, REFGUID rguid, BOOL* pfEa
*pfEaten = FALSE;
if (IsEqualGUID(rguid, WEASEL_UILESS_MODE_PRESERVED_KEY))
{
_bitset.flip(static_cast<int>(WeaselFlag::GAME_MODE));
if (GetBit(WeaselFlag::GAME_MODE))
{
SetBit(WeaselFlag::GAME_MODE_SELF_REDRAW);
ResetBit(WeaselFlag::CARET_FOLLOWING);
_cand->SetCaretFollowing(GetBit(WeaselFlag::CARET_FOLLOWING));
}
else
{
ResetBit(WeaselFlag::GAME_MODE_SELF_REDRAW);
}
Flip(WeaselFlag::GAME_MODE);
}
else if (IsEqualGUID(rguid, WEASEL_CARET_FOLLOWING_PRESERVED_KEY))
{
_bitset.flip(static_cast<int>(WeaselFlag::CARET_FOLLOWING));
Flip(WeaselFlag::CARET_FOLLOWING);
_cand->SetCaretFollowing(GetBit(WeaselFlag::CARET_FOLLOWING));
}
else if (IsEqualGUID(rguid, WEASEL_DAEMON_PRESERVED_KEY))
{
_bitset.flip(static_cast<int>(WeaselFlag::DAEMON_ENABLE));
Flip(WeaselFlag::DAEMON_ENABLE);
if (_pGlobalCompartment)
{
VARIANT var{};
var.vt = VT_I4;
if (GetBit(WeaselFlag::DAEMON_ENABLE))
{
var.lVal = 0xFC01;
}
else
{
var.lVal = 0xFC00;
}
_pGlobalCompartment->SetValue(_tfClientId, &var);
UpdateGlobalCompartment(true);
}
}
return S_OK;
Expand Down
Loading

0 comments on commit 86245ec

Please sign in to comment.