This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Threading;
|
||||||
using CursorLang.Core.Interop;
|
using CursorLang.Core.Interop;
|
||||||
using CursorLang.Settings.Interop;
|
using CursorLang.Settings.Interop;
|
||||||
|
|
||||||
@@ -29,6 +30,10 @@ public sealed class MainWindowPlacement
|
|||||||
// previous, shorter one left behind
|
// previous, shorter one left behind
|
||||||
private double? _designMaxHeight;
|
private double? _designMaxHeight;
|
||||||
|
|
||||||
|
// Captured once, so a DPI change has a known-correct value to reassert — see
|
||||||
|
// RestoreDesignWidth
|
||||||
|
private double? _designWidth;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Takes over the placement of the window: puts it in place by the first show
|
/// Takes over the placement of the window: puts it in place by the first show
|
||||||
/// and follows where the user moves it.
|
/// and follows where the user moves it.
|
||||||
@@ -91,6 +96,7 @@ public sealed class MainWindowPlacement
|
|||||||
|
|
||||||
window.SourceInitialized -= OnSourceInitialized;
|
window.SourceInitialized -= OnSourceInitialized;
|
||||||
_designMaxHeight = window.MaxHeight;
|
_designMaxHeight = window.MaxHeight;
|
||||||
|
_designWidth = window.Width;
|
||||||
|
|
||||||
LimitHeightToOwnMonitor(window);
|
LimitHeightToOwnMonitor(window);
|
||||||
window.UpdateLayout();
|
window.UpdateLayout();
|
||||||
@@ -109,13 +115,32 @@ public sealed class MainWindowPlacement
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deferred rather than run inline: this event fires while WPF is still in
|
||||||
|
// the middle of its own response to the same DPI change (its per-monitor
|
||||||
|
// rescale of Width touches it after this handler if the fix-up runs
|
||||||
|
// synchronously, undoing it). Posting behind that on the dispatcher queue
|
||||||
|
// lets our fix-up run once WPF's own pass has finished.
|
||||||
|
window.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() =>
|
||||||
|
{
|
||||||
LimitHeightToOwnMonitor(window);
|
LimitHeightToOwnMonitor(window);
|
||||||
|
RestoreDesignWidth(window);
|
||||||
// Only the size is revisited here, not the position: the window is commonly
|
|
||||||
// being dragged across monitors right when its DPI changes, and moving it
|
|
||||||
// ourselves in the middle of that would fight the drag the user is already
|
|
||||||
// doing
|
|
||||||
ReapplySizeToContent(window);
|
ReapplySizeToContent(window);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The width is a plain, explicit value rather than something SizeToContent
|
||||||
|
// computes, and WPF's own per-monitor rescaling does not reliably keep it at the
|
||||||
|
// same logical width when the system's scaling changes live under an
|
||||||
|
// already-open window, as opposed to the window being dragged onto a different
|
||||||
|
// monitor — it can come out scaled by roughly the ratio between the old and the
|
||||||
|
// new DPI instead of staying put. Reasserting the original value here is simpler
|
||||||
|
// than chasing exactly where that rescale goes wrong.
|
||||||
|
private void RestoreDesignWidth(Window window)
|
||||||
|
{
|
||||||
|
if (_designWidth is { } designWidth)
|
||||||
|
{
|
||||||
|
window.Width = designWidth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateLayout alone settles the measure/arrange pass of the visual tree, but
|
// UpdateLayout alone settles the measure/arrange pass of the visual tree, but
|
||||||
|
|||||||
Reference in New Issue
Block a user