Skip to content

Commit

Permalink
Merge pull request dotnet#21 from dotnet-campus/t/lindexi/GetAndCache…
Browse files Browse the repository at this point in the history
…TransformToDeviceMatrix_GitHub

Fix get TransformToDevice in Stylus Input thread will throw the InvalidOperationException
  • Loading branch information
kkwpsv authored Jul 22, 2022
2 parents 3e5d124 + 0ba23e1 commit ff4c143
Showing 1 changed file with 31 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -419,16 +419,41 @@ protected Matrix GetAndCacheTransformToDeviceMatrix(PresentationSource source)
var hwndSource = source as HwndSource;
Matrix toDevice = Matrix.Identity;

if (hwndSource?.CompositionTarget != null)
HwndTarget compositionTarget = hwndSource?.CompositionTarget;
if (compositionTarget != null)
{
// If we have not yet seen this DPI, store the matrix for it.
if (!_transformToDeviceMatrices.ContainsKey(hwndSource.CompositionTarget.CurrentDpiScale))
// We can calculate the Matrix fast without any cache and avoid any thread issues.
// If others inherit HwndTarget, the following rules may not apply. Because they can override the TransformToDevice property.
// Fix https://github.com/dotnet/wpf/issues/6829
Type compositionTargetType = compositionTarget.GetType();
if (compositionTargetType == typeof(HwndTarget))
{
_transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale] = hwndSource.CompositionTarget.TransformToDevice;
Debug.Assert(_transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale].HasInverse);
DpiScale2 currentDpiScale = compositionTarget.CurrentDpiScale;
toDevice.Scale(currentDpiScale.DpiScaleX, currentDpiScale.DpiScaleY);
}
else
{
// If we have not yet seen this DPI, store the matrix for it.
if (!_transformToDeviceMatrices.ContainsKey(compositionTarget.CurrentDpiScale))
{
// The Stylus Input thread will enter this case.
if (compositionTarget.Dispatcher.CheckAccess())
{
_transformToDeviceMatrices[compositionTarget.CurrentDpiScale] = compositionTarget.TransformToDevice;
}
else
{
// We have to run it in UI Thread, see https://github.com/dotnet/wpf/issues/6829
compositionTarget.Dispatcher.Invoke(() =>
_transformToDeviceMatrices[compositionTarget.CurrentDpiScale] =
compositionTarget.TransformToDevice);
}

toDevice = _transformToDeviceMatrices[hwndSource.CompositionTarget.CurrentDpiScale];
Debug.Assert(_transformToDeviceMatrices[compositionTarget.CurrentDpiScale].HasInverse);
}

toDevice = _transformToDeviceMatrices[compositionTarget.CurrentDpiScale];
}
}

return toDevice;
Expand Down

0 comments on commit ff4c143

Please sign in to comment.