diff --git a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs index 1832bbbb8b..f2e2ec723c 100644 --- a/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs +++ b/src/modules/launcher/PowerLauncher/Helper/WindowsInteropHelper.cs @@ -10,6 +10,7 @@ using System.Windows; using System.Windows.Forms; using System.Windows.Interop; using System.Windows.Media; +using Point = System.Windows.Point; namespace PowerLauncher.Helper { @@ -187,15 +188,18 @@ namespace PowerLauncher.Helper _ = NativeMethods.SetWindowLong(hwnd, GWL_EX_STYLE, NativeMethods.GetWindowLong(hwnd, GWL_EX_STYLE) | WS_EX_TOOLWINDOW); } - public static void MoveToScreenCenter(Window window, Screen screen) + /// + /// Transforms pixels to Device Independent Pixels used by WPF + /// + /// current window, required to get presentation source + /// horizontal position in pixels + /// vertical position in pixels + /// point containing device independent pixels + public static Point TransformPixelsToDIP(Visual visual, double unitX, double unitY) { - var workingArea = screen.WorkingArea; - var matrix = GetCompositionTarget(window).TransformFromDevice; - var dpiX = matrix.M11; - var dpiY = matrix.M22; + var matrix = GetCompositionTarget(visual).TransformFromDevice; - window.Left = (dpiX * workingArea.Left) + (((dpiX * workingArea.Width) - window.Width) / 2); - window.Top = (dpiY * workingArea.Top) + (((dpiY * workingArea.Height) - window.Height) / 2); + return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY)); } private static CompositionTarget GetCompositionTarget(Visual visual) diff --git a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs index 600af8dc6d..e402ed44f8 100644 --- a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs +++ b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs @@ -449,14 +449,22 @@ namespace PowerLauncher // In terms of the hack itself, removing any of these three steps seems to fail in certain scenarios only, // so be careful with testing! var desiredScreen = GetScreen(); + var workingArea = desiredScreen.WorkingArea; + Point ToDIP(double unitX, double unitY) => WindowsInteropHelper.TransformPixelsToDIP(this, unitX, unitY); // Move to top-left of desired screen. - Top = desiredScreen.WorkingArea.Top; - Left = desiredScreen.WorkingArea.Left; + Top = workingArea.Top; + Left = workingArea.Left; // Centralize twice. - WindowsInteropHelper.MoveToScreenCenter(this, desiredScreen); - WindowsInteropHelper.MoveToScreenCenter(this, desiredScreen); + void MoveToScreenTopCenter() + { + Left = ((ToDIP(workingArea.Width, 0).X - ActualWidth) / 2) + ToDIP(workingArea.X, 0).X; + Top = ((ToDIP(0, workingArea.Height).Y - SearchBox.ActualHeight) / 4) + ToDIP(0, workingArea.Y).Y; + } + + MoveToScreenTopCenter(); + MoveToScreenTopCenter(); } private void OnLocationChanged(object sender, EventArgs e)