[Color Picker] Handle default display refresh-rate sentinel values (#49973)

## Summary of the Pull Request

Treats `dmDisplayFrequency` values `0` and `1` as the display hardware's
default refresh rate instead of literal frequencies.

Color Picker now retains its existing 60 Hz fallback for these sentinel
values, preventing a timer interval overflow for `0` and one-second
sampling for `1`. Valid refresh rates greater than `1` remain unchanged.

## PR Checklist

- [x] Closes: #49971
- [ ] **Communication:** The issue has been filed for triage; this
change has not yet been discussed with core contributors
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** No end-user-facing strings were added
- [ ] **Dev docs:** Not applicable for this implementation-only bug fix
- [ ] **New binaries:** No new binaries were added
- [ ] **Documentation updated:** Not applicable; no user-facing
documentation contract changed

## Detailed Description of the Pull Request / Additional comments

`GetMainDisplayRefreshRate` now accepts a reported refresh rate only
when it is greater than `1`. Otherwise, it keeps the existing 60 Hz
fallback.

A small test seam and unit tests cover reported values `0`, `1`, `60`,
and `144`. The correct `InternalsVisibleTo` entry is added for the
existing `ColorPickerUI.UnitTests` assembly.

This issue was discovered while reviewing #49855, but it is an existing
bug and this PR targets current `main` independently. Since #49855 also
changes the refresh-rate code, whichever PR merges second may need a
trivial rebase that preserves the `> 1` sentinel handling.

No settings schema, IPC contract, dependencies, installer content, or
production binaries were changed.

## Validation Steps Performed

- `tools\build\build-essentials.cmd -Platform x64 -Configuration Debug`:
passed with exit code 0, 0 warnings, and 0 errors.
- `tools\build\build.cmd -Platform x64 -Configuration Debug` from
`ColorPickerUI.UnitTests`: passed with exit code 0, 0 warnings, and 0
errors.
- Full `vstest.console.exe` run for `ColorPickerUI.UnitTests.dll`: **382
passed, 0 failed**.
- `git diff --check`: passed.

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7b3fb20d-6e9d-4fef-a5cd-f8921d28c220
This commit is contained in:
moooyo
2026-08-17 16:58:36 +08:00
committed by Boliang Zhang (from Dev Box)
parent a9db875e21
commit e213200b5a
3 changed files with 32 additions and 2 deletions

View File

@@ -0,0 +1,23 @@
// 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 ColorPicker.Mouse;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ColorPicker.UnitTests.Mouse
{
[TestClass]
public class DisplayRefreshRateTest
{
[TestMethod]
[DataRow(0, 60.0)]
[DataRow(1, 60.0)]
[DataRow(60, 60.0)]
[DataRow(144, 144.0)]
public void GetDisplayRefreshRateOrDefault_HandlesDefaultRefreshRateSentinels(int displayFrequency, double expectedRefreshRate)
{
Assert.AreEqual(expectedRefreshRate, MouseInfoProvider.GetDisplayRefreshRateOrDefault((uint)displayFrequency));
}
}
}

View File

@@ -7,6 +7,7 @@ using System.ComponentModel.Composition.Hosting;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("UnitTest-ColorPickerUI")]
[assembly: InternalsVisibleTo("ColorPickerUI.UnitTests")]
namespace ColorPicker
{

View File

@@ -21,6 +21,8 @@ namespace ColorPicker.Mouse
[PartCreationPolicy(CreationPolicy.Shared)]
public class MouseInfoProvider : IMouseInfoProvider
{
private const double DefaultDisplayRefreshRate = 60.0;
private readonly double _mousePullInfoIntervalInMs;
private readonly DispatcherTimer _timer = new DispatcherTimer();
private readonly MouseHook _mouseHook;
@@ -123,13 +125,13 @@ namespace ColorPicker.Mouse
private static double GetMainDisplayRefreshRate()
{
double refreshRate = 60.0;
double refreshRate = DefaultDisplayRefreshRate;
foreach (var monitor in MonitorResolutionHelper.AllMonitors)
{
if (monitor.IsPrimary && EnumDisplaySettingsW(monitor.Name, ENUM_CURRENT_SETTINGS, out DEVMODEW lpDevMode))
{
refreshRate = (double)lpDevMode.dmDisplayFrequency;
refreshRate = GetDisplayRefreshRateOrDefault(lpDevMode.dmDisplayFrequency);
break;
}
}
@@ -137,6 +139,10 @@ namespace ColorPicker.Mouse
return refreshRate;
}
// EnumDisplaySettings uses 0 and 1 to represent the hardware default refresh rate.
internal static double GetDisplayRefreshRateOrDefault(uint displayFrequency)
=> displayFrequency > 1 ? displayFrequency : DefaultDisplayRefreshRate;
private void AppStateMonitor_AppClosed(object sender, EventArgs e)
{
DisposeHook();