@@ -19,6 +19,79 @@ using namespace ::Microsoft::Terminal::Core;
19
19
20
20
static LPCWSTR term_window_class = L" HwndTerminalClass" ;
21
21
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
+
22
95
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
23
96
// "If the high-order bit is 1, the key is down; otherwise, it is up."
24
97
static constexpr short KeyPressed{ gsl::narrow_cast<short >(0x8000 ) };
242
315
{
243
316
// As a rule, detach resources from the Terminal before shutting them down.
244
317
// This ensures that teardown is reentrant.
318
+ _tsfHandle = {};
245
319
246
320
// Shut down the renderer (and therefore the thread) before we implode
247
321
_renderer.reset ();
@@ -941,6 +1015,16 @@ void __stdcall TerminalSetFocus(void* terminal)
941
1015
{
942
1016
LOG_IF_FAILED (uiaEngine->Enable ());
943
1017
}
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
+ }
944
1028
}
945
1029
946
1030
void __stdcall TerminalKillFocus (void * terminal)
0 commit comments