mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 20:27:36 +02:00
Powertoys Extension: Trigger latest layout/monitor refresh for fancyzone in cmdpal extension (#44756)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Best effort trigger refresh for the monitor/layout refresh for fancyzones, user may experience error for first time run but will get correct result in next visit. This bring better experience than the always-stale-state, while still remain performant command. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Validated locally that second time visit will bring correct monitor when plug/unplug monitor
This commit is contained in:
@@ -41,16 +41,13 @@ internal static class FancyZonesDataService
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!File.Exists(FZPaths.EditorParameters))
|
// Request FancyZones to save current monitor configuration.
|
||||||
{
|
// The editor-parameters.json file is only written when:
|
||||||
error = Resources.FancyZones_MonitorDataNotFound;
|
// 1. Opening the FancyZones Editor
|
||||||
Logger.LogWarning($"TryGetMonitors: File not found. Path={FZPaths.EditorParameters}");
|
// 2. Receiving the WM_PRIV_SAVE_EDITOR_PARAMETERS message
|
||||||
return false;
|
// Without this, monitor changes (plug/unplug) won't be reflected in the file.
|
||||||
}
|
var editorParams = ReadEditorParametersWithRefresh();
|
||||||
|
Logger.LogInfo($"TryGetMonitors: ReadEditorParametersWithRefreshWithRefresh returned. Monitors={editorParams.Monitors?.Count ?? -1}");
|
||||||
Logger.LogInfo($"TryGetMonitors: File exists, reading...");
|
|
||||||
var editorParams = FancyZonesDataIO.ReadEditorParameters();
|
|
||||||
Logger.LogInfo($"TryGetMonitors: ReadEditorParameters returned. Monitors={editorParams.Monitors?.Count ?? -1}");
|
|
||||||
|
|
||||||
var editorMonitors = editorParams.Monitors;
|
var editorMonitors = editorParams.Monitors;
|
||||||
if (editorMonitors is null || editorMonitors.Count == 0)
|
if (editorMonitors is null || editorMonitors.Count == 0)
|
||||||
@@ -74,6 +71,23 @@ internal static class FancyZonesDataService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests FancyZones to save the current monitor configuration and reads the file.
|
||||||
|
/// This is a best-effort approach for performance: we send the save request and immediately
|
||||||
|
/// read the file without waiting. If the file hasn't been updated yet, the next call will
|
||||||
|
/// see the updated data since FancyZones processes the message asynchronously.
|
||||||
|
/// </summary>
|
||||||
|
private static EditorParameters.ParamsWrapper ReadEditorParametersWithRefresh()
|
||||||
|
{
|
||||||
|
// Request FancyZones to save the current monitor configuration.
|
||||||
|
// This is fire-and-forget for performance - we don't wait for the save to complete.
|
||||||
|
// If this is the first call after a monitor change, we may read stale data, but the
|
||||||
|
// next call will see the updated file since FancyZones will have processed the message.
|
||||||
|
FancyZonesNotifier.NotifySaveEditorParameters();
|
||||||
|
|
||||||
|
return FancyZonesDataIO.ReadEditorParameters();
|
||||||
|
}
|
||||||
|
|
||||||
public static IReadOnlyList<FancyZonesLayoutDescriptor> GetLayouts()
|
public static IReadOnlyList<FancyZonesLayoutDescriptor> GetLayouts()
|
||||||
{
|
{
|
||||||
Logger.LogInfo($"GetLayouts: Starting. LayoutTemplatesPath={FZPaths.LayoutTemplates} CustomLayoutsPath={FZPaths.CustomLayouts}");
|
Logger.LogInfo($"GetLayouts: Starting. LayoutTemplatesPath={FZPaths.LayoutTemplates} CustomLayoutsPath={FZPaths.CustomLayouts}");
|
||||||
|
|||||||
@@ -10,13 +10,25 @@ namespace PowerToysExtension.Helpers;
|
|||||||
internal static class FancyZonesNotifier
|
internal static class FancyZonesNotifier
|
||||||
{
|
{
|
||||||
private const string AppliedLayoutsFileUpdateMessage = "{2ef2c8a7-e0d5-4f31-9ede-52aade2d284d}";
|
private const string AppliedLayoutsFileUpdateMessage = "{2ef2c8a7-e0d5-4f31-9ede-52aade2d284d}";
|
||||||
|
private const string SaveEditorParametersMessage = "{d8f9c0e3-5d77-4e83-8a4f-7c704c2bfb4a}";
|
||||||
|
|
||||||
private static readonly uint WmPrivAppliedLayoutsFileUpdate = RegisterWindowMessageW(AppliedLayoutsFileUpdateMessage);
|
private static readonly uint WmPrivAppliedLayoutsFileUpdate = RegisterWindowMessageW(AppliedLayoutsFileUpdateMessage);
|
||||||
|
private static readonly uint WmPrivSaveEditorParameters = RegisterWindowMessageW(SaveEditorParametersMessage);
|
||||||
|
|
||||||
public static void NotifyAppliedLayoutsChanged()
|
public static void NotifyAppliedLayoutsChanged()
|
||||||
{
|
{
|
||||||
_ = PostMessageW(new IntPtr(0xFFFF), WmPrivAppliedLayoutsFileUpdate, UIntPtr.Zero, IntPtr.Zero);
|
_ = PostMessageW(new IntPtr(0xFFFF), WmPrivAppliedLayoutsFileUpdate, UIntPtr.Zero, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notifies FancyZones to save the current monitor configuration to editor-parameters.json.
|
||||||
|
/// This is needed because FancyZones only writes this file when opening the editor or when explicitly requested.
|
||||||
|
/// </summary>
|
||||||
|
public static void NotifySaveEditorParameters()
|
||||||
|
{
|
||||||
|
_ = PostMessageW(new IntPtr(0xFFFF), WmPrivSaveEditorParameters, UIntPtr.Zero, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
private static extern uint RegisterWindowMessageW(string lpString);
|
private static extern uint RegisterWindowMessageW(string lpString);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user