Skip to content

Commit c334f91

Browse files
authored
Move PointerId, focus and in-bounds handling down into Interactivity (#20017)
These do not notionally belong to TermControl; as we prepare to move automatic scrolling down into the Interactivity layer (for WpfTerminalControl to depend on,) we're going to need to track these in Interactivity too. This also converts the arguments from the winrt-specific Foundation::Point to Core::Point, and simplifies some of the signatures to no longer pass things we do not need to pass. Right now, this should result in no functional change. Some of the tests are sensitive to the fact that we never loaded `SPI_GETWHEELSCROLLLINES` and instead defaulted to `1`. They've been hammered back into shape.
1 parent 14f4271 commit c334f91

5 files changed

Lines changed: 139 additions & 98 deletions

File tree

src/cascadia/TerminalControl/ControlInteractivity.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
169169

170170
void ControlInteractivity::GotFocus()
171171
{
172+
_focused = true;
173+
172174
if (_uiaEngine.get())
173175
{
174176
THROW_IF_FAILED(_uiaEngine->Enable());
@@ -181,6 +183,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
181183

182184
void ControlInteractivity::LostFocus()
183185
{
186+
_focused = false;
187+
184188
if (_uiaEngine.get())
185189
{
186190
THROW_IF_FAILED(_uiaEngine->Disable());
@@ -248,7 +252,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
248252
PasteFromClipboard.raise(*this, std::move(args));
249253
}
250254

251-
void ControlInteractivity::PointerPressed(Control::MouseButtonState buttonState,
255+
void ControlInteractivity::PointerPressed(const uint32_t /*pointerId*/,
256+
Control::MouseButtonState buttonState,
252257
const unsigned int pointerUpdateKind,
253258
const uint64_t timestamp,
254259
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
@@ -261,6 +266,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
261266
const auto shiftEnabled = modifiers.IsShiftPressed();
262267
const auto ctrlEnabled = modifiers.IsCtrlPressed();
263268

269+
// Mark that this pointer event actually started within our bounds.
270+
// We'll need this later, for PointerMoved events.
271+
_pointerPressedInBounds = true;
272+
264273
// GH#9396: we prioritize hyper-link over VT mouse events
265274
auto hyperlink = _core->GetHyperlink(terminalPosition.to_core_point());
266275
if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown) &&
@@ -355,24 +364,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
355364
}
356365
}
357366

358-
void ControlInteractivity::TouchPressed(const winrt::Windows::Foundation::Point contactPoint)
367+
void ControlInteractivity::TouchPressed(const Core::Point contactPoint)
359368
{
360369
_touchAnchor = contactPoint;
361370
}
362371

363-
bool ControlInteractivity::PointerMoved(Control::MouseButtonState buttonState,
372+
bool ControlInteractivity::PointerMoved(const uint32_t /*pointerId*/,
373+
Control::MouseButtonState buttonState,
364374
const unsigned int pointerUpdateKind,
365375
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
366-
const bool focused,
367-
const Core::Point pixelPosition,
368-
const bool pointerPressedInBounds)
376+
const Core::Point pixelPosition)
369377
{
370378
const auto terminalPosition = _getTerminalPosition(til::point{ pixelPosition }, false);
371379
// Returning true from this function indicates that the caller should do no further processing of this movement.
372380
bool handledCompletely = false;
373381

374382
// Short-circuit isReadOnly check to avoid warning dialog
375-
if (focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
383+
if (_focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
376384
{
377385
_sendMouseEventHelper(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState);
378386
handledCompletely = true;
@@ -381,7 +389,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
381389
// actually start _in_ the control bounds. Case in point - someone drags
382390
// a file into the bounds of the control. That shouldn't send the
383391
// selection into space.
384-
else if (focused && pointerPressedInBounds && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
392+
else if (_focused && _pointerPressedInBounds && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
385393
{
386394
if (_singleClickTouchdownPos)
387395
{
@@ -427,10 +435,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
427435
return handledCompletely;
428436
}
429437

430-
void ControlInteractivity::TouchMoved(const winrt::Windows::Foundation::Point newTouchPoint,
431-
const bool focused)
438+
void ControlInteractivity::TouchMoved(const Core::Point newTouchPoint)
432439
{
433-
if (focused &&
440+
if (_focused &&
434441
_touchAnchor)
435442
{
436443
const auto anchor = _touchAnchor.value();
@@ -464,11 +471,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
464471
}
465472
}
466473

467-
void ControlInteractivity::PointerReleased(Control::MouseButtonState buttonState,
474+
void ControlInteractivity::PointerReleased(const uint32_t /*pointerId*/,
475+
Control::MouseButtonState buttonState,
468476
const unsigned int pointerUpdateKind,
469477
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
470478
const Core::Point pixelPosition)
471479
{
480+
_pointerPressedInBounds = false;
481+
472482
const auto terminalPosition = _getTerminalPosition(til::point{ pixelPosition }, false);
473483
// Short-circuit isReadOnly check to avoid warning dialog
474484
if (!_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))

src/cascadia/TerminalControl/ControlInteractivity.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
5151
::Microsoft::Console::Render::IRenderData* GetRenderData() const;
5252

5353
#pragma region Input Methods
54-
void PointerPressed(Control::MouseButtonState buttonState,
54+
void PointerPressed(const uint32_t pointerId,
55+
Control::MouseButtonState buttonState,
5556
const unsigned int pointerUpdateKind,
5657
const uint64_t timestamp,
5758
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
5859
const Core::Point pixelPosition);
59-
void TouchPressed(const winrt::Windows::Foundation::Point contactPoint);
60+
void TouchPressed(const Core::Point contactPoint);
6061

61-
bool PointerMoved(Control::MouseButtonState buttonState,
62+
bool PointerMoved(const uint32_t pointerId,
63+
Control::MouseButtonState buttonState,
6264
const unsigned int pointerUpdateKind,
6365
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
64-
const bool focused,
65-
const Core::Point pixelPosition,
66-
const bool pointerPressedInBounds);
67-
void TouchMoved(const winrt::Windows::Foundation::Point newTouchPoint,
68-
const bool focused);
66+
const Core::Point pixelPosition);
67+
void TouchMoved(const Core::Point newTouchPoint);
6968

70-
void PointerReleased(Control::MouseButtonState buttonState,
69+
void PointerReleased(const uint32_t pointerId,
70+
Control::MouseButtonState buttonState,
7171
const unsigned int pointerUpdateKind,
7272
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
7373
const Core::Point pixelPosition);
@@ -115,7 +115,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
115115

116116
// If this is set, then we assume we are in the middle of panning the
117117
// viewport via touch input.
118-
std::optional<winrt::Windows::Foundation::Point> _touchAnchor;
118+
std::optional<Core::Point> _touchAnchor;
119119

120120
using Timestamp = uint64_t;
121121

@@ -142,6 +142,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
142142
uint64_t _id;
143143
static std::atomic<uint64_t> _nextId;
144144

145+
bool _focused{ false };
146+
bool _pointerPressedInBounds{ false };
147+
145148
unsigned int _numberOfClicks(Core::Point clickPos, Timestamp clickTime);
146149
void _updateSystemParameterSettings() noexcept;
147150

src/cascadia/TerminalControl/ControlInteractivity.idl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,24 @@ namespace Microsoft.Terminal.Control
3636
void RequestPasteTextFromClipboard();
3737
void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point);
3838

39-
void PointerPressed(MouseButtonState buttonState,
39+
void PointerPressed(UInt32 pointerId,
40+
MouseButtonState buttonState,
4041
UInt32 pointerUpdateKind,
4142
UInt64 timestamp,
4243
Microsoft.Terminal.Core.ControlKeyStates modifiers,
4344
Microsoft.Terminal.Core.Point pixelPosition);
44-
void TouchPressed(Windows.Foundation.Point contactPoint);
45+
void TouchPressed(Microsoft.Terminal.Core.Point contactPoint);
4546

46-
Boolean PointerMoved(MouseButtonState buttonState,
47+
Boolean PointerMoved(UInt32 pointerId,
48+
MouseButtonState buttonState,
4749
UInt32 pointerUpdateKind,
4850
Microsoft.Terminal.Core.ControlKeyStates modifiers,
49-
Boolean focused,
50-
Microsoft.Terminal.Core.Point pixelPosition,
51-
Boolean pointerPressedInBounds);
51+
Microsoft.Terminal.Core.Point pixelPosition);
5252

53-
void TouchMoved(Windows.Foundation.Point newTouchPoint,
54-
Boolean focused);
53+
void TouchMoved(Microsoft.Terminal.Core.Point newTouchPoint);
5554

56-
void PointerReleased(MouseButtonState buttonState,
55+
void PointerReleased(UInt32 pointerId,
56+
MouseButtonState buttonState,
5757
UInt32 pointerUpdateKind,
5858
Microsoft.Terminal.Core.ControlKeyStates modifiers,
5959
Microsoft.Terminal.Core.Point pixelPosition);

src/cascadia/TerminalControl/TermControl.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,12 +1990,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
19901990
// NB: I don't think this is correct because the touch should be in the center of the rect.
19911991
// I suspect the point.Position() would be correct.
19921992
const auto contactRect = point.Properties().ContactRect();
1993-
_interactivity.TouchPressed({ contactRect.X, contactRect.Y });
1993+
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
1994+
_interactivity.TouchPressed(newTouchPoint.to_core_point());
19941995
}
19951996
else
19961997
{
19971998
const auto cursorPosition = point.Position();
1998-
_interactivity.PointerPressed(TermControl::GetPressedMouseButtons(point),
1999+
_interactivity.PointerPressed(point.PointerId(),
2000+
TermControl::GetPressedMouseButtons(point),
19992001
TermControl::GetPointerUpdateKind(point),
20002002
point.Timestamp(),
20012003
ControlKeyStates{ args.KeyModifiers() },
@@ -2034,12 +2036,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
20342036
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
20352037
type == Windows::Devices::Input::PointerDeviceType::Pen)
20362038
{
2037-
auto suppressFurtherHandling = _interactivity.PointerMoved(TermControl::GetPressedMouseButtons(point),
2039+
auto suppressFurtherHandling = _interactivity.PointerMoved(point.PointerId(),
2040+
TermControl::GetPressedMouseButtons(point),
20382041
TermControl::GetPointerUpdateKind(point),
20392042
ControlKeyStates(args.KeyModifiers()),
2040-
_focused,
2041-
pixelPosition,
2042-
_pointerPressedInBounds);
2043+
pixelPosition);
20432044

20442045
// GH#9109 - Only start an auto-scroll when the drag actually
20452046
// started within our bounds. Otherwise, someone could start a drag
@@ -2078,7 +2079,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
20782079
else if (type == Windows::Devices::Input::PointerDeviceType::Touch)
20792080
{
20802081
const auto contactRect = point.Properties().ContactRect();
2081-
_interactivity.TouchMoved({ contactRect.X, contactRect.Y }, _focused);
2082+
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
2083+
2084+
_interactivity.TouchMoved(newTouchPoint.to_core_point());
20822085
}
20832086

20842087
args.Handled(true);
@@ -2111,7 +2114,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
21112114
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
21122115
type == Windows::Devices::Input::PointerDeviceType::Pen)
21132116
{
2114-
_interactivity.PointerReleased(TermControl::GetPressedMouseButtons(point),
2117+
_interactivity.PointerReleased(point.PointerId(),
2118+
TermControl::GetPressedMouseButtons(point),
21152119
TermControl::GetPointerUpdateKind(point),
21162120
ControlKeyStates(args.KeyModifiers()),
21172121
pixelPosition);

0 commit comments

Comments
 (0)