Skip to content

Commit

Permalink
Merge pull request #44 from Aelarion/main
Browse files Browse the repository at this point in the history
Fix DPI scaling issue with restore-drag functionality
  • Loading branch information
pomianowski committed Jan 25, 2022
2 parents a0795c3 + 04052fe commit cfedcf2
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
71 changes: 71 additions & 0 deletions WPFUI/Common/Dpi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WPFUI.Common
{
/// <summary>
/// Provides access to various DPI-related methods.
/// </summary>
internal static class Dpi
{
// TODO: look into utilizing preprocessor symbols for more functionality
// ----
// There is an opportunity to check against NET46 if we can use
// VisualTreeHelper in this class. We are currently not utilizing
// it because it is not available in .NET Framework 4.6 (available
// starting 4.6.2). For now, there is no need to overcomplicate this
// solution for some infrequent DPI calculations. However, if this
// becomes more central to various implementations, we may want to
// look into fleshing it out a bit further.
// ----
// Reference: https://docs.microsoft.com/en-us/dotnet/standard/frameworks

/// <summary>
/// Gets the horizontal DPI value from <see cref="SystemParameters"/>.
/// </summary>
/// <returns>The horizontal DPI value from <see cref="SystemParameters"/>. If the property cannot be accessed, the default value 96 is returned.</returns>
internal static int SystemDpiX()
{
var dpiProperty = typeof(SystemParameters).GetProperty("DpiX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (dpiProperty == null)
return 96;

return (int)dpiProperty.GetValue(null, null);
}

/// <summary>
/// Gets the horizontal DPI scale factor based on <see cref="SystemParameters"/>.
/// </summary>
/// <returns>The horizontal DPI scale factor.</returns>
internal static double SystemDpiXScale()
{
return SystemDpiX() / 96.0;
}

/// <summary>
/// Gets the vertical DPI value from <see cref="SystemParameters"/>.
/// </summary>
/// <returns>The vertical DPI value from <see cref="SystemParameters"/>. If the property cannot be accessed, the default value 96 is returned.</returns>
internal static int SystemDpiY()
{
var dpiProperty = typeof(SystemParameters).GetProperty("Dpi", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (dpiProperty == null)
return 96;

return (int)dpiProperty.GetValue(null, null);
}

/// <summary>
/// Gets the vertical DPI scale factor based on <see cref="SystemParameters"/>.
/// </summary>
/// <returns>The vertical DPI scale factor.</returns>
internal static double SystemDpiYScale()
{
return SystemDpiY() / 96.0;
}
}
}
4 changes: 3 additions & 1 deletion WPFUI/Controls/TitleBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ private void RootGrid_MouseMove(object sender, MouseEventArgs e)
if (IsMaximized)
{
var screenPoint = PointToScreen(e.MouseDevice.GetPosition(this));
screenPoint.X /= Common.Dpi.SystemDpiXScale();
screenPoint.Y /= Common.Dpi.SystemDpiYScale();

// TODO: refine the Left value to be more accurate
// - This calculation is good enough using the center
Expand All @@ -481,7 +483,7 @@ private void RootGrid_MouseMove(object sender, MouseEventArgs e)
// - It should be set as a % (e.g. screen X / maximized width),
// then offset from the left to line up more naturally.
ParentWindow.Left = screenPoint.X - (ParentWindow.RestoreBounds.Width * 0.5);
ParentWindow.Top = 0d;
ParentWindow.Top = screenPoint.Y;

// style has to be quickly swapped to avoid restore animation delay
var style = ParentWindow.WindowStyle;
Expand Down

0 comments on commit cfedcf2

Please sign in to comment.