@@ -19,6 +19,79 @@ using namespace ::Microsoft::Terminal::Core;
1919
2020static LPCWSTR term_window_class = L" HwndTerminalClass" ;
2121
22+ STDMETHODIMP HwndTerminal::TsfDataProvider::QueryInterface (REFIID, void **) noexcept
23+ {
24+ return E_NOTIMPL;
25+ }
26+
27+ ULONG STDMETHODCALLTYPE HwndTerminal::TsfDataProvider::AddRef () noexcept
28+ {
29+ return 1 ;
30+ }
31+
32+ ULONG STDMETHODCALLTYPE HwndTerminal::TsfDataProvider::Release () noexcept
33+ {
34+ return 1 ;
35+ }
36+
37+ HWND HwndTerminal::TsfDataProvider::GetHwnd ()
38+ {
39+ return _terminal->GetHwnd ();
40+ }
41+
42+ RECT HwndTerminal::TsfDataProvider::GetViewport ()
43+ {
44+ const auto hwnd = GetHwnd ();
45+
46+ RECT rc;
47+ GetClientRect (hwnd, &rc);
48+
49+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclientrect
50+ // > The left and top members are zero. The right and bottom members contain the width and height of the window.
51+ // --> We can turn the client rect into a screen-relative rect by adding the left/top position.
52+ ClientToScreen (hwnd, reinterpret_cast <POINT*>(&rc));
53+ rc.right += rc.left ;
54+ rc.bottom += rc.top ;
55+
56+ return rc;
57+ }
58+
59+ RECT HwndTerminal::TsfDataProvider::GetCursorPosition ()
60+ {
61+ // Convert from columns/rows to pixels.
62+ til::point cursorPos;
63+ til::size fontSize;
64+ {
65+ const auto lock = _terminal->_terminal ->LockForReading ();
66+ cursorPos = _terminal->_terminal ->GetCursorPosition (); // measured in terminal cells
67+ fontSize = _terminal->_actualFont .GetSize (); // measured in pixels, not DIP
68+ }
69+ POINT ptSuggestion = {
70+ .x = cursorPos.x * fontSize.width ,
71+ .y = cursorPos.y * fontSize.height ,
72+ };
73+
74+ ClientToScreen (GetHwnd (), &ptSuggestion);
75+
76+ // Final measurement should be in pixels
77+ return {
78+ .left = ptSuggestion.x ,
79+ .top = ptSuggestion.y ,
80+ .right = ptSuggestion.x + fontSize.width ,
81+ .bottom = ptSuggestion.y + fontSize.height ,
82+ };
83+ }
84+
85+ void HwndTerminal::TsfDataProvider::HandleOutput (std::wstring_view text)
86+ {
87+ _terminal->_WriteTextToConnection (text);
88+ }
89+
90+ Microsoft::Console::Render::Renderer* HwndTerminal::TsfDataProvider::GetRenderer ()
91+ {
92+ return _terminal->_renderer .get ();
93+ }
94+
2295// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
2396// "If the high-order bit is 1, the key is down; otherwise, it is up."
2497static constexpr short KeyPressed{ gsl::narrow_cast<short >(0x8000 ) };
242315{
243316 // As a rule, detach resources from the Terminal before shutting them down.
244317 // This ensures that teardown is reentrant.
318+ _tsfHandle = {};
245319
246320 // Shut down the renderer (and therefore the thread) before we implode
247321 _renderer.reset ();
@@ -941,6 +1015,16 @@ void __stdcall TerminalSetFocus(void* terminal)
9411015 {
9421016 LOG_IF_FAILED (uiaEngine->Enable ());
9431017 }
1018+ publicTerminal->_FocusTSF ();
1019+ }
1020+
1021+ void HwndTerminal::_FocusTSF () noexcept
1022+ {
1023+ if (!_tsfHandle)
1024+ {
1025+ _tsfHandle = Microsoft::Console::TSF::Handle::Create ();
1026+ _tsfHandle.AssociateFocus (&_tsfDataProvider);
1027+ }
9441028}
9451029
9461030void __stdcall TerminalKillFocus (void * terminal)
0 commit comments