CNA-BUG-178: The SDL2 backend negates a flipped mouse wheel while SDL3 passes SDL's adjusted value through, so the two report opposite signs under natural scrolling

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

Sdl2Platform negates wheel x/y on SDL_MOUSEWHEEL_FLIPPED, undoing the host's natural-scrolling preference, while Sdl3EventMapper passes SDL's adjusted value through; MouseWheelEvent is documented as the post-preference value.

Identifier
CNA-BUG-178
Category
Bug
Subsystem
Platforms
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
CNA::Platform::MouseWheelEvent::x / y ("scroll amount after the host's scrolling-direction preference")

Expected behaviour

PlatformEvent.hpp documents MouseWheelEvent::x and y as “scroll amount after the host's scrolling-direction preference.” The SDL3 backend meets that: Sdl3EventMapper copies source.wheel.x/y and comments that SDL “has already applied the host's natural-scrolling preference ... undoing it here would change the established FNA/CNA input behaviour.” Both backends should report the same sign.

Actual behaviour at TARGET

Sdl2Platform::PollEvents negates the deltas when source.wheel.direction == SDL_MOUSEWHEEL_FLIPPED. In SDL2, FLIPPED means the x/y values are already the natural-scrolling (inverted) ones and “Multiply by -1 to change them back”, so this negation reverts to the raw device direction, dropping the host preference the field is documented to keep. Under natural scrolling (where SDL2 sets FLIPPED, for example on macOS), the SDL2 and SDL3 backends therefore report opposite wheel signs for the same gesture.

Source locations

Evidence

Checked by reading both event mappers and the MouseWheelEvent documentation at 009d40f5, and SDL2's SDL_MouseWheelDirection semantics (SDL2 SDL_events.h, release-2.30.x: “When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back”; the flag is set only on the Cocoa/UIKit natural-scrolling paths). Not executed on a host; the sign divergence follows from the two mappers' code, and the candidate is stated on the SDL2 page with that hedge.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

Sdl3EventMapperTests.cpp asserts SDL3 leaves both a NORMAL and a FLIPPED event unchanged. The SDL2 native-queue test does not assert wheel sign, and no test compares the two backends under FLIPPED.

Regression test

A mapper test that feeds a FLIPPED wheel event to both backends and requires the same sign; decide which convention is canonical (SDL3's pass-through matches the field's documentation) and make SDL2 match it.

Blast radius

Games run on the SDL2 backend by players who enabled natural scrolling (mainly macOS); their wheel input is inverted relative to the same game on SDL3 or the native backends.

Workaround

Prefer the SDL3 backend; a game can expose a scroll-inversion setting.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

User guide
Input: mouse
Known issues
Bug index