Skip to content

[Screen Ruler] Fix DPI measurement selection issue - #50696

Merged
Yu Leng (moooyo) merged 2 commits into
microsoft:mainfrom
daverayment:fix/screen-ruler-dips
Sep 22, 2026
Merged

Yu Leng (moooyo) merged 2 commits into
microsoft:mainfrom
daverayment:fix/screen-ruler-dips

Conversation

@daverayment

Copy link
Copy Markdown
Collaborator

Summary of the Pull Request

This fixes an issue which prevented the "Device-independent pixels" option from being selected as Screen Ruler's secondary measurement option.

PR Checklist

  • 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
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Screen Ruler used to store the secondary measurement unit as the enum value from MeasureToolCore.MeasurementLogic.Unit:

    enum Unit
    {
        Pixel = 1,
        Inch = 2,
        Centimetre = 4,
        Millimetre = 8,
        Dip = 16,
    };

This was changed to store the combo box index, but at the time the combo box only had 4 items with indexes 0 to 3. This crashed the application if a user had Centimetre or Millimetre saved (DIP was not available at the time). In PR #49898 a migration method was added to translate legacy settings values:

        internal static int NormalizeUnitsOfMeasureIndex(int value)
        {
            return value switch
            {
                // Before the units selector was added, this setting stored Measurement::Unit
                // enum values. Preserve the user's centimetre/millimetre choice during migration.
                4 => 2,
                8 => 3,
                >= DefaultUnitsOfMeasureIndex and <= MaximumUnitsOfMeasureIndex => value,
                _ => DefaultUnitsOfMeasureIndex,
            };
        }

(This worked for Centimetre, Millimetre and Inch, but actually broke for Pixel, setting it to Inch accidentally.)

Later, PR #49588 added DIP as the fifth combo box item at index 4 and updated the basic mapping, but did not update the NormalizeUnitsOfMeasureIndex routine or increase the MaximumUnitsOfMeasureIndex const from 3 to 4.

The effect of this was that the DIP value was saved as the combo box index of 4, but the normalisation method translated it straight back to 2 - Inch.

Solution

As a value of 4 is ambiguous we must remove the normalise step for it; otherwise DIPs cannot be selected. Legacy users who upgrade from a very old version of PowerToys and who have Centimetres saved will now get DIPs, but this should affect a very small number of individuals.

Note: this will hit us again if the number of combo box entries ever gets to 9, as the 8th entry will get mapped to millimetre. We should remove the 8 => 3 line at that point.

Validation Steps Performed

Manual tests:

  • Confirmed that all values can be selected and that the ruler correctly updates to show the correct secondary units.
  • Updated the settings file manually to include an invalid value for the unit and confirmed that it was updated to 0 (pixels only).

Unit tests:

  • Updated existing unit test to confirm that the remaining millimetre normalisation from 8 to 3 still works.
  • Wrote a new unit test to ensure that the MaximumUnitsOfMeasureIndex can no longer deviate from the number of items in the combo box.

All unit tests pass:

image image

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.

Copilot review overview

ðŸŸĒ Approval recommended

The only remaining comment is a non-blocking documentation nit.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Fixes Screen Ruler’s DIP secondary measurement selection and legacy unit migration.

Changes:

  • Supports DIP at combo-box index 4.
  • Preserves millimetre migration and updates normalization bounds.
  • Adds regression tests for normalization and item-count consistency.
File Summary
src/​settings-ui/​Settings.UI/​ViewModels/​MeasureToolViewModel.cs Updates measurement normalization and supports DIP index 4. Minor nit: correct the legacy enum value in the comment.
src/​settings-ui/​Settings.UI.UnitTests/​ViewModelTests/​MeasureTool.cs Adds regression coverage for migration and combo-box alignment.

ðŸ’Ą Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@moooyo

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@moooyo

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@moooyo

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@moooyo
Yu Leng (moooyo) merged commit 0d38f9f into microsoft:main Sep 22, 2026
10 checks passed
@daverayment
Dave Rayment (daverayment) deleted the fix/screen-ruler-dips branch September 22, 2026 11:32
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 Ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Screen Ruler] DIP measurement unit cannot be selected

5 participants