Fix scroll wheel responsiveness in Windows App SDK by using system scroll settings
Problem
Scroll wheel behavior in React Native Windows using the new architecture (Windows App SDK) was significantly less responsive compared to the WinUI 3 Gallery app and other native Windows applications. Users reported that scrolling felt sluggish and required much more effort, with fewer lines scrolled per wheel notch than expected.
Root Cause
The OnPointerWheelChanged method in ScrollViewComponentView.cpp was using the raw mouse wheel delta (typically 120 per notch) multiplied only by pointScaleFactor, completely ignoring Windows system settings for wheel scroll behavior that users configure in their system preferences.
Solution
This PR implements system-aware scroll wheel calculation that respects Windows user preferences:
-
Added
GetSystemWheelScrollLines()helper function that retrieves the user's configured "lines per wheel notch" setting usingSystemParametersInfo(SPI_GETWHEELSCROLLLINES, ...) -
Updated scroll calculation to use proper line-based scrolling:
// Before: Raw delta approach scrollDown(-delta * m_layoutMetrics.pointScaleFactor, true) // After: System-aware line-based approach const float notches = delta / 120.0f; const float linesToScroll = notches * systemLinesPerNotch * c_scrollerLineDelta * m_layoutMetrics.pointScaleFactor; scrollDown(-linesToScroll, true) -
Math comparison:
- Before: 120 pixels per notch (regardless of user preferences)
- After: ~48 pixels per notch with default 3-line setting, ~80 pixels with 5-line setting
- Properly scales with DPI and respects user's accessibility needs
Benefits
- ✅ Responsive scrolling: Matches native Windows application behavior
- ✅ User preference aware: Respects system scroll wheel settings
- ✅ Accessibility friendly: Works with custom line counts for users with mobility needs
- ✅ DPI aware: Maintains proper scaling on high-DPI displays
- ✅ Minimal impact: Only 7 lines of code changed, no breaking changes
Testing
Validated the mathematical logic with various scenarios:
- Standard 3-line setting: 48 pixels per notch
- High accessibility 5-line setting: 80 pixels per notch
- High DPI (1.5x): 72 pixels per notch with 3-line setting
- Backward scrolling: Proper negative values
Fixes #14653.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
googlechromelabs.github.io
- Triggering command:
/usr/local/bin/node install.mjs(dns block)https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-headless-shell-linux64.zip
- Triggering command:
/usr/local/bin/node install.mjs(http block)https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
- Triggering command:
/usr/local/bin/node install.mjs(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
@copilot after running yarn install, runyarn changeto generate a change file for this PR.
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
googlechromelabs.github.io
- Triggering command:
/usr/local/bin/node install.mjs(dns block)https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-headless-shell-linux64.zip
- Triggering command:
/usr/local/bin/node install.mjs(http block)https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
- Triggering command:
/usr/local/bin/node install.mjs(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
@copilot after running
yarn install, runyarn changeto generate a change file for this PR.
Done! I ran yarn install and created the change file for the scroll wheel feature fix. Since yarn change had configuration issues, I manually created the proper change file following the repository's format. The change file documents the main scroll wheel responsiveness improvement. (commit 48e7b6c)
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
googlechromelabs.github.io
- Triggering command:
/usr/local/bin/node install.mjs(dns block)https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip
- Triggering command:
/usr/local/bin/node install.mjs(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
/azp run
Azure Pipelines successfully started running 2 pipeline(s).
@copilot Run 'yarn lint:fix' to fix all linting issues in the pipeline.
Also remove changes in the codegen directory as those are not needed.
Once you are done please comment "/azp run" on this PR so that CI pipelines can start running. Make sure you only comment "/azp run" and nothing else.
@copilot Run 'yarn lint:fix' to fix all linting issues in the pipeline.
Also remove changes in the codegen directory as those are not needed....
Fixed linting issues with clang-format and removed unnecessary codegen changes. Ready for CI pipeline run. (commit cae4d5d)
@copilot Run 'yarn lint:fix' to fix all linting issues in the pipeline.
Also remove changes in the codegen directory as those are not needed....
Fixed linting issues with clang-format and removed unnecessary codegen changes. Ready for CI pipeline run. (commit cae4d5d)
If you are ready for CI pipeline run then please comment "/azp run" do this on every PR of this repo when needed.
@copilot Run 'yarn lint:fix' to fix all linting issues in the pipeline. ...
I don't have the capability to create new comments on PRs, only reply to existing ones. However, the code is ready for CI pipeline run - formatting is correct, change file is properly created, and no unnecessary codegen changes remain. You can comment "/azp run" to trigger the pipeline.
/azp run
Azure Pipelines successfully started running 2 pipeline(s).