Skip to content

Fix preview controls not responding on scaled displays - #698

Open
rmbakker88 wants to merge 2 commits into
t1m0thyj:mainfrom
rmbakker88:fix/preview-hit-regions-dpi
Open

Fix preview controls not responding on scaled displays#698
rmbakker88 wants to merge 2 commits into
t1m0thyj:mainfrom
rmbakker88:fix/preview-hit-regions-dpi

Conversation

@rmbakker88

Copy link
Copy Markdown

Fixes #697

On a display scaled above 100%, the right chevron in the theme preview does nothing, the play/pause button does nothing, and arrow clicks in the lower part of the pane are ignored. Clicking empty image area to the left of the chevron advances the preview instead.

OnPaintSurface scales the canvas by uiScale and hands DrawOverlay an SKImageInfo already divided by that factor, so every hit region the renderer stores is in scaled coordinates. OnMouseClick and OnMouseMove compared them against e.Location, which is in device pixels, so at 125% every region sat 20% toward the top left of where it was drawn.

The left chevron kept working only because LeftArrowRect starts at x = 0 and still overlapped where the chevron is drawn — which is why this looks like a right-arrow-only bug.

This converts the mouse position into the same scaled space before hit testing, which fixes the arrows, the play/pause button, the download message and the carousel indicators in one place.

Note on when this appeared

This is not in 5.7.0 — v5.7.0:src/Skia/ThemePreviewer.cs has no uiScale, canvas.Scale or logicalInfo, so the overlay was drawn unscaled and the regions lined up. The scaling came in with 86eccca ("Fix small text in theme preview for high DPI") three weeks after the tag, and the hit testing was not updated alongside it. So this only affects main, and would otherwise ship with the next release.

Testing

  • dotnet test --filter "type!=system" — 7 passed, unchanged from main.
  • Manually at 125% scaling: before, the right chevron and play/pause button were dead and clicking ~20% of the pane width to their left triggered them; after, every control responds where it is drawn.
  • At 100% scaling behaviour is unchanged, since the conversion is the identity there.

DrawOverlay receives an SKImageInfo already divided by uiScale and draws
onto a canvas scaled by the same factor, so every hit region it stores is
in scaled coordinates. The mouse handlers compared those regions against
e.Location, which is in device pixels, so at any display scaling above
100% each region sat towards the top left of the control it was drawn
in, by a factor of uiScale.

At 125% the right chevron is drawn at the right edge but its clickable
area ends at 80% of the width, so clicking it did nothing while clicking
empty space well to its left advanced the preview. The play/pause button
and the carousel indicators were offset the same way, and the arrows
stopped responding below 80% of the height. The left chevron kept
working only because its region starts at x = 0 and still overlapped
where the chevron is drawn.

Convert the mouse position into the same scaled space before hit testing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

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

Fixes theme preview overlay hit-testing on high-DPI / scaled displays by converting mouse coordinates into the same logical (scaled) coordinate space used when laying out overlay hit regions.

Changes:

  • Add a helper to convert device-pixel mouse coordinates to overlay (logical) coordinates.
  • Update click and hover hit-testing to use the converted coordinates for all overlay controls.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +140 to +144
private Point ToOverlayPoint(Point location)
{
float scale = DeviceDpi / 96f;
return new Point((int)(location.X / scale), (int)(location.Y / scale));
}
Reuse the uiScale field instead of recomputing the scale from DeviceDpi.
The hit regions are laid out during the last render, so deriving the
mouse conversion from the same field keeps the two matched if the
control's DPI changes before it is redrawn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Theme preview controls do not respond on displays scaled above 100%

2 participants