Skip to content

Commit

Permalink
Merge in 'release/5.0' changes
Browse files Browse the repository at this point in the history
  • Loading branch information
dotnet-bot committed Feb 17, 2021
2 parents cb5ea18 + 59bdffc commit 5d63647
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ internal enum FlickScrollDirection
// Caches the pointer stack enabled state
private static bool? _isPointerStackEnabled = null;

// Caches TransformToDevice matrices per DpiScale2
private readonly Dictionary<DpiScale2, Matrix> _transformToDeviceMatrices = new Dictionary<DpiScale2, Matrix>();

#endregion

#region Construction/Initilization
Expand Down Expand Up @@ -402,19 +405,48 @@ protected void ReadSystemConfig()
/// </summary>
internal abstract TabletDeviceCollection TabletDevices { get; }

/// <summary>
/// Acquires and caches the TransformToDevice matrix from a specific HwndSource.
/// </summary>
/// <remarks>
/// The caching here is done at a per DPI level. TransformToDevice only matters for a
/// specific DpiScale, so there is no need to spend space caching it per HwndSource.
/// </remarks>
/// <param name="source">The source of DpiScale and matrix transforms</param>
/// <returns>The TransformToDevice matrix corresponding to the DpiScale of the source</returns>
protected Matrix GetAndCacheTransformToDeviceMatrix(PresentationSource source)
{
var hwndSource = source as HwndSource;
Matrix toDevice = Matrix.Identity;

if (hwndSource?.CompositionTarget != null)
{
// If we have not yet seen this DPI, store the matrix for it.
if (!_transformToDeviceMatrices.ContainsKey(hwndSource.CompositionTarget.CurrentDpiScale))
{
_transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale] = hwndSource.CompositionTarget.TransformToDevice;
Debug.Assert(_transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale].HasInverse);
}

toDevice = _transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale];
}

return toDevice;
}

/// <summary>
/// Converts measure units to tablet device coordinates
/// </summary>
/// <param name="measurePoint"></param>
/// <returns></returns>
internal abstract Point DeviceUnitsFromMeasureUnits(Point measurePoint);
internal abstract Point DeviceUnitsFromMeasureUnits(PresentationSource source, Point measurePoint);

/// <summary>
/// Converts device units to measure units
/// </summary>
/// <param name="measurePoint"></param>
/// <returns></returns>
internal abstract Point MeasureUnitsFromDeviceUnits(Point measurePoint);
internal abstract Point MeasureUnitsFromDeviceUnits(PresentationSource source, Point measurePoint);

/// <summary>
/// Updates the stylus capture for the particular stylus device
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,13 +475,12 @@ internal override TabletDeviceCollection TabletDevices
/// </summary>
/// <param name="measurePoint">The point in measure units</param>
/// <returns>The point in device units</returns>
internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint)
internal override Point DeviceUnitsFromMeasureUnits(PresentationSource source, Point measurePoint)
{

// We can possibly get here with no current device. This happens from a certain order of mouse capture.
// In that case, default to identity matrix as the capture units are going to be from the mouse.
// Otherwise, transform using the tablet for the current stylus device.
Point pt = measurePoint * (_currentStylusDevice?.ActiveSource?.CompositionTarget?.TransformToDevice ?? Matrix.Identity);
Point pt = measurePoint * GetAndCacheTransformToDeviceMatrix(source);

// Make sure we return whole numbers (pixels are whole numbers)
return new Point(Math.Round(pt.X), Math.Round(pt.Y));
Expand All @@ -492,13 +491,12 @@ internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint)
/// </summary>
/// <param name="devicePoint">The point in device units</param>
/// <returns>The point in measure units</returns>
internal override Point MeasureUnitsFromDeviceUnits(Point devicePoint)
internal override Point MeasureUnitsFromDeviceUnits(PresentationSource source, Point devicePoint)
{

// We can possibly get here with no current device. This happens from a certain order of mouse capture.
// In that case, default to identity matrix as the capture units are going to be from the mouse.
// Otherwise, transform using the tablet for the current stylus device.
Point pt = devicePoint * (_currentStylusDevice?.ActiveSource?.CompositionTarget?.TransformFromDevice ?? Matrix.Identity);
Point pt = devicePoint * GetAndCacheTransformToDeviceMatrix(source);

// Make sure we return whole numbers (pixels are whole numbers)
return new Point(Math.Round(pt.X), Math.Round(pt.Y));
Expand Down Expand Up @@ -1273,7 +1271,7 @@ private void UpdateTapCount(NotifyInputEventArgs args)

int elapsedTime = Math.Abs(unchecked(stylusDownEventArgs.Timestamp - _lastTapTimeTicks));

Point ptPixels = DeviceUnitsFromMeasureUnits(ptClient);
Point ptPixels = DeviceUnitsFromMeasureUnits(stylusDevice.CriticalActiveSource, ptClient);

Size doubleTapSize = stylusDevice.PointerTabletDevice.DoubleTapSize;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ internal void ChangeStylusCapture(IInputElement stylusCapture, CaptureMode captu
// See if we need to update over for subtree mode.
if (CapturedMode == CaptureMode.SubTree && _inputSource != null && _inputSource.Value != null)
{
Point pt = _pointerLogic.DeviceUnitsFromMeasureUnits(GetPosition(null));
Point pt = _pointerLogic.DeviceUnitsFromMeasureUnits(_inputSource.Value, GetPosition(null));
inputElementHit = FindTarget(_inputSource.Value, pt);
}

Expand All @@ -1109,7 +1109,7 @@ internal void ChangeStylusCapture(IInputElement stylusCapture, CaptureMode captu
if (_inputSource != null && _inputSource.Value != null)
{
Point pt = GetPosition(null); // relative to window (root element)
pt = _pointerLogic.DeviceUnitsFromMeasureUnits(pt); // change back to device coords.
pt = _pointerLogic.DeviceUnitsFromMeasureUnits(_inputSource.Value, pt); // change back to device coords.
IInputElement currentOver = Input.StylusDevice.GlobalHitTest(_inputSource.Value, pt);
ChangeStylusOver(currentOver);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
{
// Create new RawStylusInput to send
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.CriticalActiveSource, stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(currentPic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.

Expand All @@ -459,7 +459,7 @@ internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
// The transformTabletToView matrix and plugincollection rects though can change based
// off of layout events which is why we need to lock this.
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.CriticalActiveSource, stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(pic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.

Expand Down Expand Up @@ -512,7 +512,7 @@ internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inpu
ptTablet = ptTablet * stylusDevice.TabletDevice.TabletDeviceImpl.TabletToScreen;
ptTablet.X = (int)Math.Round(ptTablet.X); // Make sure we snap to whole window pixels.
ptTablet.Y = (int)Math.Round(ptTablet.Y);
ptTablet = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.
ptTablet = _stylusLogic.MeasureUnitsFromDeviceUnits(stylusDevice.CriticalActiveSource, ptTablet); // change to measured units now.

pic = HittestPlugInCollection(ptTablet); // Use cached rectangles for UIElements.
}
Expand Down Expand Up @@ -556,6 +556,8 @@ StylusPlugInCollection HittestPlugInCollection(Point pt)
return null;
}

internal HwndSource InputSource { get { return _inputSource.Value; } }

/////////////////////////////////////////////////////////////////////

internal SecurityCriticalData<HwndSource> _inputSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ private void PreNotifyInput(object sender, NotifyInputEventArgs e)
if (!_inDragDrop && !rawStylusInputReport.PenContext.Contexts.IsWindowDisabled && !stylusDevice.IgnoreStroke)
{
Point position = stylusDevice.GetRawPosition(null);
position = DeviceUnitsFromMeasureUnits(position); // change back to device coords.
position = DeviceUnitsFromMeasureUnits(stylusDevice.CriticalActiveSource, position); // change back to device coords.
IInputElement target = stylusDevice.FindTarget(stylusDevice.CriticalActiveSource, position);
SelectStylusDevice(stylusDevice, target, true);
}
Expand Down Expand Up @@ -1077,8 +1077,8 @@ private void PreNotifyInput(object sender, NotifyInputEventArgs e)
bBarrelPressed = true;
}

Point pPixelPoint = DeviceUnitsFromMeasureUnits(ptClient);
Point pLastPixelPoint = DeviceUnitsFromMeasureUnits(stylusDevice.LastTapPoint);
Point pPixelPoint = DeviceUnitsFromMeasureUnits(stylusDevice.CriticalActiveSource, ptClient);
Point pLastPixelPoint = DeviceUnitsFromMeasureUnits(stylusDevice.CriticalActiveSource, stylusDevice.LastTapPoint);

// How long since the last click? (deals with tickcount wrapping too)
// Here's some info on how this works...
Expand Down Expand Up @@ -2660,6 +2660,8 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn
rawStylusInputReport.RawStylusInput = null;
}

WispStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As<WispStylusDevice>();

// See if we need to build up an RSI to send to the plugincollection (due to a mistarget).
bool sendRawStylusInput = false;
if (targetPIC != null && rawStylusInputReport.RawStylusInput == null)
Expand All @@ -2668,7 +2670,7 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn
// The transformTabletToView matrix and plugincollection rects though can change based
// off of layout events which is why we need to lock this.
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(stylusDevice.CriticalActiveSource, stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(targetPIC.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.

Expand All @@ -2677,8 +2679,6 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn
sendRawStylusInput = true;
}

WispStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As<WispStylusDevice>();

// Now fire the confirmed enter/leave events as necessary.
StylusPlugInCollection currentTarget = stylusDevice.CurrentVerifiedTarget;
if (targetPIC != currentTarget)
Expand All @@ -2689,7 +2689,7 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn
if (originalRSI == null)
{
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(stylusDevice.CriticalActiveSource, stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(currentTarget.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
originalRSI = new RawStylusInput(rawStylusInputReport, transformTabletToView, currentTarget);
Expand Down Expand Up @@ -3109,16 +3109,7 @@ internal void RegisterHwndForInput(InputManager inputManager, PresentationSource
{
HwndSource hwndSource = (HwndSource)inputSource;

// Query the transform from HwndTarget when the first window is created.
if (!_transformInitialized)
{
if (hwndSource != null && hwndSource.CompositionTarget != null)
{
_transformToDevice = hwndSource.CompositionTarget.TransformToDevice;
Debug.Assert(_transformToDevice.HasInverse);
_transformInitialized = true;
}
}
GetAndCacheTransformToDeviceMatrix(hwndSource);

// Keep track so we don't bother looking for changes if someone happened to query this before
// an Avalon window was created where we get TabletAdd/Removed notification.
Expand Down Expand Up @@ -3563,14 +3554,14 @@ internal object ProcessDisplayChanged(object oInput)

/////////////////////////////////////////////////////////////////////

internal Matrix GetTabletToViewTransform(TabletDevice tabletDevice)
internal Matrix GetTabletToViewTransform(PresentationSource source, TabletDevice tabletDevice)
{
// Inking is offset under 120 DPI
// Changet the TabletToViewTransform matrix to take DPI into account. The default
// value is 96 DPI in Avalon. The device DPI value is cached after the first call
// to this function.

Matrix matrix = _transformToDevice;
Matrix matrix = GetAndCacheTransformToDeviceMatrix(source);
matrix.Invert();
return matrix * tabletDevice.As<TabletDeviceBase>().TabletToScreen;
}
Expand All @@ -3580,9 +3571,9 @@ internal Matrix GetTabletToViewTransform(TabletDevice tabletDevice)
/// </summary>
/// <param name="measurePoint">The point to transform, in measure units</param>
/// <returns>The point in device coordinates</returns>
internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint)
internal override Point DeviceUnitsFromMeasureUnits(PresentationSource source, Point measurePoint)
{
Point pt = measurePoint * _transformToDevice;
Point pt = measurePoint * GetAndCacheTransformToDeviceMatrix(source);
pt.X = (int)Math.Round(pt.X); // Make sure we return whole numbers (pixels are whole numbers)
pt.Y = (int)Math.Round(pt.Y);
return pt;
Expand All @@ -3593,9 +3584,9 @@ internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint)
/// </summary>
/// <param name="measurePoint">The point to transform, in measure units</param>
/// <returns>The point in device coordinates</returns>
internal override Point MeasureUnitsFromDeviceUnits(Point measurePoint)
internal override Point MeasureUnitsFromDeviceUnits(PresentationSource source, Point measurePoint)
{
Matrix matrix = _transformToDevice;
Matrix matrix = GetAndCacheTransformToDeviceMatrix(source);
matrix.Invert();
return measurePoint * matrix;
}
Expand Down Expand Up @@ -3647,11 +3638,6 @@ internal long IncrementVersion()

/////////////////////////////////////////////////////////////////////

private Matrix _transformToDevice = Matrix.Identity;
private bool _transformInitialized;

/////////////////////////////////////////////////////////////////////

private SecurityCriticalData<InputManager> _inputManager;

DispatcherOperationCallback _dlgInputManagerProcessInput;
Expand Down
Loading

0 comments on commit 5d63647

Please sign in to comment.