mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 04:37:30 +02:00
[Settings]restore window size and position (#13912)
This commit is contained in:
committed by
GitHub
parent
59108365f1
commit
db90802e6e
21
src/settings-ui/PowerToys.Settings/Helpers/NativeMethods.cs
Normal file
21
src/settings-ui/PowerToys.Settings/Helpers/NativeMethods.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace PowerToys.Settings.Helpers
|
||||||
|
{
|
||||||
|
public static class NativeMethods
|
||||||
|
{
|
||||||
|
internal const int SW_SHOWNORMAL = 1;
|
||||||
|
internal const int SW_SHOWMAXIMIZED = 3;
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/settings-ui/PowerToys.Settings/Helpers/POINT.cs
Normal file
25
src/settings-ui/PowerToys.Settings/Helpers/POINT.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace PowerToys.Settings.Helpers
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||||
|
public struct POINT
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public POINT(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/settings-ui/PowerToys.Settings/Helpers/RECT.cs
Normal file
31
src/settings-ui/PowerToys.Settings/Helpers/RECT.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace PowerToys.Settings.Helpers
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||||
|
public struct RECT
|
||||||
|
{
|
||||||
|
public int Left { get; set; }
|
||||||
|
|
||||||
|
public int Top { get; set; }
|
||||||
|
|
||||||
|
public int Right { get; set; }
|
||||||
|
|
||||||
|
public int Bottom { get; set; }
|
||||||
|
|
||||||
|
public RECT(int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Top = top;
|
||||||
|
Right = right;
|
||||||
|
Bottom = bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace PowerToys.Settings.Helpers
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||||
|
public struct WINDOWPLACEMENT
|
||||||
|
{
|
||||||
|
public int Length { get; set; }
|
||||||
|
|
||||||
|
public int Flags { get; set; }
|
||||||
|
|
||||||
|
public int ShowCmd { get; set; }
|
||||||
|
|
||||||
|
public POINT MinPosition { get; set; }
|
||||||
|
|
||||||
|
public POINT MaxPosition { get; set; }
|
||||||
|
|
||||||
|
public RECT NormalPosition { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,16 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Interop;
|
||||||
using Microsoft.PowerLauncher.Telemetry;
|
using Microsoft.PowerLauncher.Telemetry;
|
||||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||||
using Microsoft.PowerToys.Settings.UI.Views;
|
using Microsoft.PowerToys.Settings.UI.Views;
|
||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
using Microsoft.Toolkit.Wpf.UI.XamlHost;
|
using Microsoft.Toolkit.Wpf.UI.XamlHost;
|
||||||
|
using PowerToys.Settings.Helpers;
|
||||||
using Windows.ApplicationModel.Resources;
|
using Windows.ApplicationModel.Resources;
|
||||||
using Windows.Data.Json;
|
using Windows.Data.Json;
|
||||||
|
|
||||||
@@ -28,8 +32,6 @@ namespace PowerToys.Settings
|
|||||||
|
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
|
|
||||||
Utils.FitToScreen(this);
|
|
||||||
|
|
||||||
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse();
|
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse();
|
||||||
Title = loader.GetString("SettingsWindow_Title");
|
Title = loader.GetString("SettingsWindow_Title");
|
||||||
|
|
||||||
@@ -55,6 +57,36 @@ namespace PowerToys.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnSourceInitialized(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnSourceInitialized(e);
|
||||||
|
|
||||||
|
Utils.FitToScreen(this);
|
||||||
|
|
||||||
|
var handle = new WindowInteropHelper(this).Handle;
|
||||||
|
NativeMethods.GetWindowPlacement(handle, out var startupPlacement);
|
||||||
|
var placement = Utils.DeserializePlacementOrDefault(handle);
|
||||||
|
NativeMethods.SetWindowPlacement(handle, ref placement);
|
||||||
|
|
||||||
|
var windowRect = new Rectangle((int)Left, (int)Top, (int)Width, (int)Height);
|
||||||
|
var screenRect = new Rectangle((int)SystemParameters.VirtualScreenLeft, (int)SystemParameters.VirtualScreenTop, (int)SystemParameters.VirtualScreenWidth, (int)SystemParameters.VirtualScreenHeight);
|
||||||
|
var intersection = Rectangle.Intersect(windowRect, screenRect);
|
||||||
|
|
||||||
|
// Restore default position if 1/4 of width or height of the window is offscreen
|
||||||
|
if (intersection.Width < (Width * 0.75) || intersection.Height < (Height * 0.75))
|
||||||
|
{
|
||||||
|
NativeMethods.SetWindowPlacement(handle, ref startupPlacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnClosing(CancelEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnClosing(e);
|
||||||
|
var handle = new WindowInteropHelper(this).Handle;
|
||||||
|
|
||||||
|
Utils.SerializePlacement(handle);
|
||||||
|
}
|
||||||
|
|
||||||
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
|
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// If sender is null, it could lead to a NullReferenceException. This might occur on restarting as admin (check https://github.com/microsoft/PowerToys/issues/7393 for details)
|
// If sender is null, it could lead to a NullReferenceException. This might occur on restarting as admin (check https://github.com/microsoft/PowerToys/issues/7393 for details)
|
||||||
|
|||||||
@@ -2,12 +2,19 @@
|
|||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using PowerToys.Settings.Helpers;
|
||||||
|
|
||||||
namespace PowerToys.Settings
|
namespace PowerToys.Settings
|
||||||
{
|
{
|
||||||
internal class Utils
|
internal class Utils
|
||||||
{
|
{
|
||||||
|
private static string _placementPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\PowerToys\settings-placement.json");
|
||||||
|
|
||||||
public static void FitToScreen(Window window)
|
public static void FitToScreen(Window window)
|
||||||
{
|
{
|
||||||
if (SystemParameters.WorkArea.Width < window.Width)
|
if (SystemParameters.WorkArea.Width < window.Width)
|
||||||
@@ -66,5 +73,45 @@ namespace PowerToys.Settings
|
|||||||
window.MinWidth = originalMinWidth;
|
window.MinWidth = originalMinWidth;
|
||||||
window.ShowInTaskbar = true;
|
window.ShowInTaskbar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static WINDOWPLACEMENT DeserializePlacementOrDefault(IntPtr handle)
|
||||||
|
{
|
||||||
|
if (File.Exists(_placementPath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = File.ReadAllText(_placementPath);
|
||||||
|
var placement = JsonSerializer.Deserialize<WINDOWPLACEMENT>(json);
|
||||||
|
|
||||||
|
placement.Length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
|
||||||
|
placement.Flags = 0;
|
||||||
|
placement.ShowCmd = placement.ShowCmd == NativeMethods.SW_SHOWMAXIMIZED ? NativeMethods.SW_SHOWMAXIMIZED : NativeMethods.SW_SHOWNORMAL;
|
||||||
|
return placement;
|
||||||
|
}
|
||||||
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
|
catch (Exception)
|
||||||
|
#pragma warning restore CA1031 // Do not catch general exception types
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = NativeMethods.GetWindowPlacement(handle, out var defaultPlacement);
|
||||||
|
return defaultPlacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SerializePlacement(IntPtr handle)
|
||||||
|
{
|
||||||
|
_ = NativeMethods.GetWindowPlacement(handle, out var placement);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = JsonSerializer.Serialize(placement);
|
||||||
|
File.WriteAllText(_placementPath, json);
|
||||||
|
}
|
||||||
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
|
catch (Exception)
|
||||||
|
#pragma warning restore CA1031 // Do not catch general exception types
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user