Skip to content

[Screen Ruler] Add DIP as an extra measurement unit - #49588

Open
niels9001 wants to merge 2 commits into
mainfrom
screen-ruler-measurement-units
Open

[Screen Ruler] Add DIP as an extra measurement unit#49588
niels9001 wants to merge 2 commits into
mainfrom
screen-ruler-measurement-units

Conversation

@niels9001

@niels9001 niels9001 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary of the Pull Request

Adds display-independent pixels (DIP) to Screen Ruler's existing Extra units of measurement setting. Physical pixels remain the primary overlay value; selecting DIP adds a second, parenthesized measurement that adjusts for Windows display scaling.

DIP values use the DPI of the monitor containing the measurement. This also corrects the millimeter fallback conversion when physical monitor dimensions are unavailable.

image

Before vs after:

image

PR Checklist

Detailed Description of the Pull Request / Additional comments

  • Preserves the existing persisted values for pixels, inches, centimeters, and millimeters; DIP is appended as value 4.
  • Preserves the existing overlay behavior: pixels are always displayed, with one optional extra unit on a second line.
  • Preserves the existing clipboard behavior: pixel-only output has no suffix, while a selected extra unit is copied by itself.
  • Converts physical pixels to DIP using each overlay window's monitor DPI.
  • Corrects the 96-DPI millimeter fallback so 96 px equals 25.4 mm.
  • Adds focused native conversion tests, settings compatibility tests, and DIP clipboard UI coverage.
  • Keeps guides, calibration, browser-relative units, and other measurement modes out of scope.

Validation Steps Performed

  • Built MeasureToolCore for ARM64 Debug.
  • Built MeasureToolUI for ARM64 Debug.
  • Built PowerToys Settings for ARM64 Debug.
  • Built and ran MeasureToolCore.UnitTests: 5 passed.
  • Built and ran the Screen Ruler settings tests: 6 passed.
  • Built ScreenRuler.UITests; local execution was not run because WinAppDriver is not installed.
  • Ran XAML Styler on the changed Settings page.

Show and copy only the selected unit, add per-monitor DIP conversion, and correct the physical-unit fallback. Preserve existing persisted unit values and add focused native, settings, and UI coverage.

Co-authored-by: Copilot App <[email protected]>
Copilot-Session: 1a6361cf-d701-4a9b-b8e8-d5700c5ba140
@github-actions github-actions Bot added the Product-Screen Ruler Refers to the Screen Ruler PowerToy label Jul 30, 2026
@niels9001
niels9001 requested a review from Copilot July 30, 2026 15:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a single measurement-unit setting to the Screen Ruler (MeasureTool) experience, so overlay and clipboard output are rendered in exactly one user-selected unit (Pixels, DIP, Inches, Centimeters, Millimeters), with DIP calculated using the DPI of the monitor containing the measurement.

Changes:

  • Updated Settings UI strings/XAML to present a single “Measurement unit” ComboBox option (including DIP).
  • Updated MeasureToolCore measurement pipeline to carry per-monitor DPI into conversions/formatting, fix mm fallback conversion, and print one unit (with explicit px suffix).
  • Added/updated unit tests (native conversion/formatting + settings serialization compatibility) and UITest coverage for DIP clipboard output.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/settings-ui/Settings.UI/Strings/en-us/Resources.resw Updates Settings strings for the new single measurement-unit setting and adds DIP option text.
src/settings-ui/Settings.UI/SettingsXAML/Views/MeasureToolPage.xaml Adds an AutomationId and appends the DIP option to the measurement unit ComboBox.
src/settings-ui/Settings.UI.UnitTests/ModelsTests/MeasureToolSettingsTests.cs Adds serialization/compatibility coverage for unit index persistence (including DIP).
src/modules/MeasureTool/Tests/ScreenRuler.UITests/TestHelper.cs Adds UI helper to set measurement unit and tightens clipboard validation to include explicit unit suffixes.
src/modules/MeasureTool/Tests/ScreenRuler.UITests/TestBounds.cs Adds a UITest validating DIP clipboard output for the bounds tool.
src/modules/MeasureTool/Tests/MeasureToolCore.UnitTests/MeasureToolCore.UnitTests.vcxproj Introduces a native unit test project for MeasureToolCore conversion/formatting logic.
src/modules/MeasureTool/Tests/MeasureToolCore.UnitTests/MeasurementLogicTests.cpp Adds focused native tests for DPI/DIP conversion, physical-unit fallback, and formatting behavior.
src/modules/MeasureTool/MeasureToolUI/Strings/en-us/Resources.resw Adds the DIP abbreviation resource used by the overlay/clipboard formatter.
src/modules/MeasureTool/MeasureToolCore/ToolState.h Adds a helper to retrieve per-window monitor DPI to support DIP conversion.
src/modules/MeasureTool/MeasureToolCore/ScreenCapturing.cpp Plumbs monitor DPI into captured measurements so conversions can be DPI-aware.
src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj.filters Adds MeasurementLogic.h to the project filters.
src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj Adds MeasurementLogic.h to the project includes.
src/modules/MeasureTool/MeasureToolCore/MeasureToolOverlayUI.cpp Switches overlay formatting to show only the selected unit (no forced pixel output).
src/modules/MeasureTool/MeasureToolCore/MeasurementLogic.h Adds shared conversion + formatting helper functions (including DIP + corrected mm fallback).
src/modules/MeasureTool/MeasureToolCore/Measurement.h Refactors Measurement to use MeasurementLogic and carry monitor DPI for conversions.
src/modules/MeasureTool/MeasureToolCore/Measurement.cpp Updates conversion/printing to use the shared formatter and include explicit unit suffix.
src/modules/MeasureTool/MeasureToolCore/BoundsToolOverlayUI.cpp Plumbs monitor DPI into bounds measurements and prints only the selected unit.
PowerToys.slnx Adds the new MeasureToolCore native unit test project to the solution.
doc/devdocs/modules/screenruler.md Updates module documentation to reflect the expanded unit support (including DIP).

Comment thread src/modules/MeasureTool/MeasureToolCore/MeasurementLogic.h Outdated
Co-authored-by: Copilot App <[email protected]>
Copilot-Session: 1a6361cf-d701-4a9b-b8e8-d5700c5ba140
@niels9001 niels9001 changed the title [Screen Ruler] Add selectable measurement units and DIP support [Screen Ruler] Add DIP as an extra measurement unit Jul 30, 2026
@niels9001
niels9001 requested a review from Copilot July 31, 2026 10:38
@niels9001
niels9001 marked this pull request as ready for review July 31, 2026 10:39
@niels9001
niels9001 requested a review from crutkas July 31, 2026 10:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/modules/MeasureTool/MeasureToolCore/BoundsToolOverlayUI.cpp:88

  • GetKeyState(VK_SHIFT) checks the high-order bit (0x8000). Using 0x80000 works only due to sign-extension quirks and is inconsistent with the same check in MeasureToolOverlayUI.cpp, making the intent unclear and potentially fragile if the return value is cast/handled differently.
        if (const bool shiftPress = GetKeyState(VK_SHIFT) & 0x80000; shiftPress && perScreen.currentBounds)

src/modules/MeasureTool/Tests/ScreenRuler.UITests/TestHelper.cs:456

  • The clipboard can contain multiple measurements separated by newlines (BoundsToolOverlayUI appends perScreen.measurements plus the current selection, and SetClipboardToMeasurements prints each measurement on its own line). Anchoring the regex to the full clipboard string (^...$) makes this assertion brittle if any prior measurements are present. Consider validating each non-empty line instead, and ensure none of the lines include the pixel suffix.
                Assert.IsTrue(
                    Regex.IsMatch(
                        clipboardText,
                        $@"^\d+(?:\.\d+)?\s*[x×]\s*\d+(?:\.\d+)?\s+{Regex.Escape(expectedUnit)}$"),
                    $"Clipboard should contain one {expectedUnit} measurement, but contained: '{clipboardText}'");
                Assert.IsFalse(clipboardText.Contains(" px", StringComparison.Ordinal), "Clipboard should not include an extra pixel measurement");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-Screen Ruler Refers to the Screen Ruler PowerToy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Screen Ruler] Millimetre conversion is 100x wrong in Measurement.cpp Add "Scale" setting to Screen Ruler to match Window's scaling features

2 participants