diff --git a/src/Edit/GetTextExtentEditSession.cpp b/src/Edit/GetTextExtentEditSession.cpp index 66d711c2..45e6e733 100644 --- a/src/Edit/GetTextExtentEditSession.cpp +++ b/src/Edit/GetTextExtentEditSession.cpp @@ -54,8 +54,9 @@ STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec) return S_OK; } - Global::Point[0] = rc.left * Global::DpiScale; - Global::Point[1] = rc.bottom * Global::DpiScale; + const POINT anchor = GetPhysicalTextAnchor(_pContextView, rc); + Global::Point[0] = anchor.x; + Global::Point[1] = anchor.y; if (Global::current_process_name == Global::ZEN_BROWSER) { Global::firefox_like_cnt++; diff --git a/src/Global/FanyDefines.h b/src/Global/FanyDefines.h index 64ccaef7..fca5e9da 100644 --- a/src/Global/FanyDefines.h +++ b/src/Global/FanyDefines.h @@ -10,7 +10,6 @@ inline std::wstring ZEN_BROWSER = L"zen.exe"; // inline std::unordered_set VSCodeSeries = {L"Code.exe", L"Code - Insiders.exe", L"VSCodium.exe"}; // inline bool IsVSCodeLike = false; inline LONG INVALID_Y = -100000; -inline thread_local float DpiScale = 1.0f; } // namespace Global namespace GlobalSettings diff --git a/src/IME/MetasequoiaIME.cpp b/src/IME/MetasequoiaIME.cpp index 18faa8d1..afab2b07 100644 --- a/src/IME/MetasequoiaIME.cpp +++ b/src/IME/MetasequoiaIME.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -23,7 +22,6 @@ #include "Utils/FanyUtils.h" #include "../Utils/PerfTimer.h" -#pragma comment(lib, "Shcore.lib") #pragma comment(lib, "Shell32.lib") #pragma comment(lib, "Ole32.lib") @@ -1439,36 +1437,6 @@ STDAPI CMetasequoiaIME::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClient // uses terminal activation/deactivation to reconcile floating-toolbar // visibility and status snapshots to update its displayed mode. - { - HWND hwndTarget = GetFocus(); - if (!hwndTarget) - { - hwndTarget = GetForegroundWindow(); - } - - // Always refresh: a prior UNAWARE host can leave a stale DpiScale on this - // thread, which then mis-multiplies GetTextExt screen coords for DPI-aware - // apps (Word/Excel) — especially damaging on extended displays with - // negative virtual-desktop X. - Global::DpiScale = 1.0f; - - if (hwndTarget) - { - DPI_AWARENESS awareness = GetAwarenessFromDpiAwarenessContext(GetWindowDpiAwarenessContext(hwndTarget)); - - if (awareness == DPI_AWARENESS_UNAWARE) - { - /* 宿主是非感知程序,需要反向缩放 */ - DPI_AWARENESS_CONTEXT oldCtx = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); - HMONITOR hMon = MonitorFromWindow(hwndTarget, MONITOR_DEFAULTTONEAREST); - UINT dpiX = 96, dpiY = 96; - GetDpiForMonitor(hMon, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); - SetThreadDpiAwarenessContext(oldCtx); - Global::DpiScale = dpiX / 96.0f; - } - } - } - return S_OK; ExitError: diff --git a/src/Tf/TfTextLayoutSink.cpp b/src/Tf/TfTextLayoutSink.cpp index 0a91bdb1..bf8e29a3 100644 --- a/src/Tf/TfTextLayoutSink.cpp +++ b/src/Tf/TfTextLayoutSink.cpp @@ -7,6 +7,22 @@ #include #include "../Utils/PerfTimer.h" +POINT GetPhysicalTextAnchor(_In_ ITfContextView *pContextView, _In_ const RECT &textExtent) +{ + POINT anchor = {textExtent.left, textExtent.bottom}; + HWND hostWindow = nullptr; + if (SUCCEEDED(pContextView->GetWnd(&hostWindow)) && hostWindow) + { + hostWindow = GetAncestor(hostWindow, GA_ROOT); + POINT physicalAnchor = anchor; + if (hostWindow && LogicalToPhysicalPointForPerMonitorDPI(hostWindow, &physicalAnchor)) + { + anchor = physicalAnchor; + } + } + return anchor; +} + CTfTextLayoutSink::CTfTextLayoutSink(_In_ CMetasequoiaIME *pTextService) { _pTextService = pTextService; @@ -223,7 +239,7 @@ HRESULT CTfTextLayoutSink::_UnadviseTextLayoutSink() * @param lpRect * @return HRESULT */ -HRESULT CTfTextLayoutSink::_GetTextExt(_Out_ RECT *lpRect) +HRESULT CTfTextLayoutSink::_GetTextExt(_Out_ RECT *lpRect, _Out_ POINT *lpAnchor) { PerfTimer timer; HRESULT hr = S_OK; @@ -241,6 +257,7 @@ HRESULT CTfTextLayoutSink::_GetTextExt(_Out_ RECT *lpRect) // Set default value to make sure the window is hidden by moving it out of the screen lpRect->left = 0; lpRect->bottom = Global::INVALID_Y; + *lpAnchor = {0, Global::INVALID_Y}; } else if (isClipped && lpRect && (lpRect->right <= lpRect->left || lpRect->bottom <= lpRect->top)) { @@ -248,6 +265,11 @@ HRESULT CTfTextLayoutSink::_GetTextExt(_Out_ RECT *lpRect) // degenerate clipped extents that would anchor the candidate off-screen. lpRect->left = 0; lpRect->bottom = Global::INVALID_Y; + *lpAnchor = {0, Global::INVALID_Y}; + } + else + { + *lpAnchor = GetPhysicalTextAnchor(pContextView, *lpRect); } pContextView->Release(); diff --git a/src/Tf/TfTextLayoutSink.h b/src/Tf/TfTextLayoutSink.h index d0e8962f..966fbdde 100644 --- a/src/Tf/TfTextLayoutSink.h +++ b/src/Tf/TfTextLayoutSink.h @@ -4,6 +4,8 @@ class CMetasequoiaIME; +POINT GetPhysicalTextAnchor(_In_ ITfContextView *pContextView, _In_ const RECT &textExtent); + class CTfTextLayoutSink : public ITfTextLayoutSink { public: @@ -21,7 +23,7 @@ class CTfTextLayoutSink : public ITfTextLayoutSink HRESULT _StartLayout(_In_ ITfContext *pContextDocument, TfEditCookie ec, _In_ ITfRange *pRangeComposition); VOID _EndLayout(); - HRESULT _GetTextExt(_Out_ RECT *lpRect); + HRESULT _GetTextExt(_Out_ RECT *lpRect, _Out_ POINT *lpAnchor); ITfContext *_GetContextDocument() { return _pContextDocument; diff --git a/src/UI/CandidateListUIPresenter.cpp b/src/UI/CandidateListUIPresenter.cpp index f1e131b0..babb610c 100644 --- a/src/UI/CandidateListUIPresenter.cpp +++ b/src/UI/CandidateListUIPresenter.cpp @@ -819,10 +819,11 @@ HRESULT CCandidateListUIPresenter::_StartCandidateList(TfClientId tfClientId, _I _candidateWindowVisible = FALSE; RECT rcTextExt; - if (SUCCEEDED(_GetTextExt(&rcTextExt))) + POINT anchor; + if (SUCCEEDED(_GetTextExt(&rcTextExt, &anchor))) { - Global::Point[0] = rcTextExt.left * Global::DpiScale; - Global::Point[1] = rcTextExt.bottom * Global::DpiScale; + Global::Point[0] = anchor.x; + Global::Point[1] = anchor.y; _LayoutChangeNotification(&rcTextExt); } @@ -1083,14 +1084,15 @@ BOOL CCandidateListUIPresenter::_MovePage(_In_ int offSet) void CCandidateListUIPresenter::_MoveWindowToTextExt() { RECT rc; + POINT anchor; - if (FAILED(_GetTextExt(&rc))) + if (FAILED(_GetTextExt(&rc, &anchor))) { return; } - Global::Point[0] = rc.left * Global::DpiScale; - Global::Point[1] = rc.bottom * Global::DpiScale; + Global::Point[0] = anchor.x; + Global::Point[1] = anchor.y; } //+--------------------------------------------------------------------------- //