diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs index 7af730f32a58638de5841fa547a729805ef17e6a..b95ad4d320eca8d5788cb33941bd946f4643ac7b 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs @@ -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 _transformToDeviceMatrices = new Dictionary(); + #endregion #region Construction/Initilization @@ -402,19 +405,48 @@ protected void ReadSystemConfig() /// internal abstract TabletDeviceCollection TabletDevices { get; } + /// + /// Acquires and caches the TransformToDevice matrix from a specific HwndSource. + /// + /// + /// 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. + /// + /// The source of DpiScale and matrix transforms + /// The TransformToDevice matrix corresponding to the DpiScale of the source + 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; + } + /// /// Converts measure units to tablet device coordinates /// /// /// - internal abstract Point DeviceUnitsFromMeasureUnits(Point measurePoint); + internal abstract Point DeviceUnitsFromMeasureUnits(PresentationSource source, Point measurePoint); /// /// Converts device units to measure units /// /// /// - internal abstract Point MeasureUnitsFromDeviceUnits(Point measurePoint); + internal abstract Point MeasureUnitsFromDeviceUnits(PresentationSource source, Point measurePoint); /// /// Updates the stylus capture for the particular stylus device diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerLogic.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerLogic.cs index b2d997d6e6fb289715c61aa0e858fedf26ea03a3..609149f8cb99aa98a2fd1e8305bb1937e31b9d69 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerLogic.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerLogic.cs @@ -475,13 +475,12 @@ internal override TabletDeviceCollection TabletDevices /// /// The point in measure units /// The point in device units - 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)); @@ -492,13 +491,12 @@ internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint) /// /// The point in device units /// The point in measure units - 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)); @@ -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; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerStylusDevice.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerStylusDevice.cs index 7fef6f6decbc0d9670a456f7f93f5f81d5f1a8db..a684599e2b474d326a290c9e06bfc6452e91969c 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerStylusDevice.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerStylusDevice.cs @@ -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); } @@ -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); } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs index 307f8b18df48475f9e9c9926068d430503a600ca..9b2577b64970ccbdf692e0af61a0d57a5e6628be 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs @@ -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. @@ -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. @@ -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. } @@ -556,6 +556,8 @@ StylusPlugInCollection HittestPlugInCollection(Point pt) return null; } + internal HwndSource InputSource { get { return _inputSource.Value; } } + ///////////////////////////////////////////////////////////////////// internal SecurityCriticalData _inputSource; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs index d61955ef77cab9c6d64f36a986c324946d8bc045..f6f29da28a6f9ec21833d1138e4e0ec43faf9fab 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs @@ -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); } @@ -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... @@ -2660,6 +2660,8 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn rawStylusInputReport.RawStylusInput = null; } + WispStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As(); + // 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) @@ -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. @@ -2677,8 +2679,6 @@ private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusIn sendRawStylusInput = true; } - WispStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As(); - // Now fire the confirmed enter/leave events as necessary. StylusPlugInCollection currentTarget = stylusDevice.CurrentVerifiedTarget; if (targetPIC != currentTarget) @@ -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); @@ -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. @@ -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().TabletToScreen; } @@ -3580,9 +3571,9 @@ internal Matrix GetTabletToViewTransform(TabletDevice tabletDevice) /// /// The point to transform, in measure units /// The point in device coordinates - 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; @@ -3593,9 +3584,9 @@ internal override Point DeviceUnitsFromMeasureUnits(Point measurePoint) /// /// The point to transform, in measure units /// The point in device coordinates - 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; } @@ -3647,11 +3638,6 @@ internal long IncrementVersion() ///////////////////////////////////////////////////////////////////// - private Matrix _transformToDevice = Matrix.Identity; - private bool _transformInitialized; - - ///////////////////////////////////////////////////////////////////// - private SecurityCriticalData _inputManager; DispatcherOperationCallback _dlgInputManagerProcessInput; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispStylusDevice.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispStylusDevice.cs index 97677b75971bfca34162ddfb3238a4942f5d6758..bf933843a7c642e58b582d7ee4cbf5bcaba91c33 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispStylusDevice.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispStylusDevice.cs @@ -676,7 +676,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 = _stylusLogic.DeviceUnitsFromMeasureUnits(GetPosition(null)); + Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits(_inputSource.Value, GetPosition(null)); inputElementHit = FindTarget(_inputSource.Value, pt); } @@ -688,7 +688,7 @@ internal void ChangeStylusCapture(IInputElement stylusCapture, CaptureMode captu if (_inputSource != null && _inputSource.Value != null) { Point pt = GetPosition(null); // relative to window (root element) - pt = _stylusLogic.DeviceUnitsFromMeasureUnits(pt); // change back to device coords. + pt = _stylusLogic.DeviceUnitsFromMeasureUnits(_inputSource.Value, pt); // change back to device coords. IInputElement currentOver = Input.StylusDevice.GlobalHitTest(_inputSource.Value, pt); ChangeStylusOver(currentOver); } @@ -1310,10 +1310,10 @@ internal override Point GetMouseScreenPosition(MouseDevice mouseDevice) /// Returns the transform for converting from tablet to element /// relative coordinates. /// - private GeneralTransform GetTabletToElementTransform(IInputElement relativeTo) + private GeneralTransform GetTabletToElementTransform(PresentationSource source, IInputElement relativeTo) { GeneralTransformGroup group = new GeneralTransformGroup(); - group.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(_tabletDevice.TabletDevice))); + group.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(source, _tabletDevice.TabletDevice))); group.Children.Add(StylusDevice.GetElementTransform(relativeTo)); return group; } @@ -1376,7 +1376,7 @@ internal override void UpdateEventStylusPoints(RawStylusInputReport report, bool _eventStylusPoints = new StylusPointCollection(report.StylusPointDescription, report.GetRawPacketData(), - GetTabletToElementTransform(null), + GetTabletToElementTransform(report.InputSource, null), Matrix.Identity); } } @@ -1429,7 +1429,7 @@ internal void UpdateState(RawStylusInputReport report) _eventStylusPoints = new StylusPointCollection(report.StylusPointDescription, report.GetRawPacketData(), - GetTabletToElementTransform(null), + GetTabletToElementTransform(report.InputSource, null), Matrix.Identity); PresentationSource inputSource = DetermineValidSource(report.InputSource, _eventStylusPoints, report.PenContext.Contexts); @@ -1438,8 +1438,8 @@ internal void UpdateState(RawStylusInputReport report) if (inputSource != null && inputSource != report.InputSource) { Point newWindowLocation = PointUtil.ClientToScreen(new Point(0, 0), inputSource); - newWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(newWindowLocation); - Point oldWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(report.PenContext.Contexts.DestroyedLocation); + newWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(inputSource, newWindowLocation); + Point oldWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(report.InputSource, report.PenContext.Contexts.DestroyedLocation); // Create translate matrix transform to shift coords to map points to new window location. MatrixTransform additionalTransform = new MatrixTransform(new Matrix(1, 0, 0, 1, @@ -1455,7 +1455,7 @@ internal void UpdateState(RawStylusInputReport report) if (inputSource != null) { // Update our screen position from this move. - Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits((Point)_rawPosition); + Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits(inputSource, (Point)_rawPosition); _lastScreenLocation = PointUtil.ClientToScreen(pt, inputSource); } @@ -1493,7 +1493,7 @@ internal void UpdateState(RawStylusInputReport report) // We use the first point of the packet data for Drag detection to try and // filter out cases where the stylus skips when going down. Point dragPosition = (Point)_eventStylusPoints[0]; - dragPosition = _stylusLogic.DeviceUnitsFromMeasureUnits(dragPosition); + dragPosition = _stylusLogic.DeviceUnitsFromMeasureUnits(inputSource, dragPosition); dragPosition = PointUtil.ClientToScreen(dragPosition, inputSource); // See if we need to detect a Drag gesture. If so do the calculation. @@ -1552,11 +1552,12 @@ private PresentationSource DetermineValidSource(PresentationSource inputSource, { Point ptScreen; - // If we have the last penContext then we can remap the coordinates properly. + // If we have the last penContext and a valid CompositionTarget, then we can remap the coordinates properly. // Otherwise we just use the last stylus mouse location to figure out a PresenationSource. - if (penContextsOfPoints != null) + if (penContextsOfPoints?.InputSource?.CompositionTarget != null) { - ptScreen = _stylusLogic.DeviceUnitsFromMeasureUnits((Point)stylusPoints[0]); + ptScreen = _stylusLogic.DeviceUnitsFromMeasureUnits(penContextsOfPoints.InputSource, (Point)stylusPoints[0]); + // map from window to screen (ie - add the window location). ptScreen.Offset(penContextsOfPoints.DestroyedLocation.X, penContextsOfPoints.DestroyedLocation.Y); } @@ -1646,7 +1647,7 @@ private void UpdateStateForSystemGesture(SystemGesture gesture, RawStylusSystemG // Update the current point with this data. _eventStylusPoints = new StylusPointCollection(stylusPoint.Description, stylusPoint.GetPacketData(), - GetTabletToElementTransform(null), + GetTabletToElementTransform(report.InputSource, null), Matrix.Identity); PresentationSource inputSource = DetermineValidSource(report.InputSource, _eventStylusPoints, report.PenContext.Contexts); @@ -1657,8 +1658,8 @@ private void UpdateStateForSystemGesture(SystemGesture gesture, RawStylusSystemG if (inputSource != report.InputSource) { Point newWindowLocation = PointUtil.ClientToScreen(new Point(0, 0), inputSource); - newWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(newWindowLocation); - Point oldWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(report.PenContext.Contexts.DestroyedLocation); + newWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(inputSource, newWindowLocation); + Point oldWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(report.InputSource, report.PenContext.Contexts.DestroyedLocation); // Create translate matrix transform to shift coords to map points to new window location. MatrixTransform additionalTransform = new MatrixTransform(new Matrix(1, 0, 0, 1, @@ -1669,7 +1670,7 @@ private void UpdateStateForSystemGesture(SystemGesture gesture, RawStylusSystemG _rawPosition = _eventStylusPoints[_eventStylusPoints.Count - 1]; _inputSource = new SecurityCriticalDataClass(inputSource); - Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits((Point)_rawPosition); + Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits(inputSource, (Point)_rawPosition); _lastScreenLocation = PointUtil.ClientToScreen(pt, inputSource); } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs index 10ecb5fbeea7f737c8268dc4455c590dcf70607e..e6b3ead0e50e8db680949999718b9ffbd4c534ee 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs @@ -114,7 +114,6 @@ public class HwndTarget : CompositionTarget private static readonly IntPtr Unhandled = IntPtr.Zero; private MatrixTransform _worldTransform; - private DpiScale2 _currentDpiScale; private SecurityCriticalDataForSet _renderModePreference = new SecurityCriticalDataForSet(RenderMode.Default); @@ -275,13 +274,13 @@ public HwndTarget(IntPtr hwnd) // system DPI scale // Initialize per-HwndTarget values (done once per HwndTarget instance) // DPI_AWARENESS_CONTEXT (DpiAwarenessContext property) - // Window DPI scale (_currentDpiScale field) + // Window DPI scale (CurrentDpiScale field) InitializeDpiAwarenessAndDpiScales(); _worldTransform = new MatrixTransform( new Matrix( - _currentDpiScale.DpiScaleX, 0, - 0 , _currentDpiScale.DpiScaleY, + CurrentDpiScale.DpiScaleX, 0, + 0 , CurrentDpiScale.DpiScaleY, 0 , 0)); // @@ -343,7 +342,7 @@ private void InitializeDpiAwarenessAndDpiScales() // Initialize DpiAwarenessContext (DPI_AWARENESS_CONTEXT) every // time the HwndTarget constructor runs- this can change for each HWND DpiAwarenessContext = (DpiAwarenessContextValue)DpiUtil.GetDpiAwarenessContext(_hWnd); - _currentDpiScale = GetDpiScaleForWindow(_hWnd); + CurrentDpiScale = GetDpiScaleForWindow(_hWnd); } /// @@ -753,7 +752,7 @@ internal override void CreateUCEResources(DUCE.Channel channel, DUCE.Channel out _hwndClientRectInScreenCoords.bottom - _hwndClientRectInScreenCoords.top, MediaSystem.ForceSoftwareRendering, (int)DpiAwarenessContext, - _currentDpiScale, + CurrentDpiScale, channel ); @@ -869,7 +868,7 @@ private bool HandleDpiChangedMessage(IntPtr wParam, IntPtr lParam) var hwndSource = HwndSource.FromHwnd(_hWnd); if (hwndSource != null) { - var oldDpi = _currentDpiScale; + var oldDpi = CurrentDpiScale; var newDpi = DpiScale2.FromPixelsPerInch( NativeMethods.SignedLOWORD(wParam), @@ -902,7 +901,7 @@ private bool HandleDpiChangedAfterParentMessage() if (IsPerMonitorDpiScalingEnabled) { - var oldDpi = _currentDpiScale; + var oldDpi = CurrentDpiScale; var newDpi = GetDpiScaleForWindow(_hWnd); if (oldDpi != newDpi) @@ -1747,9 +1746,9 @@ private void NotifyListenersOfWorldTransformAndClipBoundsChanged() /// internal void OnDpiChanged(HwndDpiChangedEventArgs e) { - var oldDpi = _currentDpiScale; + var oldDpi = CurrentDpiScale; var newDpi = new DpiScale2(e.NewDpi); - _currentDpiScale = newDpi; + CurrentDpiScale = newDpi; UpdateWorldTransform(newDpi); PropagateDpiChangeToRootVisual(oldDpi, newDpi); @@ -1769,9 +1768,9 @@ internal void OnDpiChanged(HwndDpiChangedEventArgs e) /// internal void OnDpiChangedAfterParent(HwndDpiChangedAfterParentEventArgs e) { - var oldDpi = _currentDpiScale; + var oldDpi = CurrentDpiScale; var newDpi = new DpiScale2(e.NewDpi); - _currentDpiScale = newDpi; + CurrentDpiScale = newDpi; UpdateWorldTransform(newDpi); PropagateDpiChangeToRootVisual(oldDpi, newDpi); @@ -1797,7 +1796,7 @@ private void NotifyRendererOfDpiChange(bool afterParent) DUCE.CompositionTarget.ProcessDpiChanged( _compositionTarget.GetHandle(channel), - _currentDpiScale, + CurrentDpiScale, afterParent, channel); } @@ -2018,6 +2017,8 @@ private void OnShowWindow(bool enableRenderTarget) /// private DpiAwarenessContextValue DpiAwarenessContext { get; set; } + internal DpiScale2 CurrentDpiScale { get; private set; } + internal static bool IsPerMonitorDpiScalingSupportedOnCurrentPlatform { get @@ -2300,7 +2301,7 @@ public override Visual RootVisual // output is the index that will be set to the visual flags. if (IsProcessPerMonitorDpiAware == true) { - DpiFlags dpiFlags = DpiUtil.UpdateDpiScalesAndGetIndex(_currentDpiScale.PixelsPerInchX, _currentDpiScale.PixelsPerInchY); + DpiFlags dpiFlags = DpiUtil.UpdateDpiScalesAndGetIndex(CurrentDpiScale.PixelsPerInchX, CurrentDpiScale.PixelsPerInchY); DpiScale newDpiScale = new DpiScale(UIElement.DpiScaleXValues[dpiFlags.Index], UIElement.DpiScaleYValues[dpiFlags.Index]); RootVisual.RecursiveSetDpiScaleVisualFlags(new DpiRecursiveChangeArgs( dpiFlags, RootVisual.GetDpi(), newDpiScale)); } @@ -2327,7 +2328,7 @@ public override Matrix TransformToDevice { VerifyAPIReadOnly(); Matrix m = Matrix.Identity; - m.Scale(_currentDpiScale.DpiScaleX, _currentDpiScale.DpiScaleY); + m.Scale(CurrentDpiScale.DpiScaleX, CurrentDpiScale.DpiScaleY); return m; } } @@ -2342,7 +2343,7 @@ public override Matrix TransformFromDevice { VerifyAPIReadOnly(); Matrix m = Matrix.Identity; - m.Scale(1.0f/_currentDpiScale.DpiScaleX, 1.0f/_currentDpiScale.DpiScaleY); + m.Scale(1.0f/CurrentDpiScale.DpiScaleX, 1.0f/CurrentDpiScale.DpiScaleY); return m; } }