diff --git a/Ninjacrab.PersistentWindows.Solution/Common/Models/ApplicationDisplayMetrics.cs b/Ninjacrab.PersistentWindows.Solution/Common/Models/ApplicationDisplayMetrics.cs index 07b60a3..a2f85c7 100644 --- a/Ninjacrab.PersistentWindows.Solution/Common/Models/ApplicationDisplayMetrics.cs +++ b/Ninjacrab.PersistentWindows.Solution/Common/Models/ApplicationDisplayMetrics.cs @@ -39,6 +39,7 @@ namespace PersistentWindows.Common.Models public RECT ScreenPosition { get; set; } public WindowPlacement WindowPlacement { get; set; } public bool NeedUpdateWindowPlacement { get; set; } //non-persistent data used for tmp argument passing only + public uint Dpi { get; set; } // window z-order public bool IsTopMost { get; set; } diff --git a/Ninjacrab.PersistentWindows.Solution/Common/PersistentWindowProcessor.cs b/Ninjacrab.PersistentWindows.Solution/Common/PersistentWindowProcessor.cs index 28599a4..43bd4a6 100644 --- a/Ninjacrab.PersistentWindows.Solution/Common/PersistentWindowProcessor.cs +++ b/Ninjacrab.PersistentWindows.Solution/Common/PersistentWindowProcessor.cs @@ -2008,7 +2008,7 @@ namespace PersistentWindows.Common { if (debugWindows.Contains(hWnd)) { - string log = string.Format("Captured {0,-8} at ({1}, {2}) of size {3} x {4} {5} fullscreen:{6} minimized:{7}", + string log = string.Format("Captured {0,-8} at ({1}, {2}) of size {3} x {4} {5} fullscreen:{6} minimized:{7}, dpi:{8}", curDisplayMetrics, curDisplayMetrics.ScreenPosition.Left, curDisplayMetrics.ScreenPosition.Top, @@ -2016,7 +2016,8 @@ namespace PersistentWindows.Common curDisplayMetrics.ScreenPosition.Height, curDisplayMetrics.Title, curDisplayMetrics.IsFullScreen, - curDisplayMetrics.IsMinimized + curDisplayMetrics.IsMinimized, + curDisplayMetrics.Dpi ); Log.Event(log); @@ -2423,6 +2424,8 @@ namespace PersistentWindows.Common RECT screenPosition = new RECT(); User32.GetWindowRect(hwnd, ref screenPosition); + uint dpi = User32.GetDpiForWindow(hwnd); + bool isMinimized = IsMinimized(hwnd); IntPtr realHwnd = hwnd; @@ -2460,6 +2463,7 @@ namespace PersistentWindows.Common WindowPlacement = windowPlacement, NeedUpdateWindowPlacement = false, ScreenPosition = screenPosition, + Dpi = dpi, IsTopMost = IsWindowTopMost(hwnd), NeedClearTopMost = false, @@ -2592,13 +2596,24 @@ namespace PersistentWindows.Common */ } + /* if (!prevDisplayMetrics.EqualPlacement(curDisplayMetrics)) { curDisplayMetrics.NeedUpdateWindowPlacement = true; moved = true; } - else if (!prevDisplayMetrics.ScreenPosition.Equals(curDisplayMetrics.ScreenPosition)) + else*/ if (!prevDisplayMetrics.ScreenPosition.Equals(curDisplayMetrics.ScreenPosition)) { + if (prevDisplayMetrics.Dpi > 0 && curDisplayMetrics.Dpi != prevDisplayMetrics.Dpi) + { + if (curDisplayMetrics.ScreenPosition.Width * curDisplayMetrics.Dpi == prevDisplayMetrics.ScreenPosition.Width * prevDisplayMetrics.Dpi) + if (curDisplayMetrics.ScreenPosition.Height * curDisplayMetrics.Dpi == prevDisplayMetrics.ScreenPosition.Height * prevDisplayMetrics.Dpi) + { + // workaround #289 + Log.Error($"ignore sudden scale ratio change for {GetWindowTitle(hwnd)}, prev DPI {prevDisplayMetrics.Dpi}, prev location {prevDisplayMetrics.ScreenPosition}, cur DPI {curDisplayMetrics.Dpi}, cur location {curDisplayMetrics.ScreenPosition}"); + return false; + } + } moved = true; } else if (!curDisplayMetrics.IsMinimized && prevDisplayMetrics.IsMinimized) diff --git a/Ninjacrab.PersistentWindows.Solution/Common/WinApiBridge/User32.cs b/Ninjacrab.PersistentWindows.Solution/Common/WinApiBridge/User32.cs index 36bbb15..f506a67 100644 --- a/Ninjacrab.PersistentWindows.Solution/Common/WinApiBridge/User32.cs +++ b/Ninjacrab.PersistentWindows.Solution/Common/WinApiBridge/User32.cs @@ -493,6 +493,10 @@ namespace PersistentWindows.Common.WinApiBridge [DllImport("user32.dll")] public static extern bool IsWindowOnCurrentVirtualDesktop(IntPtr hWnd); + [DllImport("user32.dll", SetLastError = true)] + public static extern uint GetDpiForWindow(IntPtr hWnd); + + public static bool DpiSenstiveCall = true; [DllImport("user32.dll")] public static extern bool SetProcessDpiAwarenessContext(int dpi_awareness_cxt); [DllImport("user32.dll")] @@ -508,11 +512,22 @@ namespace PersistentWindows.Common.WinApiBridge if (os_version.Version.Major < 10) return 0; + /* // windows 11 workaround for #289 if (os_version.Version.Build > 22000) if (dpi_awareness_cxt == DPI_AWARENESS_CONTEXT_UNAWARE) return 0; + if (dpi_awareness_cxt == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) + return 0; + if (dpi_awareness_cxt == DPI_AWARENESS_CONTEXT_UNAWARE) + //dpi_awareness_cxt = DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + //dpi_awareness_cxt = DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED; + dpi_awareness_cxt = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; + */ + if (!DpiSenstiveCall) + return 0; + //valid API since win10 1607 return SetThreadDpiAwarenessContext(dpi_awareness_cxt); } diff --git a/Ninjacrab.PersistentWindows.Solution/SystrayShell/Program.cs b/Ninjacrab.PersistentWindows.Solution/SystrayShell/Program.cs index b52c09f..a474baa 100644 --- a/Ninjacrab.PersistentWindows.Solution/SystrayShell/Program.cs +++ b/Ninjacrab.PersistentWindows.Solution/SystrayShell/Program.cs @@ -147,6 +147,9 @@ namespace PersistentWindows.SystrayShell case "-delay_auto_capture": delay_auto_capture = 1; break; + case "-dpi_sensitive_call=0": + User32.DpiSenstiveCall = false; + break; case "-redirect_appdata": redirect_appdata = true; break;