Compare commits

...

2 Commits

Author SHA1 Message Date
vanzue
71b4f205b6 Update check-spelling metadata 2026-01-29 16:13:14 +08:00
vanzue
d9b8407cd0 Fix an overlay issue 2026-01-29 15:56:08 +08:00
4 changed files with 74 additions and 4 deletions

View File

@@ -1022,6 +1022,7 @@ MERGECOPY
MERGEPAINT
metadatamatters
Metadatas
Metacharacter
metafile
mfc
Mgmt

View File

@@ -2,8 +2,11 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Windows;
using WorkspacesEditor.Utils;
namespace WorkspacesEditor
{
/// <summary>
@@ -11,9 +14,40 @@ namespace WorkspacesEditor
/// </summary>
public partial class OverlayWindow : Window
{
private int _targetX;
private int _targetY;
private int _targetWidth;
private int _targetHeight;
public OverlayWindow()
{
InitializeComponent();
SourceInitialized += OnWindowSourceInitialized;
}
/// <summary>
/// Sets the target bounds for the overlay window.
/// The window will be positioned using DPI-unaware context after initialization.
/// </summary>
public void SetTargetBounds(int x, int y, int width, int height)
{
_targetX = x;
_targetY = y;
_targetWidth = width;
_targetHeight = height;
// Set initial WPF properties (will be corrected after HWND creation)
Left = x;
Top = y;
Width = width;
Height = height;
}
private void OnWindowSourceInitialized(object sender, EventArgs e)
{
// Reposition window using DPI-unaware context to match the virtual coordinates.
// This fixes overlay positioning on mixed-DPI multi-monitor setups.
NativeMethods.SetWindowPositionDpiUnaware(this, _targetX, _targetY, _targetWidth, _targetHeight);
}
}
}

View File

@@ -4,6 +4,8 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace WorkspacesEditor.Utils
{
@@ -17,6 +19,39 @@ namespace WorkspacesEditor.Utils
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
private static extern IntPtr SetThreadDpiAwarenessContext(IntPtr dpiContext);
private const uint SWP_NOZORDER = 0x0004;
private const uint SWP_NOACTIVATE = 0x0010;
private static readonly IntPtr DPI_AWARENESS_CONTEXT_UNAWARE = new IntPtr(-1);
/// <summary>
/// Positions a WPF window using DPI-unaware context to match the virtual coordinates.
/// This fixes overlay positioning on mixed-DPI multi-monitor setups.
/// </summary>
public static void SetWindowPositionDpiUnaware(Window window, int x, int y, int width, int height)
{
var helper = new WindowInteropHelper(window).Handle;
if (helper != IntPtr.Zero)
{
// Temporarily switch to DPI-unaware context to position window.
IntPtr oldContext = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
try
{
SetWindowPos(helper, IntPtr.Zero, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
}
finally
{
SetThreadDpiAwarenessContext(oldContext);
}
}
}
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

View File

@@ -495,10 +495,10 @@ namespace WorkspacesEditor.ViewModels
{
var bounds = screen.Bounds;
OverlayWindow overlayWindow = new OverlayWindow();
overlayWindow.Top = bounds.Top;
overlayWindow.Left = bounds.Left;
overlayWindow.Width = bounds.Width;
overlayWindow.Height = bounds.Height;
// Use DPI-unaware positioning to fix overlay on mixed-DPI multi-monitor setups
overlayWindow.SetTargetBounds(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
overlayWindow.ShowActivated = true;
overlayWindow.Topmost = true;
overlayWindow.Show();